Size: a a a

2021 February 28

VV

Vladislav Vasiliev in STM32
Andre Savelev
Надо поискать какой-нибудь флаг готовности.
Для USB CDC я делал проверку возвращаемого значения CDC_Transmit_FS() на предмет USBD_BUSY, выжидал 10 мкс и делал повтор отправки (в цикле 10 раз) внутри int _write(int file, char *ptr, int len) {} (коллбек для printf). Работает без нареканий. (Пишу на HAL)
источник

AS

Andre Savelev in STM32
Vladislav Vasiliev
Для USB CDC я делал проверку возвращаемого значения CDC_Transmit_FS() на предмет USBD_BUSY, выжидал 10 мкс и делал повтор отправки (в цикле 10 раз) внутри int _write(int file, char *ptr, int len) {} (коллбек для printf). Работает без нареканий. (Пишу на HAL)
Так, вижу, что  USBD_CUSTOM_HID_SendReport может вернуть USBD_BUSY

А внутри самой этой функции вот так:

——————-

uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef  *pdev,
                                  uint8_t *report,
                                  uint16_t len)
{
 USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;

 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
   if (hhid->state == CUSTOM_HID_IDLE)
   {
     hhid->state = CUSTOM_HID_BUSY;
     USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len);
   }
   else
   {
     return USBD_BUSY;
   }
 }
 return USBD_OK;
}

——————-

У меня есть

hUsbDeviceFS->pClassData

Наверное можно написать:

USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*) (hUsbDeviceFS.pClassData);

а потом проверять

   if (hhid->state == CUSTOM_HID_IDLE)
источник

AS

Andre Savelev in STM32
Проверю как смогу.
источник

VV

Vladislav Vasiliev in STM32
Andre Savelev
Так, вижу, что  USBD_CUSTOM_HID_SendReport может вернуть USBD_BUSY

А внутри самой этой функции вот так:

——————-

uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef  *pdev,
                                  uint8_t *report,
                                  uint16_t len)
{
 USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;

 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
   if (hhid->state == CUSTOM_HID_IDLE)
   {
     hhid->state = CUSTOM_HID_BUSY;
     USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len);
   }
   else
   {
     return USBD_BUSY;
   }
 }
 return USBD_OK;
}

——————-

У меня есть

hUsbDeviceFS->pClassData

Наверное можно написать:

USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*) (hUsbDeviceFS.pClassData);

а потом проверять

   if (hhid->state == CUSTOM_HID_IDLE)
Никогда не работал с HID, но, судя по всему, USBD_CUSTOM_HID_SendReport для HID нечто вроде CDC_Transmit_FS для CDC. Я бы не стал вмешиваться в библиотечную функцию, это может доставить много неудобств. На мой взгляд лучше проверку вынести "выше" и проверять возвращаемое значение именно функцией USBD_CUSTOM_HID_SendReport и, в случае если оно USBD_BUSY сделать паузу и выполнить повтор.
источник

AS

Andre Savelev in STM32
Vladislav Vasiliev
Никогда не работал с HID, но, судя по всему, USBD_CUSTOM_HID_SendReport для HID нечто вроде CDC_Transmit_FS для CDC. Я бы не стал вмешиваться в библиотечную функцию, это может доставить много неудобств. На мой взгляд лучше проверку вынести "выше" и проверять возвращаемое значение именно функцией USBD_CUSTOM_HID_SendReport и, в случае если оно USBD_BUSY сделать паузу и выполнить повтор.
Я тоже не предлагал менять исходники HAL. )

Переменная hUsbDeviceFS даётся всем (у вас тоже есть при работе с CDC).

И я думаю, что из неё можно вытащить состояние state, которое можно проверить вот так:

if (hhid->state == CUSTOM_HID_IDLE)
источник

AS

Andre Savelev in STM32
Как дойдут руки, я это проверю ещё и для CDC.
источник

VV

Vladislav Vasiliev in STM32
Andre Savelev
Как дойдут руки, я это проверю ещё и для CDC.
:) отпишитесь потом по результату
источник

AS

Andre Savelev in STM32
То есть вместо цикла ожидание - повторная отправка - проверка результата - ожидание - повторная отправка

можно крутиться в цикле, проверяя

if (hhid->state == CUSTOM_HID_IDLE)

и когда USB готов, смело отправлять данные.
источник

AS

Andre Savelev in STM32
Vladislav Vasiliev
:) отпишитесь потом по результату
Хорошо. ) Жаль, спать пора, так бы проверил.
источник

VV

Vladislav Vasiliev in STM32
Andre Savelev
То есть вместо цикла ожидание - повторная отправка - проверка результата - ожидание - повторная отправка

можно крутиться в цикле, проверяя

if (hhid->state == CUSTOM_HID_IDLE)

и когда USB готов, смело отправлять данные.
В целом да, но бесконечный цикл наверное делать не стОит... мало ли что :)
источник

VV

Vladislav Vasiliev in STM32
Я делаю 10 попыток и потом возврат ошибки если "все плохо" )
источник

AS

Andre Savelev in STM32
Vladislav Vasiliev
В целом да, но бесконечный цикл наверное делать не стОит... мало ли что :)
Повесить сторожевой таймер IWDG, который будет перезагружать контроллер через минуту. )
источник

VV

Vladislav Vasiliev in STM32
Andre Savelev
Повесить сторожевой таймер IWDG, который будет перезагружать контроллер через минуту. )
:) тоже вариант
источник

S

Sergey in STM32
Варианты быстрой дектриптовки aes кто какие юзает? Пробую tiny-aes 256 , 2кб требуют 391мс. Есть софтовый вариант быстрее?
источник
2021 March 01

AS

Andre Savelev in STM32
Vladislav Vasiliev
:) отпишитесь потом по результату
Проверил для HID, кажется работает.


//Сначала вызываю это
 delayWhileHIDIsBusy();
//Потом отправляю репорт      USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, (uint8_t*) dataToSend, 5);


void delayWhileHIDIsBusy() {
 while (!(((USBD_CUSTOM_HID_HandleTypeDef*) (hUsbDeviceFS.pClassData))->state
     == CUSTOM_HID_IDLE))
   ;
}
источник

AS

Andre Savelev in STM32
Vladislav Vasiliev
:) отпишитесь потом по результату
Для CDC тоже получилось.

void waitWhileCDCBusy() {
 while (((USBD_CDC_HandleTypeDef*) hUsbDeviceFS.pClassData)->TxState != 0)
   ;
}



Вызываю waitWhileCDCBusy(); перед тем как вызвать CDC_Transmit_FS, и вроде прекрасно работает.
источник

AS

Andre Savelev in STM32
Хотя если подумать, ваш метод с проверкой результата на USBD_BUSY не хуже. Так как внутри CDC_Transmit_FS делается такая же проверка.

Вчера просто уже спать хотел, и думал, что CDC_Transmit_FS может быть тяжёлой функцией, которая копирует какие-нибудь буферы, поэтому проверять результат её выполнения с повторной отправкой, может быть накладно.
источник

K

Kaktus776 in STM32
Всем привет. Такой вопрос по работе с DMA и GPIO. гонять массивы в порт это понятно. А такой вопрос, можно ли закидывать данные в порт GPIO данные частично (только на некоторые пины, не воздействуя на остальные)?
источник

D

Dr Zlo in STM32
Kaktus776
Всем привет. Такой вопрос по работе с DMA и GPIO. гонять массивы в порт это понятно. А такой вопрос, можно ли закидывать данные в порт GPIO данные частично (только на некоторые пины, не воздействуя на остальные)?
емнип только если в чипе есть bit banding
источник

K

Kaktus776 in STM32
Dr Zlo
емнип только если в чипе есть bit banding
Stm32h750
источник