Serg1987 писал(а):И опять по поводу приема первого SETUP. Хост мне постоянно присылает вот это:
Всё как и у Radist_M..)
И теперь вопрос по поводу дальнейшего. После принятия SETUPа, как я понял из прочтенного STAT_TX выставляется в NACK??!! Т.е. сейчас мне нужно запихнуть в передающий буфер данные дескриптора и поставить STAT_TX в VALID??

Что делать со STAT_RX. Запрещать его на время передачи дескриптора, или оставить навсегда VALID?

Сразу скажу, что работаю по прерываниям.
Как только будет принят SETUP пакет: железо USB выставляет и STAT_TX и STAT_RX, в NAK для того чтобы прошивка затем решила что ей делать - принимать или передавать. А пока прошивка думает - хост будет получать на запросы RX/TX - NAK.
NAK это 10, VALID - 11. Т.е. нужно выставить нулевой бит.
Что происходит у меня:
1. После того как хост определит устройство он посылает RESET.
1.1 В обработчике прерывания смотрю регистр ISTR, проверю не резет ли это и если да, то делаю вот что:
(примечание - по сигналу резет регистры USB сбрасываются в исходное состояние)
USB->ISTR = 0;//очищаем сбытие резет
//регистр нулевой КТ девственно чист - заполняем его.
USB->EP0R = USB_EP0R_EP_TYPE_0|USB_EP0R_STAT_RX|USB_EP0R_STAT_TX_1;// тип control, STAT_RX в VALID и STAT_TX в NAK.
2. Затем хост присылает SETUP пакет:
Код: Выделить всё
0x80
0x06 - запрос дескриптора какого-то
0x00
0x01 - а точнее дескриптор устройства
0x00
0x00
0x40 - хост просит 64 байта
0x00
смотрю первый принятый байт 0x06, ага - запрос дескриптора. Остальные байты не смотрю и так знаю что это запрос дескриптора устройства
1. Загружаю в пакетную память дескриптор устройства, который представлен ниже (хотя это можно сделать заранее)
Код: Выделить всё
const uint8_t RHID_DeviceDescriptor[RHID_SIZ_DEVICE_DESC] = {
RHID_SIZ_DEVICE_DESC, // overall descriptor length
USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType - Device descriptor
0x00, 0x02, // bcdUSB usb 2.0
// class, subclass
0x00, //bDeviceClass
0x00, //bDeviceSubClass
0x00, //bDeviceProtocol
0x40, //bMaxPacketSize - max size of packets
// vid pid
0x25, 0x09, //idVendor (0x0483)0925
0x34, 0x12, //idProduct (0x5711)
DEVICE_VER_L, DEVICE_VER_H, // bcdDevice rel. DEVICE_VER_H.DEVICE_VER_L
// Sushchestvuyut dopolnitel'nyye indeksy stroki , opisyvayushchiye proizvoditel' i seriynyy nomer ustroystva .
// Otobrazhayetsya v svoystvakh ustroystva v dispetchere ustroystv
// A seriynyye nomera podklyuchennykh ustroystv s odinakovymi VID / PID drugoy sisteme
1, //Index of string descriptor describing manufacturer
2, //Index of string descriptor describing product
3, //Index of string descriptor describing the device serial number
0x01 // bNumConfigurations - kol-vo vozmozhnih configurations.
} ; /* CustomHID_DeviceDescriptor */
2. Пишу в регистр COUNT0TX размер дескриптора:
DiscrTable->COUNT0TX = RHID_SIZ_DEVICE_DESC; //0x12
3. И говорю контроллеру. что готов передавать:
Код: Выделить всё
USB->EP0R = USB_EP0R_EP_TYPE_0|USB_EP0R_STAT_TX_0;
Т.е . в регистр нулевой конечной точки пишу как бы два значения -
USB_EP0R_EP_TYPE_0 - этим я оставляю без изменений тип конечной точки Control
USB_EP0R_STAT_TX_0 - ну и выставляю 0-й бит STAT_TX, т.е. перевожу из NAK в VALID.
STAT_RX так и останется в NAK - это нисколько не мешает жить.
дальше происходит событие CORRECT TRANSFER
далее RESET
далее приходит опять SETUP пакет - смотри
Код: Выделить всё
0x00
0x05 - SET ADDRES
0x05 - это собсно адрес, который нам присвоил хост
0x00
0x00
0x00
0x00
0x00
Это запрос SET ADDRESS, тогда делаю вот что:
1. помещаю во временную переменную со спецификатором static полученный адрес (2-й принятый байт) +USB_DADDR_EF(это из заголовочного файла на МК, означает ENABLE FUNCTION) . Теперь это значение будет храниться между вызовами прерывания.
2. в регистр COUNT0TX пишу 0x00 - тем самым, сообщая что будем передавать 0 байт - этот тот самый ZLP (zero length packet). Так хост поймет, что мы приняли адрес
3. и последнее USB->EP0R = USB_EP0R_EP_TYPE_0|USB_EP0R_STAT_TX_0;//STAT_TX - valid передаем, короче
далее происходит событие CORRECT TRANSFER и вот тут я беру значение из временой перемнной и пишу в регистр USB->DADDR.
Код: Выделить всё
if (temp!=0)
{
USB->DADDR = temp;
temp=0;
}
Только с этого момнта контроллер будет откликаться на присоенный адрес хостом.
далее получаю опять SETUP пакет
Видали? то же самое, только теперь хост просит не 0x40 а 0x12 байт дескриптора
Повторяю процедуру отправки, получаю событие CORRECT TRANSFER и далее получаю 3 резета от хоста. Печаль. Дальше пока не продвинулся((.