А на картинках-то так все красиво расписаноZ_h_e писал(а):Делаю вывод, Bit Banding это аппаратный |= и по факту нет доступа к конкретному биту
Спойлер

А на картинках-то так все красиво расписаноZ_h_e писал(а):Делаю вывод, Bit Banding это аппаратный |= и по факту нет доступа к конкретному биту

В целом то все верно, регистров с битами тогл врядли много, или даже только в USB. С Bit Banding не надо переживать за соблюдение атомарности. Быстродействие опять, Сишное |= будем скомпилированно как минимум в три команды, Bit Banding в одну.isx писал(а):А на картинках-то так все красиво расписано .
Думаете она у меня какая-то не правдиваяВашу функцию пока не пробовал - хотел докопаться до правды
Уууу... Так глубоко я еще не копаюZ_h_e писал(а):Скорее всего не в STM, а в ARM.
Не то что бы не правдивая, просто когда сам все собираешь запоминается лучшеZ_h_e писал(а):Думаете она у меня какая-то не правдивая ?
Код: Выделить всё
const uint16_t bit15 = 0x8000;
const uint16_t bit7 = 0x0080;
Так то с него бы и надо начинать, основа, это ж ядро проца, единое для всех, а вот перефирия это уже от марки контроллера. Но не буду врать, я много чего забыл уже сам. Сразу в голове не все откладывается, особенно когда работаешь с контроллером иногда.isx писал(а):Уууу... Так глубоко я еще не копаю .
Когда я начал изучать STM, начал с самого легкого, с USBisx писал(а):Я правильно понимаю, что bit15 и bit7 это:
Код:
const uint16_t bit15 = 0x8000;
const uint16_t bit7 = 0x0080;
Код: Выделить всё
#define bit7 ((uint32_t)0x00000080)
#define bit15 ((uint32_t)0x00008000)Это я понимаю. Врать не буду, начинал несколько раз читать про ядра, но не осилял такой поток информацииZ_h_e писал(а):Так то с него бы и надо начинать, основа, это ж ядро проца, единое для всех
Я к нему постепенно шел, да вот только не чувствую особого различия. Все с ним наизнанку выворачиваетсяZ_h_e писал(а):Когда я начал изучать STM, начал с самого легкого, с USB
Я тоже сам начинал, но потом в 5-ом кейле встретил готовые определения... Эх, жаль тогда мне никто не сказал, что STAT-дефайны оттуда можно только для чтения использовать. Сколько я из-за этого времени убилZ_h_e писал(а):Я собственно и для регистров USB сам сделал определения
Код: Выделить всё
#include "stm32f303xc.h"
//#define USB_MAX_PACKET0 ((uint8_t) 0x40)
#define USB_EP0_BIT ((uint32_t *)(0x420B8000))
uint32_t test1 = 0x00000000;
uint32_t test2 = 0x00000000;
uint32_t test3 = 0x00000000;
uint32_t test4 = 0x00000000;
uint32_t test5 = 0x00000000;
uint32_t test6 = 0x00000000;
uint16_t testMASK = 0x0000;
uint32_t BTableOffset = 0x00000000; // указываем значение BTABLE
uint8_t i = 0;
uint16_t TXBuff = 0;
void SetRXTX (uint8_t EPNum, uint8_t EPStatus, uint8_t RXTX)
{
/*
EPNum EPStatus RXTX
0 to 7 0 - Disable 0 - RX
1 - Stall 1 - TX
2 - NAK
3 - VALID
*/
uint32_t buff;
uint32_t stat;
buff=((uint32_t*)0x40005C00)[EPNum]; //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&=0x8FBF; break; //TX
case 2:
buff^=0x0020; buff&=0x8FBF; break; //TX
case 3:
buff^=0x0030; buff&=0x8FBF; break; //TX
}
break;
case 1: //STALL
switch (EPStatus)
{
case 0:
buff^=0x0010; buff&=0x8FBF; break; //TX
case 1:
break;
case 2:
buff^=0x0030; buff&=0x8FBF; break; //TX
case 3:
buff^=0x0020; buff&=0x8FBF; break; //TX
}
break;
case 2: //NAK
switch (EPStatus)
{
case 0:
buff^=0x0020; buff&=0x8FBF; break; //TX
case 1:
buff^=0x0030; buff&=0x8FBF; break; //TX
case 2:
break;
case 3:
buff^=0x0010; buff&=0x8FBF; break; //TX
}
break;
case 3: //VALID
switch (EPStatus)
{
case 0:
buff^=0x0030; buff&=0x8FBF; break; //TX
case 1:
buff^=0x0020; buff&=0x8FBF; break; //TX
case 2:
buff^=0x0010; buff&=0x8FBF; break; //TX
case 3:
break;
}
break;
default: break;
}
}
else //////////////////////////////////////// RXTX = 0 = RX
{
stat = (buff>>12) & 3;
switch (stat)
{
case 0: //DISABLE
switch (EPStatus)
{
case 0:
break;
case 1:
buff^=0x1000; buff&=0xBF8F; break; //RX
case 2:
buff^=0x2000; buff&=0xBF8F; break; //RX
case 3:
buff^=0x3000; buff&=0xBF8F; break; //RX
}
break;
case 1: //STALL
switch (EPStatus)
{
case 0:
buff^=0x1000; buff&=0xBF8F; break; //RX
case 1:
break;
case 2:
buff^=0x3000; buff&=0xBF8F; break; //RX
case 3:
buff^=0x2000; buff&=0xBF8F; break; //RX
}
break;
case 2: //NAK
switch (EPStatus)
{
case 0:
buff^=0x2000; buff&=0xBF8F; break; //RX
case 1:
buff^=0x3000; buff&=0xBF8F; break; //RX
case 2:
break;
case 3:
buff^=0x1000; buff&=0xBF8F; break; //RX
}
break;
case 3: //VALID
switch (EPStatus)
{
case 0:
buff^=0x3000; buff&=0xBF8F; break; //RX
case 1:
buff^=0x2000; buff&=0xBF8F; break; //RX
case 2:
buff^=0x1000; buff&=0xBF8F; break; //RX
case 3:
break;
}
break;
}
}
((uint32_t*)0x40005C00)[EPNum]=buff;
}
const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
0x12, // размер данного дескриптора
0x01, // тип данного дескриптора - device descriptor
0x00, 0x02, // 2 байта - версия usb 2.0
0x02, // класс устройства cdc
0x00, // подкласс
0x00, // протокол
0x40, // USB_MAX_PACKET0, // max размер пакета для нулевой конечной точки
0x83, 0x04, // 2 байта - VID
0x40, 0x57,// 2 байта - PID
0x00, 0x02,// 2 байта - версия (ревизия) устройства
0x01, // индекс строки с названием производителя
0x02, // индекс строки с названием устройства
0x03, // индекс строки с серийным номером устройства
0x01 // количество поддерживаемых конфигураций
};
void MyUSBinit(void)
{
uint32_t temp2;
/*Тактируем ядро*/
//RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
//RCC->CR &= ~RCC_CR_HSEON;
RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
RCC->CR |= RCC_CR_HSEON;
// FLASH->ACR |= FLASH_ACR_HLFCYA;
FLASH->ACR |= FLASH_ACR_LATENCY_1;
FLASH->ACR |= FLASH_ACR_PRFTBE;
while((FLASH->ACR & FLASH_ACR_PRFTBS)==0) {}
while((RCC->CR & RCC_CR_HSERDY)==0) {} //Ожидание готовности HSE
RCC->CFGR |= RCC_CFGR_PLLSRC; //Источником сигнала для PLL выбран HSE (внешний - кварц на 8 МГц)
RCC->CR &= ~RCC_CR_PLLON; //Отключить генератор PLL
RCC->CFGR &= ~RCC_CFGR_PLLMUL; //Очистить PLLMULL
RCC->CFGR |= RCC_CFGR_PLLMUL_0 | RCC_CFGR_PLLMUL_1 | RCC_CFGR_PLLMUL_2; //Коефициент умножения 9 (будет 72 МГЦ)
RCC->CFGR |= RCC_CFGR_PPRE1_2;
RCC->CR |= RCC_CR_PLLON; //Включить генератор PLL
while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL
//Переключиться на тактирование от 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)
/*Настраиваем Порт Е*/
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 |
GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12 | GPIO_OSPEEDER_OSPEEDR13 |
GPIO_OSPEEDER_OSPEEDR14 | GPIO_OSPEEDER_OSPEEDR15; // Скорость для указанных пинов 50 МГц
GPIOE->MODER |= GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0 |
GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 |
GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0; // Указанные пины на выход
//GPIOE->OTYPER = 0x00000000;
//GPIOE->PUPDR = 0x00000000;
//GPIOE->AFR[1] |= 0x00000000;
/*----------------------------------------------------------------*/
EXTI->RTSR |= EXTI_RTSR_TR18; // внешнее прерывание №18 (USBWakeUp) по возрастающему фронту
EXTI->IMR |= EXTI_IMR_MR18; // Включаем прерывание по пинам
//EXTI->EMR |= EXTI_EMR_MR18; // Включаем прерывание по событию (USBWakeUp - по обнаружению устройства)
/*----------------------------------------------------------------*/
//NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 8);
NVIC_EnableIRQ(USBWakeUp_IRQn); // Разрешаем глобально прерывание USBWakeUp
//NVIC_SetPriority(USBWakeUp_IRQn, 3); // Приоритет прерывания (не могу определится для USB)
/*----------------------------------------------------------------*/
//здесь нужно включаить вит подтяжки резистора (но на плате STM32F3Discovery он припаян)
//USB->CNTR = 0x3;
*(__IO uint32_t*)(0x40006100) = 0;
USB->CNTR &= ~USB_CNTR_PDWN;
for ( temp2=10000000; temp2 != 0; temp2--);
//
USB->CNTR &= ~USB_CNTR_FRES;
//USB->CNTR = 0;
USB->ISTR = 0;
USB->CNTR |= USB_CNTR_RESETM; // | USB_CNTR_ERRM; // | USB_CNTR_CTRM;
//
NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
}
void USB_LP_CAN_RX0_IRQHandler(void)
{
//uint8_t tmp = 0;
if (USB->ISTR & USB_ISTR_CTR)
{
//while ((USB->ISTR & USB_ISTR_CTR) != 0)
// {
USB->ISTR &= ~USB_ISTR_CTR;
//test1 = *(__IO uint32_t*)(0x400060C1);
//test1 = (*(__IO uint32_t*)(USB_EP0R));
if ((USB->EP0R & USB_EP_CTR_TX) != 0)
{
test1 = USB->EP0R;
USB_EP0_BIT[7] = 0; // сброс CTR_TX - бит 7
test2 = USB->EP0R;
// if (FlagAddress){USB_REGISTR->DADDR+=ConfigPacket.wValue;FlagAddress=0;} //назначаем полученный адрес
SetRXTX(0, 3, 1); //to Valid TX
}
if ((USB->EP0R & USB_EP_CTR_RX) != 0)
{
test1 = USB->EP0R;
USB_EP0_BIT[15] = 0; // сброс CTR_RX
test2 = USB->EP0R;
switch (*(__IO uint32_t*)(0x40006101))
{
case 0x06:
test6 = USB->EP0R;
for (i = 0; i < 18; i+=2) // i = 18
{
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; // i = 0x0012
test3 = USB->EP0R;
SetRXTX(0, 3, 1); // to Valid TX
test5 = USB->EP0R;
SetRXTX(0, 3, 0); // to Valid RX
test2 = USB->EP0R;
break;
}
}
i = 0;
//}
}
if (USB->ISTR & USB_ISTR_RESET)
{
USB->ISTR = 0;
USB->CNTR |= USB_CNTR_CTRM | USB_CNTR_RESETM; // | USB_CNTR_ESOFM | USB_CNTR_SOFM;
USB->BTABLE = BTableOffset; // таблица начинается с 0x0000
*(__IO uint32_t*)(0x40006000) = (uint16_t) 0x40; // начальный адрес USB_ADDR0_TX (такой адрес позволяет в дальнейшем добавить все 8 возможных контрольных точек, каждая имеет размер 1 байт)
*(__IO uint32_t*)(0x40006004) = (uint16_t) 0x40; // размер исходящих данных - 64 байта USB_COUNT0TX
*(__IO uint32_t*)(0x40006008) = (uint16_t) 0x80; // начальный адрес USB_ADDR0_RX
*(__IO uint32_t*)(0x4000600C) = (uint16_t) 0x8400; // 64 байта входящих данных USB_ USB_COUNT0RX_BL_SIZE
USB->EP0R |= USB_EP_CONTROL; // режим - CONTROL
USB->EP0R |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет
USB->EP0R |= USB_EP_RX_VALID; // К приему готов
test4 = *(__IO uint32_t*)(0x40006100);
USB->DADDR |= USB_DADDR_EF;
// test1 = *(__IO uint32_t*)(0x40005C00);
// *(__IO uint32_t*)(0x420B8004) = 1;
// test2 = *(__IO uint32_t*)(0x40005C00);
// test3 = *(__IO uint32_t*)(0x40005C00);
// test4 = *(__IO uint32_t*)(0x40005C00);
}
///////////////
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
/*------------------------------ descriptor----------------------------------*/
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// configuration descriptor
const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
/* ============== CONFIGURATION 1 =========== */
/* Configuration 1 descriptor */
0x09, // размер дескриптора конфигурации
0x02, // тип дескриптора - configuration
0x43, // 2 байта - полный размер дескриптора, включая др. дескрипторы
0x00, // (CwTotalLength 2 EP + Control)
0x02, // количество интерфейсов (2 интерфейса для CDC - data и config)
0x01, // номер данной конфигурации (SET_CONFIGURATION)
0x00, // индекс строки описывающий данную конфигурацию
0xC0, // битовое поле, характеризующее конфигурацию
/*
Распределение бит:
D7 – зарезервировано (установлено в 1);
D6 – признак наличия собственного источника питания;
D5 – признак разрешения сообщения хосту о выходе
устройства из режима «сна»;
D4...D0 – зарезервированы (сброшены в 0)
*/
0x00, // max потребляемый ток от шины (половина от реального (50 = 100мА))
/* Communication Class Interface Descriptor Requirement */
0x09, // длина дескриптора
0x04, // тип дескриптора - интерфейс
0x00, // номер данного интерфейса
0x00, // номер альтернативной установки для интерфейса
0x01, // количество точек для данной альтернативной установки в данном интерфейсе
0x02, // код класса(USB-IF)
0x02, // код подкласса(USB-IF)
0x00, // код протокола(USB-IF)
0x01, // индекс строки, описывающей данную альтернативную установку данного интерфейса
/* Header Functional Descriptor */
0x05, // bFunction Length
0x24, // bDescriptor type: CS_INTERFACE
0x00, // bDescriptor subtype: Header Func Desc
0x10, // bcdCDC:1.1
0x01,
/*Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: device handles call management */ //!!!!!!!!!!!!!!!!!!1
0x01, /* bDataInterface: CDC data IF ID */
/* ACM Functional Descriptor */
0x04, // bFunctionLength
0x24, // bDescriptor Type: CS_INTERFACE
0x02, // bDescriptor Subtype: ACM Func Desc
0x02, // bmCapabilities
/* Union Functional Descriptor */
0x05, // bFunctionLength
0x24, // bDescriptorType: CS_INTERFACE
0x06, // bDescriptor Subtype: Union Func Desc
0x00, // bMasterInterface: Communication Class Interface
0x01, // bSlaveInterface0: Data Class Interface
/* Endpoint 1 descriptor */
0x07, // размер дескриптора
0x05, // тип дескриптора - endpoint
0x81, // битовое поле адреса точки // IN
/*
D7 – направление передачи данных точкой (1 – IN, 0 – OUT);
D6...D4 – зарезервированы (сброшены в 0);
D3...D0 – адрес точки
*/
0x03, // битовое поле, характеризующее точку
/*
D7, D6 – зарезервированы (сброшены в 0);
D5, D4 – функция, выполняемая точкой:
00 – точка данных;
01 – точка обратной связи;
10 – точка данных с неявной обратной связью;
11 – зарезервировано
D3, D2 – тип синхронизации хоста и точки:
00 – без синхронизации;
01 – асинхронный;
10 – адаптивный;
11 – синхронный
D1, D0 – тип обмена данными:
00 – контрольный;
01 – изохронный;
10 – bulk;
11 – interrupt
*/
64, // 2 байта - битовое поле
// характеризующее размер пакета передаваемых данных
0x00, /*
D15…D13 – зарезервированы (сброшены в 0);
D12, D11 – количество дополнительных передач:
00 – нет дополнительных передач;
01 – 1 дополнительная передача (всего 2 передачи),
10 – 2 дополнительные передачи (всего 3 передачи);
11 – зарезервировано.
D10...D0 – размер пакета в байтах
*/
0xFF, // интервал готовности точки к обмену данными
/* Data Class Interface Descriptor Requirement */
0x09, // bLength
0x04, // bDescriptorType
0x01, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x0A, // bInterfaceClass
0x00, // bInterfaceSubclass
0x00, // bInterfaceProtocol
0x04, // iInterface
/* Endpoint 2 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x02, // bEndpointAddress, Endpoint 01 - OUT
0x02, // bmAttributes BULK
64, // wMaxPacketSize
0x00,
0x00, // bInterval
/* Endpoint 3 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x83, // bEndpointAddress, Endpoint 02 - IN
0x02, // bmAttributes BULK
64, // wMaxPacketSize
0x00,
0x00 // bInterval
};
/* USB String Descriptors */
const uint8_t Virtual_Com_Port_StringLangID[] =
{
0x04, // длина дескриптора
0x03, // тип дескриптора - string desc
0x09, // N байт индетификатор языка
0x04 /* LangID = 0x0409: U.S. English */
};
const uint8_t Virtual_Com_Port_StringVendor[] =
{
10, // длина дескриптра
0x03, // тип дескриптора - string desc
/* имя */
'T', 0,
'E', 0,
'S', 0,
'T', 0
};
const uint8_t Virtual_Com_Port_StringProduct[] =
{
10, // длина дескриптра
0x03, // тип дескриптора - string desc
/* имя */
'T', 0,
'E', 0,
'S', 0,
'T', 0
};
const uint8_t Virtual_Com_Port_StringSerial[] =
{
10, // длина дескриптра
0x03, // тип дескриптора - string desc
/* имя */
'T', 0,
'E', 0,
'S', 0,
'T', 0
};
Не значит ли это, что после принятия дескриптора устройства мне нужно как-то сказать хосту о том, что я его получил (типа - отправкой пакета нулевой длины)? Или это подтверждение выполняется на железном уровне самостоятельно?Хост отправляет токен Setup, говорящий функции, что следующий пакет будет пакет Setup. Поле адреса будет содержать адрес устройства, от которого главный компьютер просит дескриптор. Номер конечной точки должен быть 0, что указывает канал по умолчанию (default pipe). Затем хост отправит пакет DATA0. Он будет содержать 8 байт полезной нагрузки, которая будет являться запросом Device Descriptor Request. Функция USB подтверждает пакет setup, что он был прочитан корректно, без ошибок.
Однако, я где-то читал, что для STM32 делить control пакет не нужно. Где всё-таки правда?Хост отправляет токен IN, чем говорит устройству, что он может теперь отправить данные для этой конечной точки. Поскольку максимальный размер пакета 8 байт, мы должны для отправки разделить 12 байт дескриптора устройства на кусочки. Каждый кусочек должен быть размером по 8 байт, за исключением последней транзакции. Хост подтверждает каждый пакет, который мы посылаем ему.
По-моему это значит Вам пора отдохнуть и потом начать все заново. Как устройство может получить дескриптор устройства и зачем это знать хосту?isx писал(а):Не значит ли это, что после принятия дескриптора устройства мне нужно как-то сказать хосту о том, что я его получил
Все управляющие пакеты будут для нулевой точки. Т.е. выделять как-то отдельно обрабатывать управляющие пакеты нет смысла.isx писал(а):Однако, я где-то читал, что для STM32 делить control пакет не нужно. Где всё-таки правда?
Прошу прощения, имел ввиду запрос дескриптора устройства.Z_h_e писал(а):Как устройство может получить дескриптор устройства и зачем это знать хосту?
Не то, чтобы выделять. Просто, как я понял смысл этих строк - пока хост полностью не получит дескриптор устройства, он за раз принимает данные не более 8 байт.Z_h_e писал(а):Все управляющие пакеты будут для нулевой точки. Т.е. выделять как-то отдельно обрабатывать управляющие пакеты нет смысла.
Источник вроде нормальный - многие на форумах на него ссылаются (http://microsin.ru/content/view/1107/44/)Поскольку максимальный размер пакета 8 байт, мы должны для отправки разделить 12 байт дескриптора устройства на кусочки. Каждый кусочек должен быть размером по 8 байт, за исключением последней транзакции.
Я хочу просто запустить USBZ_h_e писал(а):Я так понимаю, Вы собрались сделать USB UART.
Вообще хочу виртуальный COM порт сделать для начала. Только вот пока не удается даже запрос на второй дескриптор получить, а может и скормить первый.Z_h_e писал(а):Какое у Вас решение?
Похоже нашел правдуisx писал(а):Не то, чтобы выделять. Просто, как я понял смысл этих строк - пока хост полностью не получит дескриптор устройства, он за раз принимает данные не более 8 байт.
The USB driver stack issues a request for the USB Device Descriptor (GET_DESCRIPTOR for Descriptor Type DEVICE), using the default USB address of 0, and a maximum packet size of 8 bytes for low-speed devices and 64 bytes for full and high-speed devices.
bmRequestType 0x80
bRequest 0x6
wValue 0x100
wIndex 0x0
wLength 0x40
Код: Выделить всё
TestBuff[CountTestBuff] = Х;
CountTestBuff++;
В итоге массив заполняется такими значениями:RESET = 9
SETUP = 5
CTR_RX = 8
CTR_TX = 7
а затем вылетает окошко в Windows "Неопознанное устройство"9,5,8,7, 9,5,8,7, 9,5,8,7, 9,5,8,7, 0.0.0......
Я SUTUP сегодня только поставил, чисто для проверки. В нем кроме заполнения массива нет ничего.Z_h_e писал(а):но наверняка флаги сетап и rx устанавливаются одновременно, а вы их поди как два разных события обрабатываете
В дескрипторах нет необходимости - у меня второй запрос все-равно не приходит, а дескриптор устройства я нашел в статье в интернете, потом сверил с другими форумами и с книгой Агурова. Там все сходится...Z_h_e писал(а):Дескрипторы не могу выложить физически, только их и не выкладывал, я на телефоне и долго компа не увижу .
Код: Выделить всё
void USB_Reset(void)
{
USB_REGISTR->BTABLE=0;//адрес таблицы дескрипторов таблицы в выделенной памяти
//Настройка буфера EP0
DiscrTable->ADR0TX=0x0040;
DiscrTable->COUNT0TX=0x0000; //макс 0x80
DiscrTable->ADR0RX=0x0100;
DiscrTable->COUNT0RX=0b1011000000000000; //размер буфера 0x80 (128)байт
//Регистры конечных точек 0
USB_REGISTR->EP0R=0x0| //номер точки
bit13|bit12| //STAT_RX - VALID
// bit8 |//какой то статус аут
bit5|//bit4| //STAT_TX - NAK
/*bit10|*/ bit9 ; /*00 BULK //10-9 тип точки. в данном случае Контрол
01 CONTROL
10 ISO
11 INTERRUPT*/
USB_REGISTR->DADDR=bit7;//EF:Enable function, Включение ЮСБ с нулевым адресом
FlagAddress=0; //устройство не пришла команда установки адреса
// FlagZLP=0;
}Э, а как это в SETUP ничего не происходит? Ясен пень "ресет и все шаги повторяются".isx писал(а):Сделал что-то типа лога срабатывающих прерываний.
.....
SETUP (просто так, в нем ничего не происходит)
.....
В итоге массив заполняется такими значениями:а затем вылетает окошко в Windows "Неопознанное устройство"9,5,8,7, 9,5,8,7, 9,5,8,7, 9,5,8,7, 0.0.0......
Почему-то после прерывания по CTR_TX я опять вылетаю в ресет и все шаги повторяются. Во входящем буфере при этом после первого ресета постоянно висит первый запрос дескриптора устройства.
Вот про это хотелось бы по точнее. Я как-то спрашивал на форуме про ZLP после приема запроса дескриптора, но мне сказали, что делать этого не нужноRadist_M писал(а):2.1 После этого Хост долбит контроллер запросами типа IN. Если мне не изменяет память - тут надо по-моему отправить пакет нулевой длинны, чтоб комп понял, что мы приняли пакет.