Сб июн 04, 2016 20:17:46
Сб июн 04, 2016 20:27:58
Сб июн 04, 2016 20:31:50
Сб июн 04, 2016 20:46:01
Сб июн 04, 2016 20:51:08
Сб июн 04, 2016 21:02:55
Сб июн 04, 2016 21:33:01
isx писал(а):Ошибка была в предыдущем примере. Исправил, но смысл не поменялся....\
Пример с USB->EP0R = USB->EP0R | USB_EP_RX_VALID.
USB_EP_RX_VALID = 0х3000 = 0b0011000000000000. Так и получается значение VALID в RX
Вс июн 05, 2016 09:09:20
USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет
USB->EP0R |= USB_EP_RX_VALID; // К приему готов
Вс июн 05, 2016 09:40:39
Почитайте про запросы USB, я Вам тоже об этом писал. Вы задали банальный вопрос, говорящий о том что нет совсем представления как работает USB.isx писал(а): Для того, чтобы произошло прерывание пользовательский разъем USB нужно ПОДКЛЮЧАТЬ при ЗАПУЩЕННОЙ отладке.
Да, так.isx писал(а):Подскажите пожалуйста, как отправить пакет нулевой длины? Нужно USB_COUNT0TX выставить в ноль и USB_EP_TX в VALID. Тогда если хост просит ответить восьмью байтами то нужно USB_COUNT0TX сделать в 8 байт?
Сб июн 11, 2016 18:30:57
if (USB->ISTR & USB_ISTR_CTR)
{
USB->CNTR &= ~USB_EP_CTR_RX;
switch (*(__IO uint32_t*)(0x400060C1))
{
case 0x6:
for (i = 0; i < 17; i++)
{
*(__IO uint32_t*)(0x40006000 + i) = Virtual_Com_Port_DeviceDescriptor[i];
}
break;
}
}
Вс июн 12, 2016 05:54:27
//Функция заполнения буфера отправки
void Buffer_Fill_Tx (uint8_t NumEP, uint8_t *Desc,uint8_t Len){ //NumEP -номер точки, Desc - массив байтов для отрпавки. Len - длина массива
uint16_t *pCount, *pTXBuf;
uint8_t i;
pTXBuf=0x40006000+NumEP*0x10; //адрес начало буфера TX
pCount=0x40006004+NumEP*0x10; //адрес COUNTn_TX
pTXBuf=*pTXBuf*2+0x40006000;
*pCount=Len;//длина пакета
for (i=0;i<Len;i+=2) pTXBuf[i]=Desc[i]+(Desc[i+1]<<8); //заполним буфер данными
}
switch ((ConfigPacket.bmRequestType << 8 ) | (ConfigPacket.bRequest)) {
case 0x8006:{//ЗАПРОС ДЕСКРИПТОРА
//выбор типа дискриптора
switch(ConfigPacket.wValue) {
case 0x0100:{//Запрос дескриптора устройства
Buffer_Fill_Tx (0,Device_Descriptor,18); //заполнение буфера отправки
Set_Status_EPR(0,Valid,TX); // отправим дескриптор устройста,
break;}
case 0x0200:
...
...
...
Вс июн 12, 2016 17:34:27
pTXBuf[i]=Desc[i]+(Desc[i+1]<<8)
Вс июн 12, 2016 18:05:28
Пн июн 13, 2016 11:54:25
-Сначала инициализируется модуль USB. просто вкючаете, подкючаете генератор и т.д.
- По событию SE0 (воткнули девайс в комп) инициализируете нужные регистры, это событие кстати сбросит их в начальное состояние само.
-Затем устанавливаете в регистре EP0 VALID RX, т.е. МК готов принять данные для нулевой точки.
-Возникает прерывание об успешной транзакции. Расшифровываете и понимаете что что то получили.
- читаете что лежит в буфере приема, там будет запрос дескриптора устройства.
-ложите в буфер отправки дескриптор устройства и выставляете в регистре EP0 VALID TX и контроллер сам все отправит.
-после события об успешной отправки опять переводите МК в состояние в готов принять.
int main(void)
{
__enable_irq ();
//*****Настройка тактирования
//сброс системы тактирования
RCC_DeInit();
//Включаем HSE
RCC->CR |= RCC_CR_HSEON;
//Ждем готовности HSE
while((RCC->CR & RCC_CR_HSERDY) == 0) {}
//Предделитель AHB
RCC->CFGR |= RCC_CFGR_HPRE_0;
//Очистка регистра умножителя PLL
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
//источник PLL от внешнего кварца
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE;
//умножитель PLL x6
RCC->CFGR |= RCC_CFGR_PLLMULL6;
//Включаем PLL
RCC->CR |= RCC_CR_PLLON;
//Ждем готовности PLL
while((RCC->CR & RCC_CR_PLLRDY) == 0) {}
//очистка регистра SW
RCC->CFGR &= ~RCC_CFGR_SW;
//выбор источника тактирования PLL
RCC->CFGR |= RCC_CFGR_SW_1;
//Ожидание включения PLL
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {}
//*********************************************************
//Включим тактирование - порт A, B,C и альтернативного режима
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN|RCC_APB2ENR_AFIOEN;
// НОЖКА C9
GPIOC->CRH &= ~GPIO_CRH_CNF12_0 & ~GPIO_CRH_CNF12_1;
GPIOC->CRH |= GPIO_CRH_MODE12;
GPIOC->ODR |= GPIO_ODR_ODR12;
//делитель USB равен 1
RCC->CFGR |= RCC_CFGR_USBPRE;
//Разрешаем USB
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
//Очистка флагов USB
USB->ISTR = 0;
USB->CNTR = 0;
//Разрешаем прерывания
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
NVIC_SetPriority (USB_LP_CAN1_RX0_IRQn, 2);
NVIC_EnableIRQ(USBWakeUp_IRQn);
//настройка прерываний от перефирии
EXTI->RTSR |= EXTI_RTSR_TR18; // прерывание №18
EXTI->IMR |= EXTI_IMR_MR18; // прерывание по выводам
EXTI->EMR |= EXTI_EMR_MR18; // прерывание по WU
USB->CNTR &= ~USB_CNTR_PDWN; //подаем питание
USB->CNTR &= ~USB_CNTR_FRES; //Включаем тактирование
//Настройка прерываний
USB->CNTR |= USB_CNTR_CTRM;
USB->CNTR |= USB_CNTR_WKUPM;
USB->CNTR |= USB_CNTR_SUSPM;
USB->CNTR |= USB_CNTR_RESETM;
void USB_LP_IRQHandler(void)
{
//Ждем события
if ((USB->ISTR & USB_ISTR_SUSP))
{
//какой-то код
}
}
Пн июн 13, 2016 16:14:22
Пн июн 13, 2016 18:44:37
isx писал(а):А прерывание у вас точно правильно обозвано?
В моем файле с дефайнами (на stm32f1x) оно определено как USB_LP_CAN1_RX0_IRQn. Тогда и прерывание следовало бы обозвать как void USB_LP_CAN1_RX0_IRQnHandler(void)....
Пн июн 13, 2016 19:11:10
Это определит хаб, увидев что одна из линий данных "подтянулась" (воткнули разъем). Скажет об этом хосту, хост пошлет сброс. Это и есть момент подключения.Serg1987 писал(а):Далее теоретически следует определить момент присоединения девайса к шине хоста. Как это определить.?
Пн июн 13, 2016 19:42:18
switch (*(__IO uint32_t*)(0x400060C1))
{
case 0x6:
for (i = 0; i < 16; i+=2)
{
TXBuff = Virtual_Com_Port_DeviceDescriptor[i] + (Virtual_Com_Port_DeviceDescriptor[i+1] << 8);
*(__IO uint32_t*)(0x40006080 + i) = TXBuff;
}
USB->EP0R |= USB_EP_TX_VALID;
break;
}
Пн июн 13, 2016 19:57:08
USB->EP0R |= USB_EP_TX_VALID;
Пн июн 13, 2016 20:31:39
switch (*(__IO uint32_t*)(0x400060C1))
{
case 0x6:
for (i = 0; i < 18; i+=2)
{
TXBuff = Virtual_Com_Port_DeviceDescriptor[i] + (Virtual_Com_Port_DeviceDescriptor[i+1] << 8);
*(__IO uint16_t*)(0x40006080 + i*2) = TXBuff;
}
*(__IO uint32_t*)(0x40006004) = 0x0012;
USB->EP0R |= USB_EP_TX_VALID;
test1 = USB->EP0R |= USB_EP_TX_VALID;
USB->EP0R |= USB_EP_RX_VALID;
break;
}