Перейти к содержанию
    

SviMik

Участник
  • Постов

    11
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный
  1. STM32 USB FS OTG

    Я сдаюсь :( Можете выложить какой-нибудь минимальный рабочий пример с USB? Или может я выложу свой проект целиком?
  2. STM32 USB FS OTG

    (Назначение hwtx - слать Hello World. Исключительно для дебага, поэтому упрощена до безобразия) Скорее всего, я упустил что-то важное, но не могу понять что :( Для общения через нулевой эндпоинт используется тот же алгоритм, и он работает. Разница только в типах эндпоинтов (control и bulk). И вот с bulk что-то не выходит. void hwtx(){ volatile uint32_t * fifo=(uint32_t *)OTG_FS_DFIFO2_BASE; int i; int len=12; char data[]={"Hello world\n"}; pprintf("1. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); OTG_FS->DIEPTSIZ2=(1<<19)|(len<<0); // PKTCNT; XFRSIZ OTG_FS->DIEPCTL2|=(1UL<<31)|(1<<26); // EPENA; CNAK for(i=0;i<len;i+=4){ *fifo=((data[i+0]&0xFF)<<0)|((data[i+1]&0xFF)<<8)|((data[i+2]&0xFF)<<16)|((data[i+3]&0xFF)<<24); } pprintf("2. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); }
  3. STM32 USB FS OTG

    Кажется, чего-то я в этой жизни не понимаю :( Из девайса в комп через второй эндпоинт отправляется только один пакет, после чего этот эндпоинт наглухо виснет. Пробовал: 1. Сбрасывать FIFO через регистр GRSTCTL. Как выборочно, так и все. 2. Отключать-включать эндпоинт, ставить CNAK 3. Сбрасывать весь регистр DIEPCTL2 в ноль, и заново конфигурировать 4. Плясать с бубном Идеи закончились. После успешной отправки "Hello world" на комп, второй раз отправить не удаётся. Только перетыкание кабеля срабатывает.
  4. STM32 USB FS OTG

    Всмысле? Функция hwtx() выше, вызываю её вручную, по команде в UART консоль. while(1){ if((USART3->SR & USART_SR_RXNE)){ // data received char c=USART3->DR; //... if(c=='3'){hwtx();} }
  5. STM32 USB FS OTG

    Всмысле флаг прерывания? Да, как и все остальные прерывания, сбрасываю. }else if(OTG_FS->DAINT&(1<<2)){ // IEPINT on EP 2 //print("- DAINT_IRQ: EP2 IN"); if(OTG_FS->DIEPINT2&(1<<0)){ // Data IN transaction completed OTG_FS->DIEPINT2=(1<<0); pprintf("EP_IRQ(IN): EP2 XFRC"); }else if(OTG_FS->DIEPINT2&(1<<1)){ // Endpoint disabled interrupt OTG_FS->DIEPINT2=(1<<1); pprintf("EP_IRQ(IN): EP2 EPDISD"); }else if(OTG_FS->DIEPINT2&(1<<3)){ // Timeout condition mask OTG_FS->DIEPINT2=(1<<3); pprintf("EP_IRQ(IN): EP2 TOC"); }else if(OTG_FS->DIEPINT2&(1<<4)){ // IN token received when TxFIFO is empty OTG_FS->DIEPINT2=(1<<4); pprintf("EP_IRQ(IN): EP2 ITTXFE"); }else if(OTG_FS->DIEPINT2&(1<<6)){ // IN endpoint NAK effective OTG_FS->DIEPINT2=(1<<6); pprintf("EP_IRQ(IN): EP2 INEPNE"); }else if(OTG_FS->DIEPINT2&(1<<7)){ // Transmit FIFO empty OTG_FS->DIEPINT2=(1<<7); pprintf("EP_IRQ(IN): EP2 TXFE"); }else{ pprintf("EP_IRQ(IN): EP2 %i", OTG_FS->DIEPINT2); } }
  6. STM32 USB FS OTG

    Хорошо. Тоесть моя конфигурация выше впринципе правильная, и должна работать? Но почему же с отправкой у меня проблемы... При этом, в нулевой эндпоинт отправлять дескрипторы проблем нет, а отправить данные в второй эндпоинт - проходит только первый пакет и всё. Возможно, с bulk эндпоинтами как-то иначе поступать надо? А документация уже утомила своими ляпами... В таблице одно, в тексте другое... Доходит до того, что в таблице бит подписан Reserved, а ниже в тексте даётся его нормальное описание. Или в таблице "r", а в описании сказано, что в него писать надо. IN и OUT тоже путают, приходится логически до всего доходить. Даже ссылки неправильные. кликаю в оглавлении на DIEPTSIZx, попадаю на DOEPTSIZx... такой вот тест на внимательность :( Извиняюсь, накипело...
  7. STM32 USB FS OTG

    Вомзжно, я что-то не так понял с FIFO буфферами. Если верить даташиту, размер буффера указывается в word, т.е. по 4 байта. Текущая инициализация FIFO выглядит так: OTG_FS->GRXFSIZ=64; // RX FIFO = x words OTG_FS->DIEPTXF0=(128<<16) | 64; // TX FIFO 0 = x words; start=x OTG_FS->DIEPTXF1=(64<<16) | 192; // TX FIFO 1 = x words; start=x OTG_FS->DIEPTXF2=(64<<16) | 256; // TX FIFO 2 = x words; start=x Это конфигурация, при которой девайс нормально инициализируется. При попытке уменьшить приёмный буффер, инициализация уже не проходит. Хотя 64 cлова (256 байт) явно избыточно для SETUP пакетов. Инициализация эндпоинтов: /* CDC endpoints: 0:control, 1:bulk out, 2:bulk in, 3:int in */ /* OUT */ OTG_FS->DOEPCTL0=(1<<26)|(1<<15)|(0<<0); // CNAK; active endpoint; Maximum packet size=64; OTG_FS->DOEPCTL1=(1<<26)|(2<<18)|(1<<15)|(64<<0); // CNAK; Endpoint type; active endpoint; Maximum packet size; /* IN */ OTG_FS->DIEPCTL0=(0<<22)|(1<<15)|(0<<0); // TxFIFO number; active endpoint; Maximum packet size=64; OTG_FS->DIEPCTL2=(2<<22)|(2<<18)|(1<<15)|(64<<0); // TxFIFO number; Endpoint type; active endpoint; Maximum packet size;
  8. STM32 USB FS OTG

    Пытаюсь реализовать CDC девайс. Что получилось: 1. Приём от компа к девайсу - без проблем, любое количество данных. 2. Отправка от девайса к компу - отправляется только первый пакет. Дальше ничего не шлётся. Что я мог упустить? void hwtx(){ volatile uint32_t * fifo=(uint32_t *)OTG_FS_DFIFO2_BASE; int i; int len=12; char data[]={"Hello world\n"}; pprintf("1. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); OTG_FS->DIEPTSIZ2=(1<<19)|(len<<0); // PKTCNT; XFRSIZ OTG_FS->DIEPCTL2|=(1UL<<31)|(1<<26); // EPENA; CNAK for(i=0;i<len;i+=4){ *fifo=((data[i+0]&0xFF)<<0)|((data[i+1]&0xFF)<<8)|((data[i+2]&0xFF)<<16)|((data[i+3]&0xFF)<<24); } pprintf("2. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); } попытка 1, строка приходит 1. FIFO: 64 words free 2. FIFO: 61 words free IRQ: SOF IRQ: EP2 IN XFRC (Transfer completed) попытка 2: 1. FIFO: 64 words free 2. FIFO: 61 words free попытка 3: 1. FIFO: 61 words free 2. FIFO: 58 words free тоесть далее просто забивается FIFO, а отправка не идёт...
  9. STM32 USB FS OTG

    Вот же однако... Заработало! Плюс вам в карму, если б она тут была :) А я CNAK только один раз при инициализации ставил, и думал оно так и будет... Интересно, а когда "по правилам" его надо ставить? "после обработки setup" это когда 1. закончил приём setup запроса 2. только записал ответ на setup в FIFO 3. когда отправка моего ответа уже завершена (сейчас я поставил от балды)
  10. STM32 USB FS OTG

    В моём случае, дескриптор взят из заведомо рабочего проекта, но под другой МК (ARM от атмела, ATSAM3S). Там я писал полностью сам, без библиотек, так что в протоколе USB немного понимаю (как мне кажется). Решил пересесть на STM, и вот такой затык. К сожалению, не всё. Я пробовал SniffUSB, но он начинает запись только после корректного опознания устройства, тоесть абсолютно бесполезен в моём случае. Мой текущий дескриптор девайса выглядит так (как я уже сказал, он заведомо рабочий): static char device_descriptor[18]={ /* Standard USB device descriptor for the CDC serial driver */ sizeof(device_descriptor), // size 1, // USBGenericDescriptor_DEVICE 0x00,0x02, // USBDeviceDescriptor_USB2_00 2, // CDCDeviceDescriptor_CLASS 0, // CDCDeviceDescriptor_SUBCLASS 0, // CDCDeviceDescriptor_PROTOCOL 64, // BOARD_USB_ENDPOINTS_MAXPACKETSIZE 0xEB,0x03, // CDCDSerialDriverDescriptors_VENDORID 0x24,0x61, // CDCDSerialDriverDescriptors_PRODUCTID 0x10,0x01, // CDCDSerialDriverDescriptors_RELEASE 1, // Index of manufacturer description //0 2, // Index of product description //0 3, // Index of serial number description //0 1, // One possible configuration }; (остальные не привожу, т.к. до них вообще дело не доходит) Что происходит на заведомо рабочей плате с SAM3S: 1. usb сброс 2. приходит setup пакет с запросом дескриптора девайса 3. МК отправляет дескриптор (18 байт) 4. usb сброс 5. приходит фрейм, назначающий адрес usb устройству 6. и т.д. Что происходит с STM32F4: не работает. 1. usb сброс 2. приходит setup пакет с запросом дескриптора девайса 3. МК отправляет дескриптор (18 байт) 4. а дальше тишина, и через 3 секунды переходим к п.1 Приблизительный код для стм32 (упрощено до безобразия в целях отладки): volatile uint32_t * fifo=(uint32_t *)(OTG_FS_DFIFO0_BASE); OTG_FS->DIEPTSIZ0=(1<<19)|18; // PKTCNT; XFRSIZ OTG_FS->DIEPCTL0=(1<<31)|(1<<26); // EPENA; CNAK *fifo=0x02000112; *fifo=0x40000002; *fifo=0x612403EB; *fifo=0x02010110; *fifo=0x00000103; Работу с FIFO предполагаю, на основе того, что чтение работает таким образом: volatile uint32_t * fifo=(uint32_t *)OTG_FS_DFIFO0_BASE; int i=0; for(i=0;i<BCNT;i+=4){ int data=*fifo; rbuf[i+0]=(data>>0)&0xFF; rbuf[i+1]=(data>>8)&0xFF; rbuf[i+2]=(data>>16)&0xFF; rbuf[i+3]=(data>>24)&0xFF; pprintf("< %02X%02X%02X%02X", rbuf[i+0], rbuf[i+1], rbuf[i+2], rbuf[i+3]); } Исходя из даташита, я делаю правильно. 1. DIEPTSIZ0 должен устанавливаться до того, как поставлю EPENA в DIEPCTL0 2. EPENA в DIEPCTL0 должен устанавливаться до того, как начну писать данные в FIFO. Однако, я пробовал и другой порядок действий, безрезультатно.
  11. STM32 USB FS OTG

    Ровно та же проблема, как и в последнем сообщении. XFRCM прерывание получаю, от компа на дескриптор ноль реакции. Дескриптор заведомо рабочий, взят из проекта, который делал на МК другого производителя. Пробовал делать как строго по даташиту, так и переставлять всё, что только возможно - не работает. Если автор решил проблему - хотелось бы узнать как :)
×
×
  • Создать...