...Передавать надо ровно столько данных, сколько просит хост, по крайней мере не длиннее.
да-да, я не так выразился. Хост в запросе говорит что максимальная длина пакета 0x40 байт, допустимо отправить не больше этого значения.
Цитата:
На любой косяк хост "обижается". Вы должны четко соблюдать протокол. Описание дескрипторов, их длина. Очередность передачи и т.д. Если хост требует что-то сделать, но не требуются данные. Вы должны помахать в ответ ZLP. Например пришла команда установить адрес. Вы отвечаете ZLP, как от безадресного устройства, затем дальше все должно работать по адресу. Отправили дескриптор хосту, если хост его съест , то он отправит zlp.
Ну да, это понятно что чуть что и хост пошлет кривое устройство куда подальше. Буду дальше искать косяк.
Есть соображения почему не попадаю в прерывание по отправке. Может быть дело в том, что хост отвечает NAK или STALL. Тогда флаг CTR_TX не выставляется и прерывание не срабатывает. Но вот как узнать чем ответил хост?
Вы в буфер его правильно положили? Учли что 2 и 3 байты недоступны в 32 ом слове?
Да, там все верно. Смотрел в Memory watch - 2 и 3 байт 32-битного слова не используются. Сейчас под рукой нету функции, которая заполняет буферную память на основе исходного массива (в смысле не могу показать). Думаю может дескриптор не корректный. Хотя, вряд ли хост сразу сообразит, что дескриптор не корректный/
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Сообразит сообразит. Например, когда я ставил в дескрипторе устройства версию 2.0 и размер конфиг пакета отличный от 0x40, то хосту он не нравился. Но в любом случае если Вы отправили успешно данные, пускай даже с кривым дескриптором, флаг должен установится.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вот и я о том. Флаг выставляется только если попробовать передать 0 байт - COUNT_TX = 0. В случае COUNT_TX = 0x12 (18 байт) тишина. Грешил на то что ноги неверно настроил, но в моем F103 вроде не нужно особым образом настраивать ноги. При включении USB ноги конфигурируются автоматически.
Наше одну хрень при использование отладчика. Если попытаться посмотреть память в отладчике по адресу, то показывает всякую фигню, но если записать память в переменную, то в отладчике начинают отображаться нормальные значения. Может кому поможет .
Поправил код. Теперь проблема такая: не смотря на строчку USB->EP0R |= USB_EP_TX_NAK;, значение все равно сбрасывается в 0 (такая же фигня, если пытаться установить галочку в отладчике). Также не приходит прерывание по CTR. Пол дня уже голову ломаю, вроде все выставил как положено, но работать никак не хочет
//Переключиться на тактирование от PLL // RCC->CFGR |= RCC_CFGR_SW_1 ; //Выбрать источником тактового сигнала PLL
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {} //Ожидание переключения на PLL
/*Тактируем периферию*/ RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; // Включаем тактирование портов А и Е RCC->CFGR &= ~RCC_CFGR_USBPRE; // Настраиваем частоту USB (= частота ядра / 1.5) RCC->APB1ENR |= RCC_APB1ENR_USBEN; // Включаем тактирование USB от шины APB1 RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Включаем тактирование SYSCFG (хз что это, но так надо :) )
/*----------*/
/*Настраиваем Порт А*/ GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12; // Скорость 50 МГц GPIOA->MODER |= GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1; // Режим альтернативной функции (для USB) //GPIOA->OTYPER = 0x00000000; //GPIOA->PUPDR |= GPIO_PUPDR_PUPDR12_0; GPIOA->AFR[1] |= 0x000EE000; // Номер и пины альтернативной фунции (у нас пины 11 и 12 для альтернативной функции номер 14 - USB)
if (USB->ISTR & USB_ISTR_CTR) { USB->ISTR &= ~USB_ISTR_CTR; }
if (USB->ISTR & USB_ISTR_RESET) {
USB->ISTR &= ~USB_ISTR_RESET; // сбрасываем флаг прерывания по Reset
USB->BTABLE = BTableOffset; // таблица начинается с 0x0000
*(__IO uint32_t*)(0x40006000) = 0x0040; // начальный адрес USB_ADDR0_TX (такой адрес позволяет в дальнейшем добавить все 8 возможных контрольных точек, каждая имеет размер 1 байт) *(__IO uint32_t*)(0x40006004) = 0x0020; // размер исходящих данных - 32 байта USB_COUNT0TX *(__IO uint32_t*)(0x40006008) = 0x0060; // начальный адрес USB_ADDR0_RX *(__IO uint32_t*)(0x4000600C) = 0x8000; // 32 байта входящих данных USB_ USB_COUNT0RX_BL_SIZE
USB->EP0R |= USB_EP_CONTROL; // режим - CONTROL USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет USB->EP0R |= USB_EP_RX_VALID; // К приему готов
//test1 = *(__IO uint32_t*)(0x40006000);
USB->DADDR |= USB_DADDR_EF;
}
И еще вопрос, есть ли такие программы, которые позволяют мониторить данные с USB в таком состоянии (когда еще не произошла передача дескрипторов)? Может отладка в кейле сбивает работу USB?
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:1 Медали: 1
isx писал(а):
И еще вопрос, есть ли такие программы, которые позволяют мониторить данные с USB в таком состоянии (когда еще не произошла передача дескрипторов)? Может отладка в кейле сбивает работу USB?
Если я правильно понимаю, то для этого еще ставится промежуточная штуковина между хостом и девайсом, которая слушает шину. В отладкеу у меня ничего не сбивалось, правда у меня Кокос. Я на точках останова выдергивал шнур из USB, чтобы не успел пройти резет.
isx писал(а):
USB->ISTR &= ~USB_ISTR_CTR;
Bit 15CTR: Correct transfer This bit is set by the hardware to indicate that an endpoint has successfully completed a transaction; using DIR and EP_ID bits softwarecan determine which endpoint requested the interrupt. This bit is read-only.
Цитата:
USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет USB->EP0R |= USB_EP_RX_VALID; // К приему готов
Подумайте хорошенько что Вы тут сделали, выполните по шагам эти команды.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Это я знаю, просто нужно было добавить какую-нибудь строку, чтоб была возможность установить точку останова. Однако прерывание там ни разу не произошло .
Z_h_e писал(а):
USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет USB->EP0R |= USB_EP_RX_VALID; // К приему готов
Убрал USB->EP0R |= USB_EP_TX_NAK;. Ситуация не изменилась ( .
Насколько я понял - при резете сбрасываются регистры USB и контрольных точек. Поэтому их и настраивают заново при резете. Отладчик обычно не очень шустро работает. И Хост успевает послать резет, запросить дескриптор, подождать ответа, опять послать резет, опять дескриптор и т.д. Как результат установлнные значения успевают сброситься. И наверное при отладке это и происходит.
Странно, я по крайней мере получал прерывание по резету, в нем настраивался и выходил из прерывания. Далее получал прерывание по приему, точнее запрос типа SETUP и смотрю второй принятый байт - там 0x06
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Если мне не изменяет память, то хост до трех раз пытается определить что к нему подключено, соответственно резетов должно быть три в Вашем случае и потом винда должна сказать что не удалось понять что к ней подключилось. Поставте счетчик чтоли для резетов. Если этих резетов нет на самом деле, то тут что то не так. Возможно у Вас ложный резет в момент подключения разъема. У меня так бывало. Винда то ругается на неопознанное устройство?
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Блин... Простите мне мою рукожопость . Забыл, что отключил пару дней назад пользовательский разъем от компа (портов не хватало).
Резет по прежнему один, однако теперь в памяти вырисовывается запрос дескриптора устройства (если не ошибаюсь). Как тогда мне отследить момент, чтобы вовремя отреагировать на запрос?
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Во первых правильно настройте EP0R. Для TX Nack должен быть, тогда хост вежливо подождет какое-то время. И вообще вопрос непонятен. По прерыванию, как еще то?
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Для TX Nack должен быть, тогда хост вежливо подождет какое-то время.
USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет USB->EP0R |= USB_EP_RX_VALID; // К приему готов А на какую ошибку тогда вы здесь указали?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 38
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения