По поводу IN.
Приходит от хоста запрос чего-то. Пускай какого-то дескриптора. Вы ложите копируете соответствующие данные в буфер и устанавливаете VALID. Если данные "уйдут", выставится соответствующий флаг об успешной отправки. Кроме того, если хосту понравятся данные, он отправит ZLP устройству, а не устройство хосту. И как мне кажется, это очень логично.
Radist_M писал(а):отправить пакет нулевой длинны, чтоб комп понял, что мы приняли пакет.
То есть не ОН нам, а МЫ ему. Нужно ли это делать?
Z_h_e писал(а):Если данные "уйдут", выставится соответствующий флаг об успешной отправки
Z_h_e писал(а):Кроме того, если хосту понравятся данные, он отправит ZLP устройству
Данные уходят (флаг выставляется), но ZLP не приходит. И дело тут вряд ли в дескрипторе, так как я пробовал не один вариант и все сверял с Агуровым - сходилось...
void SetRXTX (uint8_t EPNum, uint8_t EPStatus, uint8_t RXTX) //номер регистра EPnR, S - Disabled,Stall,NAK,Valid, f - TX отправить RX прием
{
/*
EPNum EPStatus RXTX
0 to 7 0 - Disable 0 - RX
1 - Stall 1 - TX
2 - NAK
3 - VALID
*/
uint16_t buff;
uint8_t stat;
buff = ((uint16_t*)0x40005C00)[EPNum]; //0x40005C00 базовый адрес регистров юсб
test6 = *((uint16_t*)0x40005C00);
if (RXTX == 1)////////////////////////////////RXTX = 1 = TX
{
stat = (buff>>4) & 3;
switch (stat)
{
case 0: //DISABLE
switch (EPStatus)
{
case 0:
break;
case 1:
buff^=0x0010; buff&=0x8F9F; break; //TX
case 2:
buff^=0x0020; buff&=0x8FAF; break; //TX
case 3:
buff^=0x0030; buff&=0x8FBF; break; //TX
}
break;
...............
Отлаживал по шагам и случайно заметил, что при таком значении маски в некоторых случаях будет изменяться бит, который должен сохранить свое значение.
В итоге получились две функции отработки STAT битов:
Спойлер
Я конечно рад за Вас, что продвинулись дальше, очень скучно топтаться на месте. Однако подобные функции я выкладывал много постов назад и почему то они Вас не заинтересовали.
По поводу Вашей функции void CTR_RXTXClear (uint8_t EPNum, uint16_t RXBitClear, uint16_t TXBitClear). Оба флага будут сброшены при любых значениях 2 и 3 ого параметров функции.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вот еще, сразу не заметил. ((uint16_t*)0x40005C00)[EPNum]; Так Вы прочитаете/запишите правильно только нулевой регистр. Или считывайте 32 бита или используйте двойной индекс.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Z_h_e писал(а):Однако подобные функции я выкладывал много постов назад и почему то они Вас не заинтересовали
Не то чтобы не устроили, просто у Вас только в два состояния устанавливаются, а я хотел сделать все - чтоб наверняка, но не до конца все правильно рассчитал...
Z_h_e писал(а):Вот еще, сразу не заметил. ((uint16_t*)0x40005C00)[EPNum]; Так Вы прочитаете/запишите правильно только нулевой регистр
Спасибо за замечание. Учту .
Пока продвинулся до запроса дескриптора конфигурации и напоролся на грабли. Взял дескриптор со страницы: http://badembed.ru/stm32l-usb-cdc-virtu ... t-nachalo/ Там 67 элементов, а буфер расчитан на 64. Как тогда быть?
isx писал(а): Сначала нужно 9 байт, а потом понемногу досылать остальное (по мере затребования хостом).
Думаю Вы неправы. У меня тоже был длинный дескриптор и вроде как у меня удалось отправить его по частям. Затем он у меня уменьшился и необходимость в этом отпала. Когда дескриптор был еще длинным )), мое USB не работало еще полностью и это было давно, я напишу как я делал, но есть сомнения, что я правильно помню.
- хост запрашивает первые 9 байт дескриптора конфиг
+ устройство отправляет их.
- хост отправляет ZLP
- хост запрашивает то ли полный длинный дескриптор (например 67) то ли 64
+ устройство отпраляет первые 64 байта
- хост запрашивает остальные 3 байта
+ устройство отпраляет остаток.
- хост отпраляет ZLP
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Z_h_e писал(а):void CTR_RXTXClear (uint8_t EPNum, uint16_t RXBitClear, uint16_t TXBitClear). Оба флага будут сброшены при любых значениях 2 и 3 ого параметров функции.
Исправил buff&=0x0F0F; на buff&=0x8F8F;.
Z_h_e писал(а): ((uint16_t*)0x40005C00)[EPNum]; Так Вы прочитаете/запишите правильно только нулевой регистр.
Z_h_e писал(а):- хост запрашивает первые 9 байт дескриптора конфиг
+ устройство отправляет их.
- хост отправляет ZLP
- хост запрашивает то ли полный длинный дескриптор (например 67) то ли 64
+ устройство отпраляет первые 64 байта
- хост запрашивает остальные 3 байта
+ устройство отпраляет остаток.
- хост отпраляет ZLP
Все почти так и происходит.
- хост запрашивает первые 9 байт дескриптора конфиг
+ устройство отправляет их.
- хост отправляет ZLP
- хост запрашивает то ли полный длинный дескриптор (например 67) то ли 64
(приходит 0680 0200 0000 0043)
+ устройство отпраляет первые 64 байта
и дальше ничего не происходит. В буфере приема так и остается 0680 0200 0000 0043.
Но, если отправлять не 64 байта, а отправить также 9 байт, то идут запросы строк, потом снова запрос 12-ти байт дескриптора, потом такой запрос:
0680 0200 0000 0109
и все. Если отправть 9 байт дескриптра конфигурации, то ничего не меняется...
Я ж говорю, я точно не помню как отправлял. Возможно нет запроса от хоста на вторую часть. Наверное тогда надо после успешной отправки 64 байт, не ждать запроса, а положить в буфер еще 3 байта и сразу выставить VALID.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
в f429 для контрольной передачи:
1 - получаем, например, запрос гет-дескриптор
2 - отправляем этот дескриптор хосту
3 - получаем от хоста нулевой пакет.
case 0x0043:
SendBuff (Virtual_Com_Port_ConfigDescriptor,64,0);
SetTX(0, 3); // to Valid TX
while ((USB_EP0R & USB_EP_CTR_TX)==0)
{;}
for (i = 64; i < 68; i+=2) // i = 18
{
TXBuff = Virtual_Com_Port_ConfigDescriptor[i] + (Virtual_Com_Port_ConfigDescriptor[i+1] << 8);
*(__IO uint16_t*)(0x40006080 + (i-64)*2) = TXBuff;
}
*(__IO uint16_t*)(0x40006004) = (uint16_t) 3;
SetTX(0, 3); // to Valid TX
break;
Вроде работает, но не всегда. Приходится несколько раз передергивать шнур и ресетить МК в отладчике, пока запрос дескриптора (см. шестой элемент массива в приложении) успешно отработается. Пока не могу понять, почему так происходит ....
Теперь зависаю после запроса 9-ти байт конфигурации (последний элемент массива). После отправки 9-ти байт приходит ZLP и все - больше никаких запросов.
Куда можно дальше копать ?
P.S. Значения в массив записываются по каждому срабатыванию прерывания по успешному приему данных (CTR_TX).
Может пока стоит попробовать сделать дескриптор покороче? У меня на этой стадии никаких проблем не было, однако когда я дошел до нее, у меня дескриптор не был уже длинным. Так то после запроса 9 байт, следующий запрос должен был быть запрос дескриптора конфигурации уже с точной длиной.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вообщем, навертел, накрутил, но до конца не дошло ) .
Теперь энумерация устройства проходит нормально (см. до 21-го элемента массива включительно). Потом устройстве появляется в диспетчере устройств как виртуальный ком порт. Advanced Terminal его видит и при попытке подключиться к порту вылетает ещё куча запросов. Описать дальше я не могу нормально, так как сам толком не понимаю что происходит. Прикладываю код с обработкой прерываний и скрин со всеми прерываниями по CTR_RX с запросами.
Спойлер
Попробовал разобрать значение поля bmRequestType=0x22.
7 - 0 хост что-то отправляет устройству (т.е. ничего не запрашивает)
6:5 - 01 специфический запрос для данного класса
4:0 - 00010 другой получатель
Кто такой другой получатель мне не понятно, а вот специфический это значит что надо смотреть запросы для класса CDC. Вот тут попробуйте порыть http://www.usb.org. Где-то в инете увидел, что надо смотреть в разделе 5, но не знаю какого документа, хотя самому интересно, но сейчас времени нет.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вот тут в конце статьи расписано не плохо http://www.softelectro.ru/usb.html , но у меня как-то не так проходит процесс.
Плюс прошелся сниффером по своей прошивке и по прошивке с Microtechnics.ru (тоже CDC и нормально подключается к программе терминалу). Думал, что мне это что-то прояснит, но ошибся. Может более опытные смогут что-то там разглядеть .
Процесс моей энумерации:
Спойлер000000: PnP Event: Device Connected (UP), 2016-08-25 19:20:37,4499617 (1. Device: STMicroelectronics Virtual COM Port (COM13))
The USB device has just been connected to the system.
000001: Get Descriptor Request (DOWN), 2016-08-25 19:20:37,4500336 +0,0000719 (1. Device: STMicroelectronics Virtual COM Port (COM13))
Descriptor Type: Device
Descriptor Index: 0x0
Transfer Buffer Size: 0x12 bytes
000002: Control Transfer (UP), 2016-08-25 19:20:37,4502671 +0,0002335. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0x00000000
Pipe Handle: Control Pipe
000003: Get Descriptor Request (DOWN), 2016-08-25 19:20:37,4502729 +0,0000058 (1. Device: STMicroelectronics Virtual COM Port (COM13))
Descriptor Type: Configuration
Descriptor Index: 0x0
Transfer Buffer Size: 0x109 bytes
000004: Control Transfer (UP), 2016-08-25 19:20:37,4505108 +0,0002379. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0x00000000
Pipe Handle: Control Pipe
000007: Class-Specific Request (DOWN), 2016-08-25 19:20:37,4507124 +0,0000150 (1. Device: STMicroelectronics Virtual COM Port (COM13))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x21
Value: 0x0
Get 0x7 bytes from the device
000008: Control Transfer (UP), 2016-08-25 19:20:37,4508854 +0,0001730. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0x00000000
Pipe Handle: Control Pipe
000009: Class-Specific Request (DOWN), 2016-08-25 19:20:37,4509364 +0,0000510 (1. Device: STMicroelectronics Virtual COM Port (COM13))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x22
Value: 0x0
Send 0x0 bytes to the device
000010: Control Transfer (UP), 2016-08-25 19:20:37,4511358 +0,0001994. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0x00000000
Pipe Handle: Control Pipe
000013: Bulk or Interrupt Transfer (UP), 2016-08-25 19:20:37,4512626 +0,0001045. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0xc0000004
Pipe Handle: 0x35d2798 (Endpoint Address: 0x83)
Get 0x0 bytes from the device
000014: Bulk or Interrupt Transfer (UP), 2016-08-25 19:20:37,5474432 +0,0961806. (1. Device: STMicroelectronics Virtual COM Port (COM13)) Status: 0xc0000004
Pipe Handle: 0x57d3608 (Endpoint Address: 0x81)
Get 0x0 bytes from the device
При этом, Device Monitor Studio выделяет 13 и 14-е шаги красным цветом.
Процесс энумерации при использовании рабочей прошивки:
Спойлер000000: PnP Event: Device Connected (UP), 2016-08-25 19:07:39,5185216 (1. Device: STMicroelectronics Virtual COM Port (COM7))
The USB device has just been connected to the system.
000001: Get Descriptor Request (DOWN), 2016-08-25 19:07:39,5186023 +0,0000807 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Descriptor Type: Device
Descriptor Index: 0x0
Transfer Buffer Size: 0x12 bytes
000002: Control Transfer (UP), 2016-08-25 19:07:39,5188247 +0,0002224. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000003: Get Descriptor Request (DOWN), 2016-08-25 19:07:39,5188306 +0,0000059 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Descriptor Type: Configuration
Descriptor Index: 0x0
Transfer Buffer Size: 0x109 bytes
000004: Control Transfer (UP), 2016-08-25 19:07:39,5190714 +0,0002408. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000007: Class-Specific Request (DOWN), 2016-08-25 19:07:39,5192694 +0,0000136 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x21
Value: 0x0
Get 0x7 bytes from the device
000008: Control Transfer (UP), 2016-08-25 19:07:39,5194453 +0,0001759. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000009: Class-Specific Request (DOWN), 2016-08-25 19:07:39,5195043 +0,0000590 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x22
Value: 0x0
Send 0x0 bytes to the device
000010: Control Transfer (UP), 2016-08-25 19:07:39,5196956 +0,0001913. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000013: Class-Specific Request (DOWN), 2016-08-25 19:07:41,4999857 +1,9802684 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x21
Value: 0x0
Get 0x7 bytes from the device
000014: Control Transfer (UP), 2016-08-25 19:07:41,5001689 +0,0001832. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000015: Class-Specific Request (DOWN), 2016-08-25 19:07:41,5001847 +0,0000158 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x21
Value: 0x0
Get 0x7 bytes from the device
000016: Control Transfer (UP), 2016-08-25 19:07:41,5004090 +0,0002243. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000017: Class-Specific Request (DOWN), 2016-08-25 19:07:41,5005454 +0,0001364 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x22
Value: 0x1
Send 0x0 bytes to the device
000018: Control Transfer (UP), 2016-08-25 19:07:41,5006528 +0,0001074. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe
000019: Class-Specific Request (DOWN), 2016-08-25 19:07:41,5007972 +0,0001444 (1. Device: STMicroelectronics Virtual COM Port (COM7))
Destination: Interface, Index 0
Reserved Bits: 0
Request: 0x21
Value: 0x0
Get 0x7 bytes from the device
000020: Control Transfer (UP), 2016-08-25 19:07:41,5009031 +0,0001059. (1. Device: STMicroelectronics Virtual COM Port (COM7)) Status: 0x00000000
Pipe Handle: Control Pipe