IOW56 SPI transmission: not all bytes are read

This is the English forum for all topics related to IO-Warrior. Please post in English only

Moderator: Guido Körber

wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hi Ligang,
During its running I start another programm like Eclipse, then the error is reproduced.
Eclipse is a real showstopper on startup (another other one is Staroffice).
Do you still get the error when you don't do anything like the above, do you fail when your machine is "normal" operation?

What happens if you increase the timeout to some rediculous value like 60 seconds?
Idea behind this : Do you miss the report because your read in the IowKit-library times out too early (machine to busy with eclipse), or because Windows is not delivering it to the library.

(Since you're using a starterkit we can rule out any hardware issues. I ran a test-app like the one I proposed to you on linux for hours. The IOWarrior never missed to answer the SPI-reports I wrote.)

If you could mail the python-testapp to me I could try a few runs on my machine. I case there is a problem with the allover systemload.

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

I would not rule out hardware issues completely. Driving the SPI too fast can give garbled data.
Please show the report for initialization of the SPI.
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

hallo Robert
Robert Marquardt wrote:I would not rule out hardware issues completely. Driving the SPI too fast can give garbled data.
Please show the report for initialization of the SPI.
My test was performed on an Iow56 Starterkit with no external hardware attached. SPI-reports where send to the IOWarrior at maximum speed and all I wanted to know was : Do I get an answer (SPI-report) for each report I send. All I checked was the reports that came back carried a report-id of 0x09 (SPI).


Initialization is trivial as long as you don't set a handshake protocol I used:
0x08 0x01 0x00 0x01
for setting up the SPI-mode (Clockdivider 1 for max-speed)
and sent reports like this one here:
0x09 0x3D 0x00 0x00 ....
(61 Zeros, no handshake)

On linux I received
0x09 0x3d 0x?? 0x??
a report for every write, with the correct count, didn't care for the actual data since no SPI-hardware was attched.
The same must work on Windows or we have a bug somewhere...

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

I just did some tests though the playback function of SimpleHIDWrite and i did no lose any read reports even when starting StarOffice or Eclipse.
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Robert Marquardt wrote:I just did some tests though the playback function of SimpleHIDWrite and i did no lose any read reports even when starting StarOffice or Eclipse.
That would rule out the Hardware and Windows itself as the possible reasons for the problem...

But SimpleHIDWrite does not use the Iowkit-Library, or am I wrong ???

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

No, it uses the HID API directly and it sleeps for 50 msecs between playback commands.
lgzco
Posts: 10
Joined: Tue Mar 13, 2007 10:23 am

Post by lgzco »

Hi Eberhard, Hi Robert,
Eclipse is a real showstopper on startup (another other one is Staroffice).
Do you still get the error when you don't do anything like the above, do you fail when your machine is "normal" operation?
Yes, i still get error sometimes even when I do nothing.
What happens if you increase the timeout to some rediculous value like 60 seconds?
the same result.
If you could mail the python-testapp to me I could try a few runs on my machine. I case there is a problem with the allover systemload.
here is my short Python code. In order to run it you must have installed ctypes from http://starship.python.net/crew/theller/ctypes/

Code: Select all

import time
import os
import sys
from string import *
from ctypes import *

class IowReadResult56(Structure):
    _fields_ = [("ReportId", c_ubyte), ("IowReadResult", c_ubyte*63 )]



DeviceHandle = windll.Iowkit.IowKitOpenDevice()
windll.Iowkit.IowKitSetTimeout(DeviceHandle, 5000)

datac = IowReadResult56()
datac.ReportId = 8
datac.IowReadResult[0] = 1
datac.IowReadResult[1] = 0
datac.IowReadResult[2] = 1

#configure the IoWarrior56 with "enable"=1; "mode"=1; "clock"=1
BytesWritten = windll.IowKit.IowKitWrite(DeviceHandle, 1, pointer(datac), sizeof(IowReadResult56))
if BytesWritten != sizeof(IowReadResult56):
    print BytesWritten
    raise "IoWarrior: Not all bytes written!"

datac.ReportId = 9
datac.IowReadResult = (61, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60)
for i in range(1, 3000):
    BytesWritten = windll.IowKit.IowKitWrite(DeviceHandle, 1, pointer(datac), sizeof(IowReadResult56))
    if BytesWritten != sizeof(IowReadResult56):
      raise "IoWarrior: Not all bytes written!"

    ReturnLength = windll.Iowkit.IowKitRead(DeviceHandle, 1, pointer(datac), sizeof(IowReadResult56))
    if ReturnLength != sizeof(IowReadResult56):
      print "ReturnLength:", ReturnLength    
      print "GetLastError():", windll.kernel32.GetLastError()
      raise "IoWarrior: Not all bytes read!"

    ReturnList = []
    for k in range(1, datac.IowReadResult[0]+1):
      ReturnList.append(datac.IowReadResult[k])

    print ReturnList  
   #time.sleep(0.05)

windll.Iowkit.IowKitCloseDevice(DeviceHandle)
del DeviceHandle
I just did some tests though the playback function of SimpleHIDWrite and i did no lose any read reports even when starting StarOffice or Eclipse.
I have the same result. By the way, is there some difference between using IowKit.dll and using HID API?

Many thanks for your kind help so far!

regards,
Ligang
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hi Ligang,

I reanimated my Python-knowledge to run some tests on Windows (Vista) with the Python code using the IowKit-Lib.

This is what I found out so far:
I can reproduce the bug you encountered. On my machine it doesn't even matter wether any other apps are starting or what else is goning on, my test-app is not able to read back even a single SPI-Report after I have them send of to the IOWarrior.

But here comes the really bad part:
My test-app runs fine if I use an IOWarrior24 instead.
When I send 100 SPI-Reports to this IOWarrior24 (no SPI-Hardware attched) I'm able to read 100 reports back, just like it is on Linux and with SimpleHidWrite.

Since I don't think that the problem is introduced by the use of Python (why should the python-bindings work for an IOW24 and fail for the IOW56?)
and its not the IOWarrior56 itself thats causing the trouble (no problems on Linux or with SimpleHidWrite),
I guess there is something wrong with the IowKit-library????

@Robert: Could you write a simple test in plain "C" so we know wether its the IowKit-Lib thats causing the trouble?
Ligang wrote: By the way, is there some difference between using IowKit.dll and using HID API?
The HID_API is a provided by Windows for accessing HID-devices.

The IowKit-Library uses this API for communication with the IOWarrior,
as does my own C#-Library for the IOWarrior at
http://www.wayoda.org/csiow/index.html


Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

Yes, job has been assigned.
Wayoda, please send me your test sources. I have written a Delphi app which works for IOW56 (no SPI attached).

Code: Select all

procedure TForm1.TestClick(Sender: TObject);
var
  I: Integer;
  Dev: IOWKIT_HANDLE;
  Report, ReadReport: IOWKIT56_SPECIAL_REPORT;
begin
  LoadIowKitAPI;
  Dev := IowKitOpenDevice;

  if Dev = nil then
    ShowMessage('No IOWarrior found');

  // SPI on
  FillChar(Report, 0, SizeOf(Report));
  Report.ReportID := $08;
  Report.Bytes[0] := $01;
  Report.Bytes[1] := $00;
  Report.Bytes[2] := $01;
  IowKitWrite(Dev, IOW_PIPE_SPECIAL_MODE, @Report, IOWKIT56_SPECIAL_REPORT_SIZE);

  ListBox1.Items.Add('Testing...');
  Application.ProcessMessages;
  for I := 1 to 1000 do
  begin
    FillChar(Report, 0, SizeOf(Report));
    Report.ReportID := $09;
    Report.Bytes[0] := $3D;
    Report.Bytes[1] := $00;
    IowKitWrite(Dev, IOW_PIPE_SPECIAL_MODE, @Report, IOWKIT56_SPECIAL_REPORT_SIZE);
    FillChar(ReadReport, 0, SizeOf(ReadReport));
    if IowKitRead(Dev, IOW_PIPE_SPECIAL_MODE, @ReadReport, IOWKIT56_SPECIAL_REPORT_SIZE) <> IOWKIT56_SPECIAL_REPORT_SIZE then
      ListBox1.Items.Add(Format('Read error %d', [I]));
  end;
  ListBox1.Items.Add('Test complete');

  // SPI off
  FillChar(Report, 0, SizeOf(Report));
  Report.ReportID := $08;
  IowKitWrite(Dev, IOW_PIPE_SPECIAL_MODE, @Report, IOWKIT56_SPECIAL_REPORT_SIZE);

  IowKitCloseDevice(Dev);
  UnloadIowKitAPI;
end;
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hello Ligang and Robert

I did some more testing and it seems the problem can be at least avoided by sleeping for a short time between the writes to the SPI-bus.

Code: Select all

for i in range(0,100000):
                    wresult=iow.writeSpecialMode(spi_foo)
                    time.sleep(0.001)
                    print "write run ",i," returned ",wresult
                    if wresult==0:
                        break
                    rep=iow.readSpecialMode()    
                    print "read run ",i," returned  ", rep
                    if rep is None:
                        break
This is the python code im using (I wrote my own small wrapper for the library)
I write a SPI-report with some default values and then read the next report from the IOWarrior.

As you can see I sleep for 1 millisecond between the write and the read.
If I comment out this line, my programm fails after sometimes only 100 iterations. Sometimes the programm even goes up to 7000 iterations before it dies.

With the time.sleep(0.001) I was able to successfully go through the whole 100000 iterations 3 times now.

The next tests I ran without reading from the IOWarrior.
I found out that already the writes to the IOWarrior SPI-Bus failed after a few (thousand) iterations. Again I was able to solve this problem by sleeping between the writes.

Maybe its not a Read-Problem, but rather a Write issue?

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

I hate it when i cannot reproduce the problem. i just optimized my Delphi program to only do 10000 IowKitWrite and it still behaves.
Which CPU do you use?
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Robert Marquardt wrote:I hate it when i cannot reproduce the problem. i just optimized my Delphi program to only do 10000 IowKitWrite and it still behaves.
Which CPU do you use?
Core 2 Duo, Vista Home-Premium

If you have time to install Python 2.5 http://www.python.org I'll send my python-tests.
I'm sending my Linux C-code (that works just like your delphi) right now.

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

My colleague could reproduce by writing only using a Pentium M 2GHz on Vista Business and Win XP. Adding a sleep made the bug go away.

Update:
IowKitWrite gets stuck in the overlapped WriteFileEx call. Setting the write timeout with IowKitSetWriteTimeout(iowHandle, 1000) allows the WriteFileEx call to fail with timeout. I see no bug in the source of IowKit.dll.
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Robert Marquardt wrote:IowKitWrite gets stuck in the overlapped WriteFileEx call. Setting the write timeout with IowKitSetWriteTimeout(iowHandle, 1000) allows the WriteFileEx call to fail with timeout. I see no bug in the source of IowKit.dll.
I was able to reproduce the bug with my C#-code. (Write times out in WriteFileEx).

Is this only a SPI-Mode problem?

Eberhard
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

wayoda wrote: Is this only a SPI-Mode problem?
Hard to test. Definitely not a problem of the IO-Pins (tested).
I also tested with my HID component (so no iowkit.dll involved) and it gets stuck in the WriteFile the component uses.

Updated: Special Mode $FF tested and it fails.
Post Reply