|
|
  |
STM32F4, DCMI и USB |
|
|
|
Apr 14 2015, 09:38
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Возвращаюсь к проекту. Мне удалось-таки настроить CDC на последней 5 версии KEIL и ее библиотеках. ПО упомянутой мной ранее СТАТЬЕКак выяснилось, отправка байтов все-таки не поспевала за командами контроллера. Ибо когда я поставил буфер 1024 байта, а отправляю единовременно по 640 байт, проблемы не возникает. Но, сами понимаете, решение это временное. Хотелось бы знать, как мне организовать проверку, окончено ли задание по отправке пакета, можно ли направлять следующий? Как понять, свободен ли буфер? Перековырял всю библиотеку - то ли лыжи не едут... то ли я не пойму как это сделать...
|
|
|
|
|
Apr 14 2015, 11:55
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Действительно, проблема оказалась временно решенной. Как только я попытался передать большой поток данных, начались тормоза. Первые ошибки отправки посыпались примерно на 16 500 байте. Вот как я отправляю Код while(1) {
if (USBD_Configured (0)) { /* USB -> MCU */ if (usb_rx_ch == -1) { usb_rx_ch = USBD_CDC_ACM_GetChar (0); } if (usb_rx_ch != -1) {
for (j=0;j<480;j++) { for (i=0;i<640;i++) { sprintf(ss,"%d ",i); RESULT=USBD_CDC_ACM_PutChar (0, ss[0]); // на эту хрень не обращайте внимания, это временно урезаный кусок. if (RESULT==-1) { if (ERRORS==0) {ierr=i;jerr=j;} ERRORS++; } } } } if (usb_rx_ch != LF) usb_rx_ch = -1; } } ierr и jerr - для контроля, когда возникает первая ошибка. Так как все-таки правильно передавать данные?
Сообщение отредактировал zheka - Apr 14 2015, 12:06
|
|
|
|
|
Apr 15 2015, 06:15
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Цитата Вроде б очевидно, что если функция не может отправить данные, надо чуть-чуть подождать Цитата Чёрт, ну вот как, как до этого можно догадаться?! Не надо иронизировать, а? Я прекрасно понимаю, что нужно чуть-чуть подождать, я спрашивал, как не ждать определенное время, а четко ловить момент, когда можно еще что-то пихать. Что-то типа while(cdc_is_busy) {} Цитата Как ускорять кейловскую библиотеку, я не знаю. Подозреваю, что только выкидыванием и переписыванием. Очень странное предложение. А я думал настройками, коих великое множество.
|
|
|
|
|
Apr 15 2015, 10:30
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Если USBD_CDC_ACM_PutChar () не смог сделать этот самый putchar, он вернёт -1. Соответственно, ничего страшного не случится, если попросить его сделать это ещё раз. И ещё.
А настроек там немного совсем. Во всяком случае, таких, которые может крутить пользователь. Размер пакета там уже установлен в 64 байта, что ещё можно поменять, не знаю. Как оно устроено внутри, кейл не говорит.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 15 2015, 10:54
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Про ошибки - проехали. ПРо быстродействие - я уже где-то вычитал, что для того чтобы достичь максимума в 1.2 мбайт/с, нужно оперировать нужно массивами. Для массивов есть спецфункция Код extern int32_t USBD_CDC_ACM_WriteData (int8_t instance, const uint8_t *buf, int32_t len); Как видите len - 32битный. Но в настройках больше 64 байт в endpoint не ставится. Даже если сам buf объявить больше чем на 64 байта - устройство USB не определяется. Где собака порылась?
Сообщение отредактировал zheka - Apr 15 2015, 10:56
|
|
|
|
|
Apr 15 2015, 11:09
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Цитата(Golikov A. @ Apr 15 2015, 13:59)  может где то в районе спецификации USB, по которой контрольная точка больше 64 байт для HS, FS устройств не допускает? Возможно, но для HS размера пакета в настройках ставится 512 байт. И тем не менее - это тоже не 32 бит, как допускает параметр len Это и наталкивало меня на мысль, что размер буфера - вещь аппаратная, в функцию можно пихать столько, сколько позволяет разерность len и ресурсы конкретного контроллера, а она уже сама позаботится о разбивке. Кроме того, в настройках есть такой параметр: Maximum Communication Device Send Buffer Size, который выставляется до 1024 байт. СОбственно у меня он и выставлен в 1024 байт и я уже раскатал на них губу.
Сообщение отредактировал zheka - Apr 15 2015, 11:27
|
|
|
|
|
Apr 15 2015, 12:32
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Цитата Буфер, в который пишет USBD_CDC_ACM_WriteData() (ну и ваши тысячи USBD_CDC_ACM_PutChar()) организован в основной памяти контроллера, вооооот.... Тогда почему же, если я делаю вот так Код uint8_t DataOut[64]; uint8_t *pDataOut; ..... USBD_CDC_ACM_WriteData(0,pDataOut,64); и ставлю в первой строке DataOut[640], то при запуске USB вообще не определяется? Работая кусками по 64 байта и склеивая их по 10 уже на компьютере, я все-таки получил вывод картинки со скоростью 1 кадр за 0.3 секунды (как раз примерно 900 кб/сек). Но гложет меня этот короткий буфер. Я пока-что искусственно генерю содержимое памяти. Сейчас вот прикручу DCMI и DMA - подозреваю что будут проблемы. Хотелось целую строку запихивать в буфер и тут же по сигналу окончания считывания строки отправлять ее по USB... Максимум чего удалось добиться - uint8_t DataOut[256];
Сообщение отредактировал zheka - Apr 15 2015, 11:53
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|