|
Передача данных по USB, Потихоньку, по шагам надо реализовать... |
|
|
|
Oct 16 2010, 18:48
|

Участник

Группа: Участник
Сообщений: 28
Регистрация: 2-10-10
Пользователь №: 59 884

|
Доброго Всем время суток, Друзья! Есть интересная платка с процессором AT91SAM7S256. Только-только начал разбираться с написанием прошивок... Мигать уже умеем  Сейчас буду разбираться с передачей данных по USB-шинке (других портов на плате нет) Сильно надеюсь на Вашу помощь. Конкретных вопросов много, поэтому решил, что проще создать одну тему, где их буду разбирать. Вопрос для начала. Как прописать для платы PID/VID? Никакой инфы в даташитах по процессору я не нашел. В стандартных проектах, в которых устройству должен прописывается PID - 6119, я нигде не смог найти данную строку. Ну и правильно ли я понимаю, что если прописать PID/VID, то пока даже без настройки UDP и USART устройство будет определяться как "6119ое" ? Всем заранее Спасибо!
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Oct 17 2010, 14:31
|

Гуру
     
Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514

|
Цитата(mr.smart @ Oct 16 2010, 22:48)  Доброго Всем время суток, Друзья! Есть интересная платка с процессором AT91SAM7S256. Только-только начал разбираться с написанием прошивок... Мигать уже умеем  Сейчас буду разбираться с передачей данных по USB-шинке (других портов на плате нет) Сильно надеюсь на Вашу помощь. Конкретных вопросов много, поэтому решил, что проще создать одну тему, где их буду разбирать. Вопрос для начала. Как прописать для платы PID/VID? Никакой инфы в даташитах по процессору я не нашел. В стандартных проектах, в которых устройству должен прописывается PID - 6119, я нигде не смог найти данную строку. Ну и правильно ли я понимаю, что если прописать PID/VID, то пока даже без настройки UDP и USART устройство будет определяться как "6119ое" ? Всем заранее Спасибо! мда... а какое отношение слова UDP и USART имеют отношение к VID/PID и USB?
|
|
|
|
|
Oct 17 2010, 16:34
|

Участник

Группа: Участник
Сообщений: 28
Регистрация: 2-10-10
Пользователь №: 59 884

|
Цитата(toweroff @ Oct 17 2010, 17:31)  мда... а какое отношение слова UDP и USART имеют отношение к VID/PID и USB? Ну, мол, чтобы наладить передачу по USB (для начала хотя бы с эмуляцией COM-порта), нужно для начала сделать так чтоб драйвер просто определял устройство, а для этого в свою очередь нужно писать inf-файл, в котором прописывать PID. Я могу и ошибаться, Вы поправьте... Я для этого на этот форум и пришел. Я понял, что действия нужно провернуть следующие: - указываем для USB режим эмуляции СОМ (с CDC пока разбираюсь...) - указываем PID/VID - настраиваем USART - настраиваем всякие clock'и и прочее. - пишем собственно основу программки. Например: Код TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK); printf("test"); После всего этого можно подключать устройство, оно определяется как подключенное к СОМ. Ну и затем тестим его через гипертерминал, в котором должно появляться "test". Я где-то неправ?
|
|
|
|
|
Oct 18 2010, 06:31
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 21-06-09
Пользователь №: 50 494

|
почитайте данный топик, в котором я разбирался с USB. Первый пост - бред, а потом началось понимание. PS не рано ли за USB?
Сообщение отредактировал Shaienn - Oct 18 2010, 06:31
|
|
|
|
|
Oct 27 2010, 16:00
|

Участник

Группа: Участник
Сообщений: 28
Регистрация: 2-10-10
Пользователь №: 59 884

|
Цитата(Shaienn @ Oct 18 2010, 09:31)  PS не рано ли за USB? А что еще остается делать? На моей плате только один usb-порт есть и всё. Так. Используя стандартный Атмеловский пример "USB CDC serial converter" добился того, чтобы при подключении через USB устройство определялось как подключенное к COM-порту. Выдавать данные в гипертерминал получается с помощью готовенькой функции CDCDSerialDriver_Write. Считывать введенные данные получается с помощью готовенькой функции CDCDSerialDriver_Read. Но. Проблема в том, что единожды считав введенную информацию в буфер (например если ввести в гипертерминале символ "q"), буфер остается заполненным и новые символы туда не лезут, а функция CDCDSerialDriver_Write (которая выводит введенную информацию) постоянно выдает символ "q". Я так понимаю после CDCDSerialDriver_Write нужно как-то отчистить буфер. А вот как это сделать я не понимаю. Вот код функции считывания в буфер: Код char USBD_Read( unsigned char bEndpoint, void *pData, unsigned int dLength, TransferCallback fCallback, void *pArgument ) { Endpoint *pEndpoint = &(endpoints[bEndpoint]); Transfer *pTransfer = &(pEndpoint->transfer); // Return if the endpoint is not in IDLE state if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
return USBD_STATUS_LOCKED; }
TRACE_DEBUG_WP("Read%d(%d) ", bEndpoint, dLength); //TRACE_ERROR_WP("Read%d(%d) ", bEndpoint, dLength);
// Endpoint enters Receiving state pEndpoint->state = UDP_ENDPOINT_RECEIVING;
// Set the transfer descriptor pTransfer->pData = pData; pTransfer->remaining = dLength; pTransfer->buffered = 0; pTransfer->transferred = 0; pTransfer->fCallback = fCallback; pTransfer->pArgument = pArgument;
#ifdef DMA // Test if endpoint type control if (AT91C_OTGHS_EPT_TYPE_CTL_EPT == (AT91C_OTGHS_EPT_TYPE & AT91C_BASE_OTGHS->OTGHS_DEVEPTCFG[bEndpoint])) { #endif // Control endpoint // Enable endpoint IT AT91C_BASE_OTGHS->OTGHS_DEVIER = (1<<SHIFT_INTERUPT<<bEndpoint); AT91C_BASE_OTGHS->OTGHS_DEVEPTIER[bEndpoint] = AT91C_OTGHS_RXOUT; #ifdef DMA } else {
TRACE_DEBUG_WP("Read%d(%d) ", bEndpoint, dLength);
// Others endpoints (not control) if( pTransfer->remaining > DMA_MAX_FIFO_SIZE ) {
// Transfer the max pTransfer->buffered = DMA_MAX_FIFO_SIZE; } else { // Transfer the good size pTransfer->buffered = pTransfer->remaining; }
AT91C_BASE_OTGHS->OTGHS_DEVDMA[bEndpoint].OTGHS_DEVDMAADDRESS = (unsigned int)(pTransfer->pData);
// Clear unwanted interrupts AT91C_BASE_OTGHS->OTGHS_DEVDMA[bEndpoint].OTGHS_DEVDMASTATUS;
// Enable DMA endpoint interrupt AT91C_BASE_OTGHS->OTGHS_DEVIER = (1<<SHIFT_DMA<<bEndpoint);
TRACE_DEBUG_WP("\n\r_RR:%d ", pTransfer->remaining ); TRACE_DEBUG_WP("B:%d ", pTransfer->buffered ); TRACE_DEBUG_WP("T:%d ", pTransfer->transferred );
// DMA config AT91C_BASE_OTGHS->OTGHS_DEVDMA[bEndpoint].OTGHS_DEVDMACONTROL = 0; // raz AT91C_BASE_OTGHS->OTGHS_DEVDMA[bEndpoint].OTGHS_DEVDMACONTROL = (((pTransfer->buffered<<16)&AT91C_OTGHS_BUFF_LENGTH) | AT91C_OTGHS_END_TR_EN | AT91C_OTGHS_END_TR_IT | AT91C_OTGHS_END_B_EN | AT91C_OTGHS_END_BUFFIT | AT91C_OTGHS_CHANN_ENB); } #endif
return USBD_STATUS_SUCCESS; } Одно слово: нипонятна. Может кто-нибудь сталкивался с таким примером?
|
|
|
|
|
Nov 3 2010, 17:16
|

Участник

Группа: Участник
Сообщений: 28
Регистрация: 2-10-10
Пользователь №: 59 884

|
Эээм, прошу прощения за мой предыдущий пост с толстым кодом. Не сообразил использовать codebox, а сейчас уже вроде как нельзя отредактировать. Ну значит я пока решил отложить вопрос с тем примером и перешел на простой Атмеловский пример BasicUSB. Настроил CDC, разговор с платой веду через гипертерминал. Проблема осталась практически той же: при повторном использовании фун-ии write, программа зависает. Оказалось что при повторном использовании записи когда в ее финале происходит проверка на завершение передачи не приходит бит TXCOMP. Код //Wait for the end of transfer while ( !(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) ) if ( !AT91F_UDP_IsConfigured(pCdc) ) return length; pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); И из первого while'а программа выйти не может. В чем может быть проблема?
|
|
|
|
|
Nov 4 2010, 17:04
|

Участник

Группа: Участник
Сообщений: 28
Регистрация: 2-10-10
Пользователь №: 59 884

|
Цитата Я бы, на Вашем месте, не пилил чей-то код, а начал писать свой (подглядывая в чужой), понимая каждую строку кода и ожидаемую реакцию на нее.
Начните с инициализации UDP, прерывания от него. В обработчике прерывания поймайте AT91C_UDP_ENDBUSRES != 0 и двигайтесь дальше. Я хочу сперва разобраться с этим кодом, а потом уже писать своё. Сейчас меня гложет невозможность передать в гипертерминал больше 1го пакета. Как я понимаю алгоритм передачи: 1) проверяем не заполнен ли TXPKTRDY в UDP_CSR. 2) заполняем UDP_FDR. 3) сообщаем что мы готовы отправлять данные, устанавливая TXPKTRDY в единицу. 4) ожидаем пока хост не вернет нам TXCOMP. (одновременно с этим, как я понимаю, он обнуляет TXPKTRDY) 5) обнуляем TXCOMP. Мой код функции записи: Код AT91PS_UDP pUdp = pCdc->pUdp; // проверяем, готов ли юсб к передаче if (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) { return 0; } pUdp->UDP_FDR[AT91C_EP_IN] = 0x74; // хотим передать символ "t" pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; // готовы отправлять while ( !(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) ); // ждем пока нам не вернут TXCOMP pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); // обнуляем TXCOMP Символ 't' в гипертерминале появляется, но вот дождаться бита TXCOMP программа не может. В результате этот while зависает. В чем теоретически может быть проблема?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|