Page 1 of 3
working nicely on my laptop, but fail on my PC?
Posted: Fri Apr 11, 2008 1:12 am
by SimonQian
recognized by both, but sometimes fails on PC.
Using Bulk.
any possible reason?
or any thing else I can check?
Posted: Fri Apr 11, 2008 12:37 pm
by SimonQian
It's really hard to debug cause I have no USB proto analyzer, but I still tried to fight out.
There are 2 kinds of errors.
1.is solved
2 is that Bulk package error, for example, the package format is:
//dat[idx] para(value) --Description
//dat[0] Command
//dat[1] NumBytes(MSB) --Total number of bytes to program(MSB)
//dat[2] NumBytes(LSB) --Total number of bytes to program(LSB)
//dat[3] mode --Mode byte
//dat[4] delay --Delay used for different types of programming termination,according to mode byte
//dat[5] cmd1 --Comamnd byte for Load Page
//dat[6] cmd2 --Command byte for Write Memory
//dat[7] cmd3 --Command byte for Read Memory
//dat[8] poll1
//dat[9] poll2
//data[10] Data --Data to program
........// other data, length of which is define in NumBytes section.
when OK, package length is NumBytes + 10, but when fails, it's larger.
If Data section is read by "dat[10 + i ]" for example, it will fail when package size is error, but succeed if read data by "dat[len - NumBytes + i]", in which "len" is the size of the whole package received, even if package size is error.
Posted: Fri Apr 11, 2008 3:30 pm
by SimonQian
To find what's wrong, I add these code:
if((10 + NumBytes) < len) {
for(i = 0;i < len;i++)
EEPROM_Write(0x10+i,dat[i]);
}
And found that if error occurs, the first or second 8 bytes is received twice, so the real package size is 18 + NumBytes, and data can be obtained if count from bottom.
I tried 100 times to retrieve data from bottom, and even if the package size is wrong, data retrieved is OK. Another 100 times, I retrieve data from dat[10 + i], and got 9 errors in all.
Posted: Sat Apr 12, 2008 9:06 pm
by christian
This probably means that Sharity was not fast enough sending an ACK so that the host did a USB retry after some time.
What clock frequency do you use? Can you reproduce this? If yes, do you have a digital storage scope to analyze it? Would be really interesting to find out why this happens since bulk endpoints cause problems on some computers.
Posted: Sun Apr 13, 2008 7:39 am
by SimonQian
christian wrote:This probably means that Sharity was not fast enough sending an ACK so that the host did a USB retry after some time.
What clock frequency do you use? Can you reproduce this? If yes, do you have a digital storage scope to analyze it? Would be really interesting to find out why this happens since bulk endpoints cause problems on some computers.
It's running on 12MHz.
I CAN reproduce it.
My scope can't store so many data(maybe 1 error among hundreds of packages). I think a USB proto analyzer will do, but I don't have one.
If using a older version, it's not that bad. But still will error occasionally.
Anything else I can do to find the reason?
Try a faster oscillator, and see whether it fails again?
-- tried and failed for same error with 16MHz oscillator.
Posted: Sun Apr 13, 2008 12:27 pm
by christian
The 16 MHz version meets the specs reliably when you use bulk endpoints, the 12 MHz version is very close to the limit.
Since one 8 byte chunk is duplicated, it's almost certain that this is a retry from the host. In principle, it's possible to filter out retries by checking data toggling. But I'd rather try to find out why there is a retry at all.
How much memory do you have in your scope? If you generate a trigger when you receive the duplicate package, would the memory suffice?
Posted: Sun Apr 13, 2008 2:15 pm
by SimonQian
I'll try sometime next week.
BTW:
I tried to check the data toggle by this:
in usbdrvasm.S add(myTok is define uchar in main.c):
extern myTok
in asmcommon.S function handleData insert first:
sts myTok,token; this will store token(DATA0 or DATA1) to myTok
This will add 2 cycle delay.
But if I check the data toggle in usbFunctionWriteOut function,
some other package will fails.
I will chech it later if I have time next week.
Posted: Sun Apr 13, 2008 3:27 pm
by christian
You must reset data toggling after each new connection. Do you lose the first chunk or one in the middle?
When you generate a trigger in usbFunctionWriteOut() if data toggling is wrong, you should see many DATA packets which are answered with a NAK between the two with the same token. The main loop code should be as fast as possible to limit this number.
Posted: Wed Apr 16, 2008 3:57 pm
by SimonQian
too busssssssssy these days.
Is there any list to show which PC or chipset is more likely to fail with Bulk Transfer?
Posted: Wed Apr 16, 2008 4:02 pm
by christian
I think Osamu has some statistics included with his AVR-CDC project.
Posted: Thu Apr 17, 2008 11:46 am
by SimonQian
I add code to check data toggle like this(AVRUSB run at 16M):
Code: Select all
/// Token recorded when receive DATA package
uchar lastTok;
///
/// @brief AVRUSB will call this function when DATA package is received
/// @param data received data to process
/// @param len received data length
///
void usbFunctionWriteOut(uchar *data, uchar len)
{
#if 1
static uchar preTok;
// not first package, same tok as last package, then ignore
if(CMD_Len_tmp && (preTok == lastTok))
{
uint8 i;
EEPROM_Write(0x01,preTok);
EEPROM_Write(0x02,lastTok);
for(i = 0;i < CMD_Len_tmp;i++)
EEPROM_Write(0x10 + i,AVR_Device_DataBuff[i]);
for(i = 0;i < len;i++)
EEPROM_Write(0x80 + i,data[i]);
return;
}
preTok = lastTok;
#endif
......
}
On my Lenovo T60, it works fine under windows and linux.
On my IBM i Series, it works fine also under windows(have no linux installed)
On my PC(SL-K8AV-R), fials frequently under windows(in fact, never succeed), OK under Linux.
Checking the EEPROM, data token and some data are error.
Posted: Thu Apr 17, 2008 12:30 pm
by christian
Can you please post (or mail me) the EEPROM content (previous and current package) and add a note where see an error?
Another question: Do you use other interrupts than the USB interrupt or do you disable interrupts in your main code?
Posted: Fri Apr 18, 2008 2:10 pm
by SimonQian
Code for usbFunctionWriteOut:
Code: Select all
/// Token recorded when receive DATA package
uchar lastTok;
///
/// @brief AVRUSB will call this function when DATA package is received
/// @param data received data to process
/// @param len received data length
///
void usbFunctionWriteOut(uchar *data, uchar len)
{
#if 1
static uchar preTok;
// not first package, same tok as last package, then ignore
if(CMD_Len_tmp && (preTok == lastTok))
{
uint8 i;
EEPROM_Write(0x01,preTok);
EEPROM_Write(0x02,lastTok);
EEPROM_Write(0x03,CMD_Len_tmp);
EEPROM_Write(0x04,len);
for(i = 0;i < CMD_Len_tmp;i++)
EEPROM_Write(0x10 + i,AVR_Device_DataBuff[i]);
for(i = 0;i < len;i++)
EEPROM_Write(0x80 + i,data[i]);
LED_On(LED_Green);
while(1);
return;
}
preTok = lastTok;
#endif
memcpy(AVR_Device_DataBuff + CMD_Len_tmp,data,len);
CMD_Len_tmp += len;
......
}
PC should send(12 bytes in Hex): 10 C8 64 19 20 00 53 03 AC 53 00 00
EEPROM content(in Hex) On error(addr:data):
1.
0x01:C3
0x02:C3
0c03:08
0c04:04
0x10:10 C8 64 19 20 00 53 03
0x80:AC 53 00 00
Error: same DATA PID
2.
0x01:4B
0x02:4B
0c03:08
0c04:04
0x10:10 C8 64 19 20 00 53 03
0x80:AC 53 00 00
Error:same DATA PID
Tried 50 times,
Running on my PC under Linux, the green LED is never on.
Running on my PC under Windows, can't pass even once.
Bad driver for Windows? But it drives my USB mice and keyboard well.
Posted: Fri Apr 18, 2008 3:27 pm
by christian
Where exactly do you store lastTok in the assembler code? Do you store it even if the request is answered with NAK? This would explain it: Data is only stored if we answer with ACK, but lastTok may change if a packet has been rejected meanwhile.
Posted: Sat Apr 19, 2008 7:45 am
by SimonQian
It's OK after I only store the DATA token when ACK is sent:
Code: Select all
handleData:
mov x3, token
lds token, usbCurrentTok;[18]
tst token ;[20]
breq doReturn ;[21]
lds x2, usbRxLen ;[22]
tst x2 ;[24]
brne sendNakAndReti ;[25]
; 2006-03-11: The following two lines fix a problem where the device was not
; recognized if usbPoll() was called less frequently than once every 4 ms.
cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack
brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
sts lastTok, x3
sts usbRxLen, cnt ;[28] store received data, swap buffers
sts usbRxToken, token ;[30]
lds x2, usbInputBufOffset;[32] swap buffers
ldi cnt, USB_BUFSIZE ;[34]
sub cnt, x2 ;[35]
sts usbInputBufOffset, cnt;[36] buffers now swapped
rjmp sendAckAndReti ;[38] 40 + 17 = 57 until SOP
Checking the EEPROM, some package is really sent twice, and even there is a data error among them.
Just ignore the resent package, it's running well. Tested many times, never fails.