реклама на сайте
подробности

 
 
> Заводим USB STM32 на CMSIS
isx
сообщение Aug 4 2016, 16:33
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Приветствую форумчан!
Вот уже 4-й месяц (с перерывами конечно sm.gif ) бьюсь об USB, но он никак не хочет работать. Сейчас происходит следующее: После ресета и настройки EP0 получаю запрос от хоста GET_DESCRIPTOR, затем происходит прерывание по CTR_RX и я ухожу в ресет, а затем все повторяется еще три раза и ВУАЛЯ .... "Неопознанное устройство".
Делал в KEIL5, но сегодня портировал и в KEIL4 (думал в программе дело), но толку нет. Примет виртуального COM порта с microtechnic запускается и определяется нормально, но мне нужно без STM-овских библиотек завести (не люблю я их sm.gif ).
Может кто-нибудь подсказать, что я делаю не так?
P.S. Все переменные со словом test в названии служат исключительно для диагностики и не вносят изменений в процесс общения МК с хостом.
CODE
#include "stm32f30x.h"

//#define USB_MAX_PACKET0 ((uint8_t) 0x40)
//#define USB_EP0_BIT ((uint32_t *)(0x420B8000))

uint32_t iTemp = 0;
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 testflag = 0x00000000;
uint32_t BTableOffset = 0x00000000; // указываем значение BTABLE
uint8_t i = 0;
uint16_t TXBuff = 0;
uint16_t RXBuff[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t TestBuff[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t TestBuffCountRX[20] = {99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
uint8_t TestBuffCountTX[20] = {99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
uint8_t CountTestBuffCountRX = 0;
uint8_t CountTestBuffCountTX = 0;
uint8_t CountTestBuff = 0;

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 базовый адрес регистров юсб



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;

}
}

((uint16_t*)0x40005C00)[EPNum]=buff;

}


const uint8_t Virtual_Com_Port_DeviceDescriptor[] = // second
{
0x12, // длина дескриптора в байтах;
0x01, // тип дескриптора: 1-Device descriptor
0x00, // 2 байта - версия USB: 2.0
0x02, //
0x02, // класс устройства: 2-CDC class code
0x00, // подкласс: 0-CDC class sub code
0x00, // протокол: 0-CDC Device protocol
0x40, // максимальный размер пакета для "нулевой конечной точки"
0xEB, // 2 байта - код производителя VID
0x03, //
0x27, // 2 байта - код устройства PID
0x61, //
0x10, // 2 байта - версия (ревизия) устройства
0x01, //
0x01, // индекс строки с названием производителя
0x02, // индекс строки с названием устройства
0x03, // индекс строки с серийным номером устройства
0x01 // количество поддерживаемых конфигураций
};


void MyUSBinit(void)
{

/*------------------------------USB----------------------------------*/

//здесь нужно включать бит подтяжки резистора (но на моей плате STM32F3Discovery он припаян)


*(__IO uint16_t*)(0x40006100) = (uint16_t) (0x0000);

RCC->CFGR &= ~RCC_CFGR_USBPRE; // Настраиваем частоту USB (= частота ядра / 1.5)
RCC->APB1ENR |= RCC_APB1ENR_USBEN; // Включаем тактирование USB от шины APB1
USB_CNTR &= ~USB_CNTR_PDWN;

USB_CNTR |= USB_CNTR_FRES;
USB_CNTR &= ~USB_CNTR_FRES;
USB_ISTR = 0;
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
USB_CNTR |= USB_CNTR_RESETM | USB_CNTR_CTRM | 0; // | USB_CNTR_ERRM; //;

}

void USB_LP_CAN1_RX0_IRQHandler (void)
{


if (USB_ISTR & USB_ISTR_CTR) //
{

USB_ISTR &= ~USB_ISTR_CTR;

if ((USB_EP0R & USB_EP_CTR_TX) != 0) //
{
TestBuffCountTX[CountTestBuffCountTX] = *(__IO uint8_t*)(0x4000600C);
CountTestBuffCountTX++;
TestBuff[CountTestBuff] = 7;
CountTestBuff++;

test1 = USB_EP0R;
USB_EP0R &= ~USB_EP_CTR_TX; // сброс CTR_TX - бит 7
test2 = USB_EP0R;


SetRXTX(0, 3, 0); //to Valid RX
test5 = USB_EP0R;
test5 = USB_EP0R;

return;
}

/*
if ((USB->EP0R & USB_EP_SETUP) != 0) ///////////////////////// развить
{
TestBuff[CountTestBuff] = 5;
CountTestBuff++;


test4 = *(__IO uint32_t*)(0x40006101); ///////////////////////// 32
test4 = 0;
}

*/

if (USB_EP0R & USB_EP_CTR_RX)
{
TestBuffCountRX[CountTestBuffCountRX] = *(__IO uint8_t*)(0x40006105);
CountTestBuffCountRX++;
TestBuff[CountTestBuff] = 8;
CountTestBuff++;

test1 = USB_EP0R;
USB_EP0R &= ~USB_EP_CTR_RX; // сброс CTR_RX
test2 = USB_EP0R;


switch (*(__IO uint8_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;
}
i = 0;

*(__IO uint16_t*)(0x40006004) = (uint16_t) 18; // i = 0x0012

USB_EP0R |= USB_EP_CONTROL;

test3 = USB_EP0R;
SetRXTX(0, 3, 1); // to Valid TX
test5 = USB_EP0R;
test5 = USB_EP0R;
break;

default:
test4 = *(__IO uint16_t*)(0x40006101);
test4 = 0;
break;
}


return;
}

i = 0;
}



if (USB_ISTR & USB_ISTR_RESET)
{

TestBuff[CountTestBuff] = 9;
CountTestBuff++;

USB_ISTR &= ~USB_ISTR_RESET;
//USB_ISTR = 0;
USB_BTABLE = 0; // таблица начинается с 0x0000


*(__IO uint16_t*)(0x40006000) = (uint16_t) 0x0040; // начальный адрес USB_ADDR0_TX (такой адрес позволяет в
//дальнейшем добавить все 8 возможных контрольных точек, каждая имеет размер 1 байт)
*(__IO uint16_t*)(0x40006004) = (uint16_t) 0x0040; // размер исходящих данных - 64 байта USB_COUNT0TX
*(__IO uint16_t*)(0x40006008) = (uint16_t) 0x0080; // начальный адрес USB_ADDR0_RX
*(__IO uint16_t*)(0x4000600C) = (uint16_t) 0x8400; // 64 байта входящих данных USB_ USB_COUNT0RX_BL_SIZE



USB_EP0R |= USB_EP_CONTROL;
test3 = *(__IO uint16_t*)(0x40006100);
SetRXTX(0, 3, 0); // to Valid RX
SetRXTX(0, 2, 1); // to NAK TX
test4 = *(__IO uint16_t*)(0x40006100);

USB_DADDR |= USB_DADDR_EF;

return;
}

}


Настройка периферии и прочие мелочи (main)

CODE
#include <stm32f30x.h>
#include <MyUSBsetting.h>


void TIM1_BRK_TIM15_IRQHandler(void) //??????? ??????????? ?????????? ?? ??????? 6
{
TIM15->SR &= ~TIM_SR_UIF;
if ((GPIOE->ODR &= GPIO_ODR_8) == 0)
GPIOE->ODR |= GPIO_ODR_8;
else
GPIOE->ODR &= ~GPIO_ODR_8;
;}


int main()
{

/*Тактируем ядро*/
//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_PLLMULL; //Очистить PLLMULL
RCC->CFGR |= RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_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->APB2ENR |= RCC_APB2ENR_TIM15EN;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; // Включаем тактирование портов А и Е
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Включаем тактирование SYSCFG (хз что это, но так надо sm.gif )

/*------------------------------GPIO----------------------------------*/

/*Настраиваем Порт А*/
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12; // Скорость 50 МГц
GPIOA->MODER |= GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1; // Режим альтернативной функции (для USB)
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; // Указанные пины на выход


/*------------------------------EXTI----------------------------------*/

//EXTI->RTSR |= EXTI_RTSR_TR18; // внешнее прерывание №18 (USBWakeUp) по возрастающему фронту
//EXTI->IMR |= EXTI_IMR_MR18; // Включаем прерывание по пинам
//EXTI->EMR |= EXTI_EMR_MR18; // Включаем прерывание по событию (USBWakeUp - по обнаружению устройства)

/*------------------------------NVIC----------------------------------*/


NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 8);
//NVIC_EnableIRQ(USBWakeUp_IRQn); // Разрешаем глобально прерывание USBWakeUp

NVIC_EnableIRQ(TIM1_BRK_TIM15_IRQn);
NVIC_SetPriority(TIM1_BRK_TIM15_IRQn, 5);

/*-----------------------------TIM15---------------------------------*/

TIM15->PSC = 7200 - 1;
TIM15->ARR = 10000;
TIM15->DIER |= TIM_DIER_UIE;
TIM15->CR1 |= TIM_CR1_CEN;


MyUSBinit();
GPIOE->BSRR |= GPIO_BSRR_BS_8;
__enable_irq ();


while(1)
{

}


}

TIM15 срабатывает раз в секунду (мигание диода - 1 ГЦ), значит частота тактирования ядра правильная (72МГц).

Сообщение отредактировал IgorKossak - Aug 10 2016, 12:41
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- isx   Заводим USB STM32 на CMSIS   Aug 4 2016, 16:33


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 04:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01366 секунд с 7
ELECTRONIX ©2004-2016