zheka 1 27 марта, 2015 Опубликовано 27 марта, 2015 · Жалоба Да как же это проверить, если функция всегда будет возвращать USB_OK? static uint16_t cdc_DataTx (uint8_t* Buf, uint32_t Len) { uint32_t i; //loop through buffer for( i = 0; i < Len; i++ ) { //push data into transfer buffer APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i]; //increase pointer value APP_Rx_ptr_in++; /* To avoid buffer overflow */ if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; } } return USBD_OK; } Смотрел разные библиотеки, "говор" в них немного разный, но суть этой функции везде одна и та же Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 марта, 2015 Опубликовано 27 марта, 2015 · Жалоба эта хрень не уменьшается по мере отправки? APP_Rx_ptr_in ? Если нет, то значит должен быть еще указатель который показывает где сейчас указатель последних отправленных данных Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Возвращаюсь к проекту. Мне удалось-таки настроить CDC на последней 5 версии KEIL и ее библиотеках. ПО упомянутой мной ранее СТАТЬЕ Как выяснилось, отправка байтов все-таки не поспевала за командами контроллера. Ибо когда я поставил буфер 1024 байта, а отправляю единовременно по 640 байт, проблемы не возникает. Но, сами понимаете, решение это временное. Хотелось бы знать, как мне организовать проверку, окончено ли задание по отправке пакета, можно ли направлять следующий? Как понять, свободен ли буфер? Перековырял всю библиотеку - то ли лыжи не едут... то ли я не пойму как это сделать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 14 апреля, 2015 Опубликовано 14 апреля, 2015 (изменено) · Жалоба Действительно, проблема оказалась временно решенной. Как только я попытался передать большой поток данных, начались тормоза. Первые ошибки отправки посыпались примерно на 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 - для контроля, когда возникает первая ошибка. Так как все-таки правильно передавать данные? Изменено 14 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Вроде б очевидно, что если функция не может отправить данные, надо чуть-чуть подождать, и это не ошибка, а вполне стандартная ситуация. PS всегда считал, что документацию кейл содержит в порядке. Ан нет - в код повсюду добавили параметр instance, а в описании на сайте его нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Спасибо, я уже в принципе и сам дошел до этого, ставлю небольшую задержку между отправками каждого байта. Подобрал ее опытным путем, пытаясь получить максимальную скорость. В итоге - 307200 байт передаются примерно за секунду. Кто-то писал, что CDC позволяет выжать 900 кбайт/сек. Как этого добиться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Чёрт, ну вот как, как до этого можно догадаться?! Есть обратная связь, получилось положить в буфер CDC или не получилось. Почему бы ей не пользоваться? Как ускорять кейловскую библиотеку, я не знаю. Подозреваю, что только выкидыванием и переписыванием. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Вроде б очевидно, что если функция не может отправить данные, надо чуть-чуть подождать Чёрт, ну вот как, как до этого можно догадаться?! Не надо иронизировать, а? Я прекрасно понимаю, что нужно чуть-чуть подождать, я спрашивал, как не ждать определенное время, а четко ловить момент, когда можно еще что-то пихать. Что-то типа while(cdc_is_busy) {} Как ускорять кейловскую библиотеку, я не знаю. Подозреваю, что только выкидыванием и переписыванием. Очень странное предложение. А я думал настройками, коих великое множество. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Если USBD_CDC_ACM_PutChar () не смог сделать этот самый putchar, он вернёт -1. Соответственно, ничего страшного не случится, если попросить его сделать это ещё раз. И ещё. А настроек там немного совсем. Во всяком случае, таких, которые может крутить пользователь. Размер пакета там уже установлен в 64 байта, что ещё можно поменять, не знаю. Как оно устроено внутри, кейл не говорит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 (изменено) · Жалоба Про ошибки - проехали. ПРо быстродействие - я уже где-то вычитал, что для того чтобы достичь максимума в 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 не определяется. Где собака порылась? Изменено 15 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба может где то в районе спецификации USB, по которой контрольная точка больше 64 байт для HS, FS устройств не допускает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 (изменено) · Жалоба может где то в районе спецификации USB, по которой контрольная точка больше 64 байт для HS, FS устройств не допускает? Возможно, но для HS размера пакета в настройках ставится 512 байт. И тем не менее - это тоже не 32 бит, как допускает параметр len Это и наталкивало меня на мысль, что размер буфера - вещь аппаратная, в функцию можно пихать столько, сколько позволяет разерность len и ресурсы конкретного контроллера, а она уже сама позаботится о разбивке. Кроме того, в настройках есть такой параметр: Maximum Communication Device Send Buffer Size, который выставляется до 1024 байт. СОбственно у меня он и выставлен в 1024 байт и я уже раскатал на них губу. Изменено 15 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба цитаты из исходников кейла: * - 'Maximum Communication Device Send Buffer Size' specifies the maximum * value for \em len in \ref USBD_CDC_ACM_WriteData // <o>Maximum Communication Device Send Buffer Size // <i>Specifies size of buffer used for sending of data to USB Host. // <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes // <128=>128 Bytes <256=>256 Bytes <512=>512 Bytes <1024=>1024 Bytes #define USBD_CDC%Instance%_SEND_BUF_SIZE 1024 Буфер, в который пишет USBD_CDC_ACM_WriteData() (ну и ваши тысячи USBD_CDC_ACM_PutChar()) организован в основной памяти контроллера, и оттуда библиотека перекладывает в контроллер USB кусочками по 64 байта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 (изменено) · Жалоба Буфер, в который пишет 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]; Изменено 15 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Максимум чего удалось добиться - uint8_t DataOut[256]; Вы бы пояснили, в ситуации, когда USB не определяется, 640 и 256 фигурируют только в размерности DataOut[], или при вызове USBD_CDC_ACM_WriteData() тоже? А то сейчас можно подумать, что DataOut[] локальная переменная, для которой просто не хватает стека. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться