Дабы не создавать новую тему спрошу здесь.
Пытаюсь запустить usb на своей самодельной плате. чип stm32f103cr8. плата минималистична контроллер пара выводов и usb кабель с внешней подтяжкой. Кварц не стандартный как для таких устройств ( такой кварц нужен для других целей на этой плате) 12Мгц. Использую пример из библиотеки ST JoistickMouse, тактирование изменил под свои требования, проблема в том что при подключении к компьютеру он пишет неопознанное устройство и все.
Если я правильно понимаю работу юсб, после подключения шлейфа хост должен послать команду сброса и после конфигурации эндпоинтов получить дескрипторы.
Путем всяких тестов выяснилось что программа не уходит на прерывание описанное в файле stm32f10x_it.c
Код: Выделить всё
void USB_LP_CAN1_RX0_IRQHandler(void)
{
USB_Istr();
}
из за этого не понятно где вообще искать причину неисправности.
ниже приведу мой код тактирования и инициализации usb.
main.c
Спойлер
Код: Выделить всё
int main(void)
{
Set_System();
USB_Interrupts_Config();
Set_USBClock();
USB_Init();
while (1)
{
if (bDeviceState == CONFIGURED)
{
if ((JoyState() != 0) && (PrevXferComplete))
{
Joystick_Send(JoyState());
}
}
}
}
hw_config.c
Спойлер
Код: Выделить всё
/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
* File Name : hw_config.c
* Author : MCD Application Team
* Version : V3.3.0
* Date : 21-March-2011
* Description : Hardware Configuration & Setup
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "hw_config.h"
#include "usb_lib.h"
#include "usb_desc.h"
#include "platform_config.h"
#include "usb_pwr.h"
#include "usb_lib.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#define JOY_DOWN 1
#define JOY_LEFT 2
#define JOY_RIGHT 3
#define JOY_UP 4
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ErrorStatus HSEStartUpStatus;
EXTI_InitTypeDef EXTI_InitStructure;
/* Extern variables ----------------------------------------------------------*/
extern __IO uint8_t PrevXferComplete;
/* Private function prototypes -----------------------------------------------*/
static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : Set_System
* Description : Configures Main system clocks & power.
* Input : None.
* Return : None.
*******************************************************************************/
void Set_System(void)
{
GPIO_InitTypeDef gpio; //sozdayom peremennuyu tipa gpio
GPIO_StructInit(&gpio); // sozdayom ukazatel na strukturu gpio
RCC_DeInit();
RCC->CFGR &=~((RCC_CFGR_PLLSRC|RCC_CFGR_PLLXTPRE|RCC_CFGR_PLLMULL)); // Ïðåäî÷èñòêà.
RCC->CR |= RCC_CR_HSEON; //Âêëþ÷àåì òàêòîâûé ãåíåðàòîð HSE
while(!(RCC_CR_HSIRDY)); //Æäåì åãî ñòàáèëèçàöèè
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR &= ~FLASH_ACR_LATENCY; // Ïðåäî÷èñòêà.
//FLASH->ACR |= FLASH_ACR_LATENCY_0; // Åñëè SystemCoreClock <= 24 ÌÃö, áåç ïðîïóñêîâ.
FLASH->ACR |= FLASH_ACR_LATENCY_1; // Åñëè 24< SystemCoreClock <= 48, ïðîïóñêàòü 1 òàêò.
//FLASH->ACR |= FLASH_ACR_LATENCY_2; // Åñëè 48< SystemCoreClock <= 72, ïðîïóñêàòü 2 òàêòà.
RCC->CFGR|=RCC_CFGR_PLLSRC_HSE; // Òàêòèðîâàòü PLL îò HSE (12 MHz).
RCC->CFGR|=RCC_CFGR_PLLMULL4; // Óìíîæàòü ÷àñòîòó íà 2 (12*4=48 MHz).
RCC->CR |= RCC_CR_PLLON; // Çàïóñòèòü PLL.
while ((RCC->CR & RCC_CR_PLLRDY)==0) {} // Îæèäàíèå ãîòîâíîñòè PLL.
RCC->CFGR &=~RCC_CFGR_SW; // Î÷èñòèòü áèòû SW0, SW1.
RCC->CFGR |= RCC_CFGR_SW_PLL; // Òàêòèðîâàíèå ñ âûõîäà PLL.
while ((RCC->CFGR&RCC_CFGR_SWS)!=0x08) {} // Îæèäàíèå ïåðåêëþ÷åíèÿ íà PLL.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //taktiruem porti gpio
gpio.GPIO_Mode = GPIO_Mode_Out_PP; //vistavlayen naprvlenie portov
gpio.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
gpio.GPIO_Speed=GPIO_Speed_2MHz;//GPIO_Speed_400KHz;
GPIO_Init(GPIOA, &gpio);
GPIO_WriteBit(GPIOA, GPIO_Pin_1|GPIO_Pin_0, Bit_RESET);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
gpio.GPIO_Mode = GPIO_Mode_Out_PP; //vistavlayen naprvlenie portov
gpio.GPIO_Pin = GPIO_Pin_5;
gpio.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &gpio);
GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET);
}
/*******************************************************************************
* Function Name : Set_USBClock
* Description : Configures USB Clock input (48MHz).
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Set_USBClock(void)
{
RCC->CFGR|=RCC_CFGR_USBPRE;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_USBEN, ENABLE) ;
}
/*******************************************************************************
* Function Name : GPIO_AINConfig
* Description : Configures all IOs as AIN to reduce the power consumption.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void GPIO_AINConfig(void)
{
}
/*******************************************************************************
* Function Name : Enter_LowPowerMode.
* Description : Power-off system clocks and power while entering suspend mode.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Enter_LowPowerMode(void)
{
/* Set the device state to suspend */
bDeviceState = SUSPENDED;
}
/*******************************************************************************
* Function Name : Leave_LowPowerMode.
* Description : Restores system clocks and power while exiting suspend mode.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Leave_LowPowerMode(void)
{
DEVICE_INFO *pInfo = &Device_Info;
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
{}
#ifdef STM32F10X_CL
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
#endif /* STM32F10X_CL */
/* Enable PLL1 */
RCC_PLLCmd(ENABLE);
/* Wait till PLL1 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
#ifdef STM32L1XX_MD
while (RCC_GetSYSCLKSource() != 0x0C)
#else
while (RCC_GetSYSCLKSource() != 0x08)
#endif /* STM32L1XX_MD */
{}
/* Set the device state to the correct state */
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
else
{
bDeviceState = ATTACHED;
}
}
/*******************************************************************************
* Function Name : USB_Interrupts_Config.
* Description : Configures the USB interrupts.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_Interrupts_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 2 bit for pre-emption priority, 2 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
#ifdef STM32F10X_CL
/* Enable the USB Interrupts */
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USB Wake-up interrupt */
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);
#elif defined(STM32L1XX_MD)
/* Enable the USB interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USB Wake-up interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_FS_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#else
/* Enable the USB interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USB Wake-up interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);
#endif /* STM32F10X_CL */
/* Enable the Key EXTI line Interrupt */
/* NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Init(&NVIC_InitStructure);
*/
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
}
/*******************************************************************************
* Function Name : USB_Cable_Config.
* Description : Software Connection/Disconnection of USB Cable.
* Input : NewState: new state.
* Output : None.
* Return : None
*******************************************************************************/
void USB_Cable_Config (FunctionalState NewState)
{
if (NewState != DISABLE)
{
GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
}
else
{
GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
}
}
/*******************************************************************************
* Function Name : JoyState.
* Description : Decodes the Joystick direction.
* Input : None.
* Output : None.
* Return value : The direction value.
*******************************************************************************/
uint8_t JoyState(void)
{
return JOY_DOWN;
}
/*******************************************************************************
* Function Name : Joystick_Send.
* Description : prepares buffer to be sent containing Joystick event infos.
* Input : Keys: keys received from terminal.
* Output : None.
* Return value : None.
*******************************************************************************/
void Joystick_Send(uint8_t Keys)
{
uint8_t Mouse_Buffer[4] = {0, 0, 0, 0};
int8_t X = 0, Y = 0;
switch (Keys)
{
case JOY_LEFT:
X -= CURSOR_STEP;
break;
case JOY_RIGHT:
X += CURSOR_STEP;
break;
case JOY_UP:
Y -= CURSOR_STEP;
break;
case JOY_DOWN:
Y += CURSOR_STEP;
break;
default:
return;
}
/* prepare buffer to send */
Mouse_Buffer[1] = X;
Mouse_Buffer[2] = Y;
/* Reset the control token to inform upper layer that a transfer is ongoing */
PrevXferComplete = 0;
/* Copy mouse position info in ENDP1 Tx Packet Memory Area*/
USB_SIL_Write(EP1_IN, Mouse_Buffer, 4);
#ifndef STM32F10X_CL
/* Enable endpoint for transmission */
SetEPTxValid(ENDP1);
#endif /* STM32F10X_CL */
}
/*******************************************************************************
* Function Name : Get_SerialNum.
* Description : Create the serial number string descriptor.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Get_SerialNum(void)
{
uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
#ifdef STM32L1XX_MD
Device_Serial0 = *(uint32_t*)(0x1FF80050);
Device_Serial1 = *(uint32_t*)(0x1FF80054);
Device_Serial2 = *(uint32_t*)(0x1FF80064);
#else
Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
#endif /* STM32L1XX_MD */
Device_Serial0 += Device_Serial2;
if (Device_Serial0 != 0)
{
IntToUnicode (Device_Serial0, &Joystick_StringSerial[2] , 8);
IntToUnicode (Device_Serial1, &Joystick_StringSerial[18], 4);
}
}
/*******************************************************************************
* Function Name : HexToChar.
* Description : Convert Hex 32Bits value into char.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len)
{
uint8_t idx = 0;
for( idx = 0 ; idx < len ; idx ++)
{
if( ((value >> 28)) < 0xA )
{
pbuf[ 2* idx] = (value >> 28) + '0';
}
else
{
pbuf[2* idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[ 2* idx + 1] = 0;
}
}
#ifdef STM32F10X_CL
/*******************************************************************************
* Function Name : USB_OTG_BSP_uDelay.
* Description : provide delay (usec).
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
RCC_ClocksTypeDef RCC_Clocks;
/* Configure HCLK clock as SysTick clock source */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(usec * (RCC_Clocks.HCLK_Frequency / 1000000));
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk ;
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
}
#endif
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Может я что то делаю не так? подскажите как правильно.