BrunoB81HK
Member
I use RawHID with a Teensy 4.1 in my project and I need a control loop that run at at least 1kHz. Since RawHID's timeout are measured in ms, it is impossible to have a higher frequency than 500Hz since I call the recv and send function in each loop and they each take at least 1 ms.
To solve my problem, I went to the source code, in the cores/teensy4/usb_rawhid.c file and change the following :
to :
In summary, I changed all systick_millis_count to micros().
I don't know if those changes can bring other bugs, but so far, this has not caused me any problems. The communication is working and the data I receive is good.
Request: Implement those changes or something similar in the source code.
To solve my problem, I went to the source code, in the cores/teensy4/usb_rawhid.c file and change the following :
Code:
int usb_rawhid_recv(void *buffer, uint32_t timeout)
{
uint32_t wait_begin_at = systick_millis_count;
uint32_t tail = rx_tail;
while (1) {
if (!usb_configuration) return -1; // usb not enumerated by host
if (tail != rx_head) break;
if (systick_millis_count - wait_begin_at > timeout) {
return 0;
}
yield();
}
// digitalWriteFast(0, LOW);
if (++tail > RX_NUM) tail = 0;
uint32_t i = rx_list[tail];
rx_tail = tail;
memcpy(buffer, rx_buffer + i * RAWHID_RX_SIZE, RAWHID_RX_SIZE);
rx_queue_transfer(i);
//memset(rx_transfer, 0, sizeof(rx_transfer));
//usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
//usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
return RAWHID_RX_SIZE;
}
int usb_rawhid_send(const void *buffer, uint32_t timeout)
{
transfer_t *xfer = tx_transfer + tx_head;
uint32_t wait_begin_at = systick_millis_count;
while (1) {
if (!usb_configuration) return -1; // usb not enumerated by host
uint32_t status = usb_transfer_status(xfer);
if (!(status & 0x80)) break; // transfer descriptor ready
if (systick_millis_count - wait_begin_at > timeout) return 0;
yield();
}
uint8_t *txdata = txbuffer + (tx_head * RAWHID_TX_SIZE);
memcpy(txdata, buffer, RAWHID_TX_SIZE);
arm_dcache_flush_delete(txdata, RAWHID_TX_SIZE );
usb_prepare_transfer(xfer, txdata, RAWHID_TX_SIZE, 0);
usb_transmit(RAWHID_TX_ENDPOINT, xfer);
if (++tx_head >= TX_NUM) tx_head = 0;
return RAWHID_TX_SIZE;
}
to :
Code:
int usb_rawhid_recv(void *buffer, uint32_t timeout)
{
uint32_t wait_begin_at =micros();
uint32_t tail = rx_tail;
while (1) {
if (!usb_configuration) return -1; // usb not enumerated by host
if (tail != rx_head) break;
if (micros() - wait_begin_at > timeout) {
return 0;
}
yield();
}
// digitalWriteFast(0, LOW);
if (++tail > RX_NUM) tail = 0;
uint32_t i = rx_list[tail];
rx_tail = tail;
memcpy(buffer, rx_buffer + i * RAWHID_RX_SIZE, RAWHID_RX_SIZE);
rx_queue_transfer(i);
//memset(rx_transfer, 0, sizeof(rx_transfer));
//usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
//usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
return RAWHID_RX_SIZE;
}
int usb_rawhid_send(const void *buffer, uint32_t timeout)
{
transfer_t *xfer = tx_transfer + tx_head;
uint32_t wait_begin_at = micros();
while (1) {
if (!usb_configuration) return -1; // usb not enumerated by host
uint32_t status = usb_transfer_status(xfer);
if (!(status & 0x80)) break; // transfer descriptor ready
if (micros() - wait_begin_at > timeout) return 0;
yield();
}
uint8_t *txdata = txbuffer + (tx_head * RAWHID_TX_SIZE);
memcpy(txdata, buffer, RAWHID_TX_SIZE);
arm_dcache_flush_delete(txdata, RAWHID_TX_SIZE );
usb_prepare_transfer(xfer, txdata, RAWHID_TX_SIZE, 0);
usb_transmit(RAWHID_TX_ENDPOINT, xfer);
if (++tx_head >= TX_NUM) tx_head = 0;
return RAWHID_TX_SIZE;
}
In summary, I changed all systick_millis_count to micros().
I don't know if those changes can bring other bugs, but so far, this has not caused me any problems. The communication is working and the data I receive is good.
Request: Implement those changes or something similar in the source code.