working nicely on my laptop, but fail on my PC?
working nicely on my laptop, but fail on my PC?
recognized by both, but sometimes fails on PC.
Using Bulk.
any possible reason?
or any thing else I can check?
Using Bulk.
any possible reason?
or any thing else I can check?
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.
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.
Last edited by SimonQian on Sat Apr 12, 2008 3:00 pm, edited 1 time in total.
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.
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.
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.
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.
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.
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?
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?
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.
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.
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.
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.
I add code to check data toggle like this(AVRUSB run at 16M):
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.
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.
Code for usbFunctionWriteOut:
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.
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.
It's OK after I only store the DATA token when ACK is sent:
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.
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.