реклама на сайте
подробности

 
 
> Передача данных по USB, Потихоньку, по шагам надо реализовать...
mr.smart
сообщение Oct 16 2010, 18:48
Сообщение #1


Участник
*

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



Доброго Всем время суток, Друзья!

Есть интересная платка с процессором AT91SAM7S256. Только-только начал разбираться с написанием прошивок... Мигать уже умеем smile.gif
Сейчас буду разбираться с передачей данных по USB-шинке (других портов на плате нет) Сильно надеюсь на Вашу помощь. Конкретных вопросов много, поэтому решил, что проще создать одну тему, где их буду разбирать.

Вопрос для начала.
Как прописать для платы PID/VID? Никакой инфы в даташитах по процессору я не нашел. В стандартных проектах, в которых устройству должен прописывается PID - 6119, я нигде не смог найти данную строку.
Ну и правильно ли я понимаю, что если прописать PID/VID, то пока даже без настройки UDP и USART устройство будет определяться как "6119ое" ?

Всем заранее Спасибо!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
toweroff
сообщение Oct 17 2010, 14:31
Сообщение #2


Гуру
******

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



Цитата(mr.smart @ Oct 16 2010, 22:48) *
Доброго Всем время суток, Друзья!

Есть интересная платка с процессором AT91SAM7S256. Только-только начал разбираться с написанием прошивок... Мигать уже умеем smile.gif
Сейчас буду разбираться с передачей данных по USB-шинке (других портов на плате нет) Сильно надеюсь на Вашу помощь. Конкретных вопросов много, поэтому решил, что проще создать одну тему, где их буду разбирать.

Вопрос для начала.
Как прописать для платы PID/VID? Никакой инфы в даташитах по процессору я не нашел. В стандартных проектах, в которых устройству должен прописывается PID - 6119, я нигде не смог найти данную строку.
Ну и правильно ли я понимаю, что если прописать PID/VID, то пока даже без настройки UDP и USART устройство будет определяться как "6119ое" ?

Всем заранее Спасибо!

мда...
а какое отношение слова UDP и USART имеют отношение к VID/PID и USB?
Go to the top of the page
 
+Quote Post
mr.smart
сообщение Oct 17 2010, 16:34
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 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". Я где-то неправ?
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 17 2010, 17:23
Сообщение #4


Гуру
******

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



Здесь есть большая разница. Вы пытаетесь поднять CDC пот какой-то ОС, или ваяете "с нуля" USB поддержку для камня?
Отсюда разные вопросы и разные направления решения
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Oct 17 2010, 19:58
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



А что примеры CDC от Atmel'a чем-то не устраивают? Там же все сделано без всяких ОС.

VID/PID вы должны прописать в дескрипторе usb устройства и такие же указать в inf файле.
Go to the top of the page
 
+Quote Post
Shaienn
сообщение Oct 18 2010, 06:31
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 103
Регистрация: 21-06-09
Пользователь №: 50 494



почитайте данный топик, в котором я разбирался с USB. Первый пост - бред, а потом началось понимание.

PS не рано ли за USB?

Сообщение отредактировал Shaienn - Oct 18 2010, 06:31
Go to the top of the page
 
+Quote Post
mr.smart
сообщение Oct 27 2010, 16:00
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 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;
}


Одно слово: нипонятна. Может кто-нибудь сталкивался с таким примером?
Go to the top of the page
 
+Quote Post
mr.smart
сообщение Nov 3 2010, 17:16
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 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'а программа выйти не может. В чем может быть проблема?
Go to the top of the page
 
+Quote Post
Shaienn
сообщение Nov 4 2010, 00:34
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 103
Регистрация: 21-06-09
Пользователь №: 50 494



Я бы, на Вашем месте, не пилил чей-то код, а начал писать свой (подглядывая в чужой), понимая каждую строку кода и ожидаемую реакцию на нее.

Начните с инициализации UDP, прерывания от него. В обработчике прерывания поймайте AT91C_UDP_ENDBUSRES != 0 и двигайтесь дальше.

Сообщение отредактировал Shaienn - Nov 4 2010, 00:38
Go to the top of the page
 
+Quote Post
mr.smart
сообщение Nov 4 2010, 17:04
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 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 зависает. В чем теоретически может быть проблема?
Go to the top of the page
 
+Quote Post
mr.smart
сообщение Nov 5 2010, 10:47
Сообщение #11


Участник
*

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



Затестили ту же самую программу на той же самой плате, но на другой машине с Вистой и соответственно другим драйвером usbser. Работает как надо. Бит TXCOMP приходит, когда следует.
Отсюда еще вопрос: некорректная работа с XP-шным драйвером - это просто баг XP-шного драйвера, а сама программа написана правильно, или корректная работа на Висте - это следствие того, что ее драйвер лояльнее относится к плохо написанной программе? Или может быть не в драйвере дело, а в железе?...
Go to the top of the page
 
+Quote Post
AlfaStar
сообщение Nov 5 2010, 14:28
Сообщение #12


Участник
*

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



Чувак... Понял твою проблему. Вот тебе четкий ответ. Считаю, что все дело в дровах. Переустанови их и 100% заработает. А лучше хлебни пивка и все сразу получиться! ВОт как вижу... beer.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 14:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01448 секунд с 7
ELECTRONIX ©2004-2016