Hello,
I'm having a problem that I can't pin point the reason.
From what I read, FS USB bulk transfers can be max 64 bytes, but I'm having issues sending and receiving bulk data with 64 bytes, 63 and below work pretty well.
My test project is here:
https://github.com/rbarreiros/STM32F1-usb-test
Any idea what am I doing wrong ? or if I'm doing anything wrong at all ! I tried to debug the issue with no success :/
Thanks.
STM32F1 Bulk transfer size problem
Moderators: RoccoMarco, barthess
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: STM32F1 Bulk transfer size problem
Hi,
Hard to tell, my usual test writes blocks much larger than 64 bytes.
Just a note, when you get the event of input available then you need to keep reading from the endpoint until the returned length is zero or the queue will not be emptied. Use TIME_IMMEDIATE as timeout, you don't need to sleep.
Giovanni
Hard to tell, my usual test writes blocks much larger than 64 bytes.
Just a note, when you get the event of input available then you need to keep reading from the endpoint until the returned length is zero or the queue will not be emptied. Use TIME_IMMEDIATE as timeout, you don't need to sleep.
Giovanni
-
- Posts: 27
- Joined: Sat Mar 28, 2015 2:32 am
Re: STM32F1 Bulk transfer size problem
I noticed something strange, I increased the size of the array holding the data read from 64 to 128, to make sure I would empty the buffer, then I proceeded to make sure all the data was read from the buffer by checking when the length returned was 0, but still had the same problem, the test.c was getting read timeouts from the device, but sending to the device was ok, only that the device would acknowledge a read only after every 4th send, 4 * 64 = 256 which is the SERIAL_USB_BUFFERS_SIZE so I decreased SERIAL_USB_BUFFERS_SIZE to 64, and lo and behold, the data flows.
Is this supposed to happen ? can't I have a SERIAL_USB_BUFFERS_SIZE of say 128, and still be able to read from queue before it's full, empty it, reply the host and repeat ? Is me doing something wrong ?
Thanks.
p.s. : I updated the repo above with this changes
Is this supposed to happen ? can't I have a SERIAL_USB_BUFFERS_SIZE of say 128, and still be able to read from queue before it's full, empty it, reply the host and repeat ? Is me doing something wrong ?
Thanks.
p.s. : I updated the repo above with this changes
Re: STM32F1 Bulk transfer size problem
This sounds like a protocol issue. When sending data of max packet size the host/device need to 'terminate' the request with a short packet (zero-length packet). Without a short packet both the host/device don't know the transfer has ended if the length is equal to the max packet size.
To test you can try changing the max packet size to 16 and see if the problem occurs when attempting to transfer 16 bytes.
To test you can try changing the max packet size to 16 and see if the problem occurs when attempting to transfer 16 bytes.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: STM32F1 Bulk transfer size problem
The insertion of the zero packet should be performed by the driver, I need to test this, weekend job.
It would be interesting to test your application on a device with the OTG cell, it uses a different driver, and see if the result is the same or if it works. That would hint at a problem in the driver.
Giovanni
It would be interesting to test your application on a device with the OTG cell, it uses a different driver, and see if the result is the same or if it works. That would hint at a problem in the driver.
Giovanni
-
- Posts: 27
- Joined: Sat Mar 28, 2015 2:32 am
Re: STM32F1 Bulk transfer size problem
When debugging, I noticed in wireshark that libusb was sending the 0 length packet, so I would assume the problem is in ChibiOS, I'll try to test a bit further.
Off topic quick question, can I put a callback function inside a thread ? or I shouldn't ? Something like this:
Is this OK ? will each thread call each own callback instead of the same callback since they share the same name ?
Off topic quick question, can I put a callback function inside a thread ? or I shouldn't ? Something like this:
Code: Select all
static THD_WORKING_AREA(waThread2, 1024);
static THD_FUNCTION(Thread2, arg)
{
uint8_t buffer[513];
void mycallback(UARTDriver *uart)
{
...
chSysLockFromISR();
uartStartSendI(uart, sizeof(buffer), buffer);
chSysUnlockFromISR();
}
thd_config_t cfg = (thd_config_t)arg;
...
cfg.uartCfg.txend2_cb = &mycallback;
while(true)
{
chThdMiliseconds(10); // Do I really need this or can be ignored ?
}
}
int __attribute__((noreturn)) main(void)
{
halInit();
chSysInit();
thd_config_t cfg1, cfg2, cfg3;
... fill cfg structs ...
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, cfg1);
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, cfg2);
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, cfg3);
while(true)
{
chThdMiliseconds(10); // Do I really need this or can be ignored ?
}
}
Is this OK ? will each thread call each own callback instead of the same callback since they share the same name ?
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: STM32F1 Bulk transfer size problem
Each thread should call its own but it is not standard C, it is a GNU extension.
BTW, I am not sure it would work with callbacks, try to avoid it. Writing into the configuration structure after the driver is started is also a bad idea, it is meant to be constant.
Giovanni
BTW, I am not sure it would work with callbacks, try to avoid it. Writing into the configuration structure after the driver is started is also a bad idea, it is meant to be constant.
Giovanni
-
- Posts: 27
- Joined: Sat Mar 28, 2015 2:32 am
Re: STM32F1 Bulk transfer size problem
Giovanni wrote:Writing into the configuration structure after the driver is started is also a bad idea, it is meant to be constant.
Giovanni
The callback change in the config struct in that code was just an example to make the point, I do change it's config, but only the BRR, to send the break signal in a DMX stream, I tried the 'proper' approach, uartStop, change cfg, uartStart but the time this takes is too much, makes the break too long, so, I opted for the following, which works:
Code: Select all
void txend2_cb(UARTDriver uart)
{
switch(dmxStatus)
{
case BREAK: // Break finished, send DMX Stream
dmxStatus = IDLE;
uart->usart->BRR = dmxBRR;
chSysLockFromISR();
uartStartSendI(uart, DMX_BUFFER_SIZE, dmxStream);
chSysUnlockFromISR();
break;
case IDLE: // Finished sending stream, send break
dmxStatus = BREAK;
uart->usart->BRR = brkBRR;
uint8_t tmp[1] = {0};
chSysLockFromISR();
uartStartSendI(uart, 1, &tmp);
chSysUnlockFromISR();
break;
};
}
BRR value is saved in brkBRR and dmxBRR after I set the correct baudrate in the cfg struct in order to avoid having to recalculate the BRR every time I change it:
Code: Select all
...
UARTConfig uartCfg = { NULL, NULL, NULL, NULL, NULL, DMX_BAUDRATE, 0, USART_CR2_STOP_1, 0 };
uartStart(UART1, &uartCfg);
dmxBRR = uartCfg.BRR;
uartStop(UART1);
uartCfg.speed = BREAK_BAUDRATE;
uartStart(UART1, &uartCfg);
brkBRR = uartCfg.BRR;
uartStop(UART1);
...
I would guess that is ok ?
-
- Posts: 27
- Joined: Sat Mar 28, 2015 2:32 am
Re: STM32F1 Bulk transfer size problem
Hello Giovanni,
Any news on your weekend test ?
I got my code running right now using a max packet size of 63, but I'd love to have it standard on 64 !
Another small issue, while debug is on (specially asserts) if I connect/disconnect/connect the device it hits an assert because it calls usbInitEndpointI twice (1 each connect) because of osalDbgAssert(usbp->epc[ep] == NULL, "already initialized"); shouldn't it be de-init when disconnecting ? or, removed the assert ?
Other small issue, I don't need to set configuration on libusb when opening the device, but, some other applications might, and, right now, when calling set_configuration after running the test application which does a libusb open/set_configuration/claim_interface/bulk_transfer/release_interface/close twice, the third time, I get a -99 (LIBUSB_ERROR_OTHER) error when I run the test app again when calling set_configuration, and a -1 (LIBUSB_ERROR_IO) when trying to bulk write/read to the device. The device doesn't 'crash' as everything else keeps running, just stops talking USB, debug shows nothing wrong !
Best regards.
Any news on your weekend test ?
I got my code running right now using a max packet size of 63, but I'd love to have it standard on 64 !
Another small issue, while debug is on (specially asserts) if I connect/disconnect/connect the device it hits an assert because it calls usbInitEndpointI twice (1 each connect) because of osalDbgAssert(usbp->epc[ep] == NULL, "already initialized"); shouldn't it be de-init when disconnecting ? or, removed the assert ?
Other small issue, I don't need to set configuration on libusb when opening the device, but, some other applications might, and, right now, when calling set_configuration after running the test application which does a libusb open/set_configuration/claim_interface/bulk_transfer/release_interface/close twice, the third time, I get a -99 (LIBUSB_ERROR_OTHER) error when I run the test app again when calling set_configuration, and a -1 (LIBUSB_ERROR_IO) when trying to bulk write/read to the device. The device doesn't 'crash' as everything else keeps running, just stops talking USB, debug shows nothing wrong !
Best regards.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: STM32F1 Bulk transfer size problem
No news yet, I am in a busy month so little is going on with ChibiOS. I would appreciate if somebody could run a test about this else I will try again in next weekend.
Giovanni
Giovanni
Who is online
Users browsing this forum: Bing [Bot] and 6 guests