From 6ab94e0b318884bbcb95e2ea3835f951502e1d99 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 14 Oct 2020 12:47:28 +0200 Subject: Move firmware into subdirectory --- fw/hid-dials/Src/main.c | 465 +++++++++++++++++++++ fw/hid-dials/Src/stm32f0xx_hal_msp.c | 191 +++++++++ fw/hid-dials/Src/stm32f0xx_it.c | 176 ++++++++ fw/hid-dials/Src/system_stm32f0xx.c | 265 ++++++++++++ fw/hid-dials/Src/usb_device.c | 107 +++++ fw/hid-dials/Src/usbd_conf.c | 775 +++++++++++++++++++++++++++++++++++ fw/hid-dials/Src/usbd_desc.c | 365 +++++++++++++++++ fw/hid-dials/Src/usbd_hid.c | 599 +++++++++++++++++++++++++++ 8 files changed, 2943 insertions(+) create mode 100644 fw/hid-dials/Src/main.c create mode 100644 fw/hid-dials/Src/stm32f0xx_hal_msp.c create mode 100644 fw/hid-dials/Src/stm32f0xx_it.c create mode 100644 fw/hid-dials/Src/system_stm32f0xx.c create mode 100644 fw/hid-dials/Src/usb_device.c create mode 100644 fw/hid-dials/Src/usbd_conf.c create mode 100644 fw/hid-dials/Src/usbd_desc.c create mode 100644 fw/hid-dials/Src/usbd_hid.c (limited to 'fw/hid-dials/Src') diff --git a/fw/hid-dials/Src/main.c b/fw/hid-dials/Src/main.c new file mode 100644 index 0000000..4ccbca0 --- /dev/null +++ b/fw/hid-dials/Src/main.c @@ -0,0 +1,465 @@ + +#include + +#include "main.h" +#include "usb_device.h" +#include "usbd_hid.h" + +#define HID_MEDIA_REPORT 2 +#define HYSTERESIS 200 + +ADC_HandleTypeDef hadc; +DMA_HandleTypeDef hdma_adc; + +PCD_HandleTypeDef hpcd_USB_FS; + +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void key_matrix_select(int row); +static int key_matrix_query(int debounce_time); +static uint32_t poll_encoders(void); +static uint32_t poll_keys(void); + +enum keybits { + /* These match up with the record descriptor in usbd_hid.c */ + KEYBITS_NEXT = 0x01, + KEYBITS_PREV = 0x02, + KEYBITS_STOP = 0x04, + KEYBITS_PLAY_PAUSE = 0x08, + KEYBITS_MUTE = 0x10, + KEYBITS_VOL_UP = 0x20, + KEYBITS_VOL_DOWN = 0x40, +}; + +enum key_names { + KEY_2 = 0, + KEY_3 = 1, + KEY_1 = 2, + KEY_ENC = 3, + KEY_4 = 4 +}; + +enum keymap_rows { + KEYMAP_BOTTOM_LEFT_ENC = 0, + KEYMAP_TOP_RIGHT_ENC = 1, +}; + +enum key_matrix_params { + KEY_MATRIX_ROWS = 5, + KEY_MATRIX_COLS = 2, +}; + +void sendKeybits(uint8_t keybits); + +struct key_t +{ + uint8_t id; + uint8_t modifier; + uint8_t reserved; + uint8_t keycode[6]; +} key; + +uint16_t ADCreg[8]; +uint16_t ADCval[8]; +uint16_t ADClast[8]; + +/* FIXME debug remove */ +TIM_TypeDef *tim1 = TIM1; +TIM_TypeDef *tim3 = TIM3; + +int main(void) +{ + HAL_Init(); + + SystemClock_Config(); + + MX_GPIO_Init(); + MX_USB_HID_INIT(); + + __HAL_RCC_TIM1_CLK_ENABLE(); + __HAL_RCC_TIM3_CLK_ENABLE(); + + TIM1->SMCR = 3; // Encoder mode 3 + TIM1->CCER = 0; // rising edge polarity + TIM1->ARR = 0xFFFF; // count from 0-ARR or ARR-0 + TIM1->CCMR1 = 0x0101; // f_DTS/16, N=8, IC1->TI1, IC2->TI2 + TIM1->CNT = 0; // Initialize counter + TIM1->EGR = 1; // Generate an update event + TIM1->CR1 = 1; // Enable the counter + + TIM3->SMCR = 3; // Encoder mode 3 + TIM3->CCER = 0; // rising edge polarity + TIM3->ARR = 0xFFFF; // count from 0-ARR or ARR-0 + TIM3->CCMR1 = 0x0101; // f_DTS/16, N=8, IC1->TI1, IC2->TI2 + TIM3->CNT = 0; // Initialize counter + TIM3->EGR = 1; // Generate an update event + TIM3->CR1 = 1; // Enable the counter + + while (1) { + uint32_t keybits = poll_encoders(); + for (int i=0; i<10; i++) { + keybits |= poll_keys(); + HAL_Delay(1); + } + sendKeybits(keybits); + } +} + +static uint32_t poll_encoders() { + static bool tx_vol_reset = 0; + static uint16_t tim1_last = 0, tim3_last = 0; /* timers init to 0 */ + static int vol_delta = 0; + + uint16_t tim1_now = TIM1->CNT, tim3_now = TIM3->CNT; + int16_t tim1_delta = (int16_t)(tim1_now - tim1_last); + int16_t tim3_delta = (int16_t)(tim3_now - tim3_last); + + /* Gang both encoders */ + vol_delta += tim3_delta - tim1_delta; + +#define VOL_DELTA_INC 4 + uint8_t keybits = 0; + if (!tx_vol_reset) { + /* Customize encoder action here */ + if (vol_delta >= VOL_DELTA_INC) { + keybits |= KEYBITS_VOL_UP; + vol_delta -= VOL_DELTA_INC; + tx_vol_reset = 1; + } else if (vol_delta <= -VOL_DELTA_INC) { + keybits |= KEYBITS_VOL_DOWN; + vol_delta += VOL_DELTA_INC; + tx_vol_reset = 1; + } + } else { + tx_vol_reset = 0; + } + + tim1_last = tim1_now; + tim3_last = tim3_now; + return keybits; +} + +static uint32_t poll_keys() { + int debounce_time = 5; /* 5 * 10 ms loop timing increments */ + uint32_t val = key_matrix_query(debounce_time); + uint32_t state = val&0xffff, edges = val>>16; + uint32_t pressed = state & edges; + (void)edges; /* unused */ + uint32_t keybits = 0; + + if (pressed & (1 << KEY_3)) + keybits |= KEYBITS_PLAY_PAUSE; + if (pressed & (1 << KEY_3 << KEY_MATRIX_ROWS)) + keybits |= KEYBITS_PREV; + if (pressed & (1 << KEY_4 << KEY_MATRIX_ROWS)) + keybits |= KEYBITS_NEXT; + if (pressed & (1 << KEY_ENC << KEY_MATRIX_ROWS)) + keybits |= KEYBITS_MUTE; + + return keybits; +} + +const uint8_t _asciimap[128] = +{ + 0x00, // NUL + 0x00, // SOH + 0x00, // STX + 0x00, // ETX + 0x00, // EOT + 0x00, // ENQ + 0x00, // ACK + 0x00, // BEL + 0x2a, // BS Backspace + 0x2b, // TAB Tab + 0x28, // LF Enter + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI + 0x00, // DEL + 0x00, // DC1 + 0x00, // DC2 + 0x00, // DC3 + 0x00, // DC4 + 0x00, // NAK + 0x00, // SYN + 0x00, // ETB + 0x00, // CAN + 0x00, // EM + 0x00, // SUB + 0x00, // ESC + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US + + 0x2c, // ' ' + 0x1e|0x80, // ! + 0x34|0x80, // " + 0x20|0x80, // # + 0x21|0x80, // $ + 0x22|0x80, // % + 0x24|0x80, // & + 0x34, // ' + 0x26|0x80, // ( + 0x27|0x80, // ) + 0x25|0x80, // * + 0x2e|0x80, // + + 0x36, // , + 0x2d, // - + 0x37, // . + 0x38, // / + 0x27, // 0 + 0x1e, // 1 + 0x1f, // 2 + 0x20, // 3 + 0x21, // 4 + 0x22, // 5 + 0x23, // 6 + 0x24, // 7 + 0x25, // 8 + 0x26, // 9 + 0x33|0x80, // : + 0x33, // ; + 0x36|0x80, // < + 0x2e, // = + 0x37|0x80, // > + 0x38|0x80, // ? + 0x1f|0x80, // @ + 0x04|0x80, // A + 0x05|0x80, // B + 0x06|0x80, // C + 0x07|0x80, // D + 0x08|0x80, // E + 0x09|0x80, // F + 0x0a|0x80, // G + 0x0b|0x80, // H + 0x0c|0x80, // I + 0x0d|0x80, // J + 0x0e|0x80, // K + 0x0f|0x80, // L + 0x10|0x80, // M + 0x11|0x80, // N + 0x12|0x80, // O + 0x13|0x80, // P + 0x14|0x80, // Q + 0x15|0x80, // R + 0x16|0x80, // S + 0x17|0x80, // T + 0x18|0x80, // U + 0x19|0x80, // V + 0x1a|0x80, // W + 0x1b|0x80, // X + 0x1c|0x80, // Y + 0x1d|0x80, // Z + 0x2f, // [ + 0x31, // bslash + 0x30, // ] + 0x23|0x80, // ^ + 0x2d|0x80, // _ + 0x35, // ` + 0x04, // a + 0x05, // b + 0x06, // c + 0x07, // d + 0x08, // e + 0x09, // f + 0x0a, // g + 0x0b, // h + 0x0c, // i + 0x0d, // j + 0x0e, // k + 0x0f, // l + 0x10, // m + 0x11, // n + 0x12, // o + 0x13, // p + 0x14, // q + 0x15, // r + 0x16, // s + 0x17, // t + 0x18, // u + 0x19, // v + 0x1a, // w + 0x1b, // x + 0x1c, // y + 0x1d, // z + 0x2f|0x80, // { + 0x31|0x80, // | + 0x30|0x80, // } + 0x35|0x80, // ~ + 0 // DEL +}; + + +void sendChar(uint8_t ch){ + if( ch > 128 ) ch -=128; + + key.id = 1; + key.keycode[0]=_asciimap[ch]&0x7F; + key.keycode[1]=0; + + if ( _asciimap[ch] & 0x80) key.modifier |= 0x02; + + for(int i=0; i< 4;i++){ + USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key)); + HAL_Delay(10); + } + memset(key.keycode, 0 , sizeof(key.keycode)); + key.modifier = 0; + USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key)); + HAL_Delay(10); +} + +void sendCharWrong(uint8_t ch){ + key.id = 1; + key.keycode[0]=ch&0x7F; + key.keycode[1]=0; + + if ( _asciimap[ch] & 0x80) key.modifier |= 0x02; + + for(int i=0; i< 4;i++){ + USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key)); + HAL_Delay(10); + } + memset(key.keycode, 0 , sizeof(key.keycode)); + key.modifier = 0; + USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key, sizeof(key)); + HAL_Delay(10); +} + +void sendKeybits(uint8_t keybits){ + uint8_t report[2]; + report[0]= HID_MEDIA_REPORT; + report[1]= keybits; + USBD_HID_SendReport(&hUsbDeviceFS, report, 2); +} + +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSI14State = RCC_HSI14_ON; + RCC_OscInitStruct.HSI14CalibrationValue = 16; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + +} + +static void MX_GPIO_Init(void) { + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + + /* Left encoder (SW2) A/B inputs: PA9/PA8 (TIM1 CH1/2) + * Right encoder (SW7) A/B inputs: PB4/PB5 (TIM3 CH1/2) + * Key matrix: PB2 -> encoder switches left/right + * PB8 -> SW3/8 + * PB1 -> SW4/9 + * PA15 -> SW5/10 + * PA0 -> SW6/11 + * key matrix inputs: PA1/PA4 + * + * Physical key layout: + * + * +------------|USB|------------+ + * | SW9 SW11 SW10 SW8 | + * | SW2 SW7 | + * | SW4 SW6 SW5 SW3 | + * +-----------------------------+ + * + * Logical key layout: + * + * +------------|USB|------------+ + * | KT1 KT2 KT3 KT4 | + * | EL ER | + * | KB1 KB2 KB3 KB4 | + * +-----------------------------+ + * + */ + GPIOA->MODER = 0x28000000 | (2<<(8*2)) | (2<<(9*2)) | (1<<(15*2))| (1<<(0*2)); + GPIOB->MODER = (2<<(4*2)) | (2<<(5*2)) | (1<<(1*2)) | (1<<(2*2)) | (1<<(8*2)); + GPIOA->PUPDR = 0x24000000 | (1<<(8*2)) | (1<<(9*2)) | (2<<(1*2)) | (2<<(4*2)); + GPIOB->PUPDR = (1<<(4*2)) | (1<<(5*2)); + GPIOA->AFR[1]= 0x00000022; + GPIOB->AFR[0]= 0x00110000; +} + +static void key_matrix_select(int row) { + uint16_t bsrr_a = 0, bsrr_b = 0; + /* A0 -> A15 -> B1 -> B2 -> B8 */ + switch (row) { + case 0: bsrr_a = 1<<0; break; + case 1: bsrr_a = 1<<15; break; + case 2: bsrr_b = 1<<1; break; + case 3: bsrr_b = 1<<2; break; + case 4: bsrr_b = 1<<8; break; + } + uint16_t mask_a = (1<<15) | (1<<0), mask_b = (1<<1) | (1<<2) | (1<<8); + /* Reset all pins except for selected pin */ + GPIOA->BSRR = (mask_a<<16) ^ ((bsrr_a<<16) | bsrr_a) ; + GPIOB->BSRR = (mask_b<<16) ^ ((bsrr_b<<16) | bsrr_b) ; +} + +static int key_matrix_query(int debounce_time) { + static int debounce_states[KEY_MATRIX_COLS][KEY_MATRIX_ROWS] = {0}; + static int key_matrix_row = -1; + static uint32_t matrix_state = 0; + uint32_t matrix_state_edges = 0; + if (key_matrix_row < 0) { /* On first iteration just set outputs and return */ + key_matrix_row = 0; + key_matrix_select(0); + return 0; + } + + int input = GPIOA->IDR; + int pressed[KEY_MATRIX_COLS] = { input & (1<<4), input & (1<<1) }; + for (int i=0; i 0) { + /* debounce timer running */ + debounce_states[i][key_matrix_row]--; + } else { + uint32_t bit = 1 << key_matrix_row << (KEY_MATRIX_ROWS * i); + uint32_t old_matrix_state = matrix_state; + if (pressed[i]) + matrix_state |= bit; + else + matrix_state &= ~bit; + + uint32_t edge = old_matrix_state ^ matrix_state; + if (edge) + debounce_states[i][key_matrix_row] = debounce_time; + matrix_state_edges |= edge; + } + } + + key_matrix_row = (key_matrix_row+1) % KEY_MATRIX_ROWS; + key_matrix_select(key_matrix_row); + return (matrix_state_edges<<16) | matrix_state; +} + +void Error_Handler(void) +{ + while(1){ + HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,1); + HAL_Delay(100); + HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,0); + HAL_Delay(100); + } +} + diff --git a/fw/hid-dials/Src/stm32f0xx_hal_msp.c b/fw/hid-dials/Src/stm32f0xx_hal_msp.c new file mode 100644 index 0000000..8695580 --- /dev/null +++ b/fw/hid-dials/Src/stm32f0xx_hal_msp.c @@ -0,0 +1,191 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32f0xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_adc; + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief ADC MSP Initialization +* This function configures the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**ADC GPIO Configuration + PA0 ------> ADC_IN0 + PA1 ------> ADC_IN1 + PA2 ------> ADC_IN2 + PA3 ------> ADC_IN3 + PA4 ------> ADC_IN4 + PA5 ------> ADC_IN5 + PA6 ------> ADC_IN6 + PA7 ------> ADC_IN7 + PB0 ------> ADC_IN8 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* ADC1 DMA Init */ + /* ADC Init */ + hdma_adc.Instance = DMA1_Channel1; + hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_adc.Init.Mode = DMA_CIRCULAR; + hdma_adc.Init.Priority = DMA_PRIORITY_MEDIUM; + if (HAL_DMA_Init(&hdma_adc) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc); + + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } + +} + +/** +* @brief ADC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) +{ + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC GPIO Configuration + PA0 ------> ADC_IN0 + PA1 ------> ADC_IN1 + PA2 ------> ADC_IN2 + PA3 ------> ADC_IN3 + PA4 ------> ADC_IN4 + PA5 ------> ADC_IN5 + PA6 ------> ADC_IN6 + PA7 ------> ADC_IN7 + PB0 ------> ADC_IN8 + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0); + + /* ADC1 DMA DeInit */ + HAL_DMA_DeInit(hadc->DMA_Handle); + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/hid-dials/Src/stm32f0xx_it.c b/fw/hid-dials/Src/stm32f0xx_it.c new file mode 100644 index 0000000..3d94908 --- /dev/null +++ b/fw/hid-dials/Src/stm32f0xx_it.c @@ -0,0 +1,176 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern DMA_HandleTypeDef hdma_adc; +extern PCD_HandleTypeDef hpcd_USB_FS; + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M0 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVC_IRQn 0 */ + + /* USER CODE END SVC_IRQn 0 */ + /* USER CODE BEGIN SVC_IRQn 1 */ + + /* USER CODE END SVC_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F0xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f0xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles DMA1 channel 1 global interrupt. + */ +void DMA1_Channel1_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */ + + /* USER CODE END DMA1_Channel1_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_adc); + /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */ + + /* USER CODE END DMA1_Channel1_IRQn 1 */ +} + +/** +* @brief This function handles USB global Interrupt / USB wake-up interrupt through EXTI line 18. +*/ +void USB_IRQHandler(void) +{ + /* USER CODE BEGIN USB_IRQn 0 */ + + /* USER CODE END USB_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_FS); + /* USER CODE BEGIN USB_IRQn 1 */ + + /* USER CODE END USB_IRQn 1 */ +} + + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/hid-dials/Src/system_stm32f0xx.c b/fw/hid-dials/Src/system_stm32f0xx.c new file mode 100644 index 0000000..6a3202b --- /dev/null +++ b/fw/hid-dials/Src/system_stm32f0xx.c @@ -0,0 +1,265 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f0xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (8 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. This file configures the system clock as follows: + *============================================================================= + * Supported STM32F0xx device + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 8000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 8000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** @addtogroup STM32F0xx_System_Private_Includes + * @{ + */ + +#include "stm32f0xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI48_VALUE */ +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock there is no need to + call the 2 first functions listed above, since SystemCoreClock variable is + updated automatically. + */ +uint32_t SystemCoreClock = 8000000; + +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* NOTE :SystemInit(): This function is called at startup just after reset and + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, PLL Multiplier + and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + pllmull = ( pllmull >> 18) + 2; + predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; + + if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) + { + /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ + SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull; + } +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) + { + /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */ + SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull; + } +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */ + else + { +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \ + || defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \ + || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ + SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull; +#else + /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || + STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || + STM32F091xC || STM32F098xx || STM32F030xC */ + } + break; + default: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/fw/hid-dials/Src/usb_device.c b/fw/hid-dials/Src/usb_device.c new file mode 100644 index 0000000..dc6a44f --- /dev/null +++ b/fw/hid-dials/Src/usb_device.c @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file : usb_device.c + * @version : v2.0_Cube + * @brief : This file implements the USB Device + ****************************************************************************** + * This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * Copyright (c) 2018 STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "usb_device.h" +#include "usbd_core.h" +#include "usbd_desc.h" + +/* USER CODE BEGIN Includes */ +#include "usbd_hid.h" + +/* USER CODE END Includes */ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* USB Device Core handle declaration. */ +USBD_HandleTypeDef hUsbDeviceFS; + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* + * -- Insert your external function declaration here -- + */ +/* USER CODE BEGIN 1 */ + +void MX_USB_HID_INIT(void) +{ + USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS); + + USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID); + + USBD_Start(&hUsbDeviceFS); +} + +/* USER CODE END 1 */ + + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/hid-dials/Src/usbd_conf.c b/fw/hid-dials/Src/usbd_conf.c new file mode 100644 index 0000000..cb09894 --- /dev/null +++ b/fw/hid-dials/Src/usbd_conf.c @@ -0,0 +1,775 @@ +/** + ****************************************************************************** + * @file : usbd_conf.c + * @version : v2.0_Cube + * @brief : This file implements the board support package for the USB device library + ****************************************************************************** + * This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * Copyright (c) 2018 STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" +#include "stm32f0xx_hal.h" +#include "usbd_def.h" +#include "usbd_core.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +PCD_HandleTypeDef hpcd_USB_FS; +//void _Error_Handler(char * file, int line); + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* Private functions ---------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state); +//extern void SystemClock_Config(void); + +/******************************************************************************* + LL Driver Callbacks (PCD -> USB Device Library) +*******************************************************************************/ +/* MSP Init */ + +void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) +{ + if(pcdHandle->Instance==USB) + { + /* USER CODE BEGIN USB_MspInit 0 */ + + /* USER CODE END USB_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USB_CLK_ENABLE(); + + /* Peripheral interrupt init */ + HAL_NVIC_SetPriority(USB_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(USB_IRQn); + /* USER CODE BEGIN USB_MspInit 1 */ + + /* USER CODE END USB_MspInit 1 */ + } +} + +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) +{ + if(pcdHandle->Instance==USB) + { + /* USER CODE BEGIN USB_MspDeInit 0 */ + + /* USER CODE END USB_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_CLK_DISABLE(); + + /* Peripheral interrupt Deinit*/ + HAL_NVIC_DisableIRQ(USB_IRQn); + + /* USER CODE BEGIN USB_MspDeInit 1 */ + + /* USER CODE END USB_MspDeInit 1 */ + } +} + +/** + * @brief Setup stage callback + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); +} + +/** + * @brief Data Out stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); +} + +/** + * @brief Data In stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Reset callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_SpeedTypeDef speed = USBD_SPEED_FULL; + + /* Set USB current speed. */ + switch (hpcd->Init.speed) + { + case PCD_SPEED_FULL: + speed = USBD_SPEED_FULL; + break; + + default: + speed = USBD_SPEED_FULL; + break; + } + USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed); + + /* Reset Device. */ + USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Suspend callback. + * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + /* Inform USB library that core enters in suspend Mode. */ + USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData); + /* Enter in STOP mode. */ + /* USER CODE BEGIN 2 */ + if (hpcd->Init.low_power_enable) + { + /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ + SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); + } + /* USER CODE END 2 */ +} + +/** + * @brief Resume callback. + * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + /* USER CODE BEGIN 3 */ + + /* USER CODE END 3 */ + USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief ISOOUTIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** + * @brief ISOINIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** + * @brief Connect callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Disconnect callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/******************************************************************************* + LL Driver Interface (USB Device Library --> PCD) +*******************************************************************************/ + +/** + * @brief Initializes the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + /* Init USB Ip. */ + /* Link the driver to the stack. */ + hpcd_USB_FS.pData = pdev; + pdev->pData = &hpcd_USB_FS; + + hpcd_USB_FS.Instance = USB; + hpcd_USB_FS.Init.dev_endpoints = 8; + hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; + hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_64; + hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd_USB_FS.Init.low_power_enable = DISABLE; + hpcd_USB_FS.Init.lpm_enable = DISABLE; + hpcd_USB_FS.Init.battery_charging_enable = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) + { + //_Error_Handler(__FILE__, __LINE__); + } + + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0); + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110); + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100); + return USBD_OK; +} + +/** + * @brief De-Initializes the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_DeInit(pdev->pData); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Starts the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_Start(pdev->pData); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Stops the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_Stop(pdev->pData); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Opens an endpoint of the low level driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param ep_type: Endpoint type + * @param ep_mps: Endpoint max packet size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Closes an endpoint of the low level driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Flushes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Sets a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Clears a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Returns Stall condition. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData; + + if((ep_addr & 0x80) == 0x80) + { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + } + else + { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + } +} + +/** + * @brief Assigns a USB address to the device. + * @param pdev: Device handle + * @param dev_addr: Device address + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Transmits data over an endpoint. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param pbuf: Pointer to data to be sent + * @param size: Data size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Prepares an endpoint for reception. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param pbuf: Pointer to data to be received + * @param size: Data size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + + switch (hal_status) { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} + +/** + * @brief Returns the last transfered packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval Recived Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr); +} + +/** + * @brief Delays routine for the USB device library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} + +/** + * @brief Static single allocation. + * @param size: Size of allocated memory + * @retval None + */ +//void *USBD_static_malloc(uint32_t size) +//{ +// static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */ +// return mem; +//} + +/** + * @brief Dummy memory free + * @param p: Pointer to allocated memory address + * @retval None + */ +void USBD_static_free(void *p) +{ + +} + +/* USER CODE BEGIN 5 */ +/** + * @brief Configures system clock after wake-up from USB Resume CallBack: + * enable HSI, PLL and select PLL as system clock source. + * @retval None + */ +//static void SystemClockConfig_Resume(void) +//{ +// SystemClock_Config(); +//} +/* USER CODE END 5 */ + +/** + * @brief Software device connection + * @param hpcd: PCD handle + * @param state: Connection state (0: disconnected / 1: connected) + * @retval None + */ +void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) +{ + /* USER CODE BEGIN 6 */ + if (state == 1) + { + /* Configure Low connection state. */ + + } + else + { + /* Configure High connection state */ + + } + /* USER CODE END 6 */ +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/hid-dials/Src/usbd_desc.c b/fw/hid-dials/Src/usbd_desc.c new file mode 100644 index 0000000..bdcaca4 --- /dev/null +++ b/fw/hid-dials/Src/usbd_desc.c @@ -0,0 +1,365 @@ +/** + ****************************************************************************** + * @file : usbd_desc.c + * @version : v2.0_Cube + * @brief : This file implements the USB device descriptors. + ****************************************************************************** + * This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * Copyright (c) 2018 STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @addtogroup USBD_DESC + * @{ + */ + +/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions + * @brief Private types. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_TYPES */ + +/* USER CODE END PRIVATE_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines + * @brief Private defines. + * @{ + */ + +/* + *************************************************[ATTENTION]************************************************ + * + * VID 0x1209 and PID 0x0001 is experimental IDs from http://pid.codes . + * You must get your own IDs, and change to your own IDs in order to avoid conflicting to other USB devices. + * + ************************************************************************************************************ +*/ + +#define USBD_VID 0x1209 +#define USBD_LANGID_STRING 1041 +#define USBD_MANUFACTURER_STRING "jaseg.de" +#define USBD_PID_FS 0x0002 // FIXME +#define USBD_PRODUCT_STRING_FS "MultiHID" +#define USBD_SERIALNUMBER_STRING_FS "000000000001" +#define USBD_CONFIGURATION_STRING_FS "HID Config" +#define USBD_INTERFACE_STRING_FS "HID Interface" + + + +/* USER CODE BEGIN PRIVATE_DEFINES */ + +/* USER CODE END PRIVATE_DEFINES */ + +/** + * @} + */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros + * @brief Private macros. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_MACRO */ + +/* USER CODE END PRIVATE_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes + * @brief Private functions declaration. + * @{ + */ + +uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); + +#ifdef USB_SUPPORT_USER_STRING_DESC +uint8_t * USBD_FS_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); +#endif /* USB_SUPPORT_USER_STRING_DESC */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables + * @brief Private variables. + * @{ + */ + +USBD_DescriptorsTypeDef FS_Desc = +{ + USBD_FS_DeviceDescriptor +, USBD_FS_LangIDStrDescriptor +, USBD_FS_ManufacturerStrDescriptor +, USBD_FS_ProductStrDescriptor +, USBD_FS_SerialStrDescriptor +, USBD_FS_ConfigStrDescriptor +, USBD_FS_InterfaceStrDescriptor +}; + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ +/** USB standard device descriptor. */ +__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = +{ + 0x12, /*bLength */ + USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ + 0x00, /*bcdUSB */ + 0x02, + 0x02, /*bDeviceClass*/ + 0x02, /*bDeviceSubClass*/ + 0x00, /*bDeviceProtocol*/ + USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ + LOBYTE(USBD_VID), /*idVendor*/ + HIBYTE(USBD_VID), /*idVendor*/ + LOBYTE(USBD_PID_FS), /*idProduct*/ + HIBYTE(USBD_PID_FS), /*idProduct*/ + 0x00, /*bcdDevice rel. 2.00*/ + 0x02, + USBD_IDX_MFC_STR, /*Index of manufacturer string*/ + USBD_IDX_PRODUCT_STR, /*Index of product string*/ + USBD_IDX_SERIAL_STR, /*Index of serial number string*/ + USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ +}; + +/* USB_DeviceDescriptor */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables + * @brief Private variables. + * @{ + */ + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ + +/** USB lang indentifier descriptor. */ +__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = +{ + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING) +}; + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ +/* Internal string descriptor. */ +__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions + * @brief Private functions. + * @{ + */ + +/** + * @brief Return the device descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + *length = sizeof(USBD_FS_DeviceDesc); + return USBD_FS_DeviceDesc; +} + +/** + * @brief Return the LangID string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + *length = sizeof(USBD_LangIDDesc); + return USBD_LangIDDesc; +} + +/** + * @brief Return the product string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Return the manufacturer string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** + * @brief Return the serial number string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Return the configuration string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Return the interface string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/hid-dials/Src/usbd_hid.c b/fw/hid-dials/Src/usbd_hid.c new file mode 100644 index 0000000..3704be4 --- /dev/null +++ b/fw/hid-dials/Src/usbd_hid.c @@ -0,0 +1,599 @@ +/** + ****************************************************************************** + * @file usbd_hid.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the HID core functions. + * + * @verbatim + * + * =================================================================== + * HID Class Description + * =================================================================== + * This module manages the HID class V1.11 following the "Device Class Definition + * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - The Mouse protocol + * - Usage Page : Generic Desktop + * - Usage : Joystick + * - Collection : Application + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2015 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_hid.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_HID + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_HID_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Macros + * @{ + */ +/** + * @} + */ + + + + +/** @defgroup USBD_HID_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + + +static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_HID = +{ + USBD_HID_Init, + USBD_HID_DeInit, + USBD_HID_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_HID_DataIn, /*DataIn*/ + USBD_HID_DataOut, /*DataOut*/ + NULL, /*SOF */ + NULL, + NULL, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetDeviceQualifierDesc, +}; + +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_HID_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x00, /*iConfiguration: Index of string descriptor describing + the configuration*/ + 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + + /* Interface descriptor */ + /* 09 */ + 0x09, /*bLength: Interface Descriptor size*/ + USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ + 0x00, /*bInterfaceNumber: Number of Interface*/ + 0x00, /*bAlternateSetting: Alternate setting*/ + HID_NUM_EP, + + 0x03, /*bInterfaceClass: HID*/ + + 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ + 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ + 0, /*iInterface: Index of string descriptor*/ + /* HID descriptor */ + /* 18 */ + 0x09, /*bLength: HID Descriptor size*/ + HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ + 0x11, /*bcdHID: HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, + /* HID endpoint descriptor */ + /* 27 */ + 0x07, /*bLength: Endpoint Descriptor size*/ + USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + + HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /*bmAttributes: Interrupt endpoint*/ + HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */ + 0x00, + HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/ + /* 34 */ +#if HID_LED_SUPPORT + 0x07, /*bLength: Endpoint Descriptor size*/ + USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + + HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /*bmAttributes: Interrupt endpoint*/ + HID_EPOUT_SIZE, /*wMaxPacketSize: 4 Byte max */ + 0x00, + HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/ +#endif + /* 41 */ + +} ; + +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = +{ + /* 18 */ + 0x09, /*bLength: HID Descriptor size*/ + HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ + 0x11, /*bcdHID: HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +__ALIGN_BEGIN static uint8_t HID_ReportDesc[HID_REPORT_DESC_SIZE] __ALIGN_END = +{ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x01, /* Report ID */ + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x95, 0x05, // REPORT_COUNT (5) + 0x75, 0x01, // REPORT_SIZE (1) + 0x05, 0x08, // USAGE_PAGE (LEDs) + 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + 0x29, 0x05, // USAGE_MAXIMUM (Kana) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x03, // REPORT_SIZE (3) + 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0, // End Collection +// + 0x05, 0x0C, /* Usage Page (Consumer Devices) */ + 0x09, 0x01, /* Usage (Consumer Control) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x85, 0x02, /* Report ID=2 */ + 0x05, 0x0C, /* Usage Page (Consumer Devices) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x07, /* Report Count (7) */ + 0x09, 0xB5, /* Usage (Scan Next Track) */ + 0x09, 0xB6, /* Usage (Scan Previous Track) */ + 0x09, 0xB7, /* Usage (Stop) */ + 0x09, 0xCD, /* Usage (Play / Pause) */ + 0x09, 0xE2, /* Usage (Mute) */ + 0x09, 0xE9, /* Usage (Volume Up) */ + 0x09, 0xEA, /* Usage (Volume Down) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x95, 0x01, /* Report Count (1) */ + 0x81, 0x01, /* Input (Constant) */ + 0xC0, // End Collection + + // how to format the 3 byte report + // byte 0 report ID = 0x02 (VOLUME_REPORT) + // byte 1 media code for ex VOL_UP 0xE9 , VOL_DONW 0xEA ... etc + // byte 2 0x00 + // a second report with 0 code shal be send to avoid "key repaeat" +}; + +uint32_t nOutData; +uint8_t OutDataBuffer[HID_EPOUT_SIZE]; // local copy for user (usb fly at same time) +uint8_t OutData[HID_EPOUT_SIZE]; // live usb buffer + +#ifdef DEBUG + +uint8_t OutDataLog[8*HID_EPOUT_SIZE]; +#endif +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Functions + * @{ + */ + +/** + * @brief USBD_HID_Init + * Initialize the HID interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + HID_EPIN_ADDR, + USBD_EP_TYPE_INTR, + HID_EPIN_SIZE); +#if HID_LED_SUPPORT + USBD_LL_OpenEP(pdev, + HID_EPOUT_ADDR, + USBD_EP_TYPE_INTR, + HID_EPOUT_SIZE); +#endif + + pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { +#if HID_LED_SUPPORT + USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, OutData, HID_EPOUT_SIZE); +#endif + ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + + } + return ret; +} + +/** + * @brief USBD_HID_Init + * DeInitialize the HID layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + /* Close HID EPs */ + USBD_LL_CloseEP(pdev, + HID_EPIN_ADDR); + + USBD_LL_CloseEP(pdev, + HID_EPOUT_ADDR); + + /* FRee allocated memory */ + if(pdev->pClassData != NULL) + { + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return USBD_OK; +} + +/** + * @brief USBD_HID_Setup + * Handle the HID specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + + + case HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case HID_REQ_GET_PROTOCOL: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->Protocol, + 1); + break; + + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->IdleState, + 1); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( req->wValue >> 8 == HID_REPORT_DESC) + { + len = MIN(HID_REPORT_DESC_SIZE , req->wLength); + pbuf = HID_ReportDesc; + } + else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_HID_Desc; + len = MIN(USB_HID_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->AltSetting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + hhid->AltSetting = (uint8_t)(req->wValue); + break; + } + } + return USBD_OK; +} + +/** + * @brief USBD_HID_SendReport + * Send HID Report + * @param pdev: device instance + * @param buff: pointer to report + * @retval status + */ +uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*)pdev->pClassData; + + if (pdev->dev_state == USBD_STATE_CONFIGURED ) + { + if(hhid->state == HID_IDLE) + { + hhid->state = HID_BUSY; + USBD_LL_Transmit (pdev, + HID_EPIN_ADDR, + report, + len); + } + } + return USBD_OK; +} + +/** + * @brief USBD_HID_GetPollingInterval + * return polling interval from endpoint descriptor + * @param pdev: device instance + * @retval polling interval + */ +uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev) +{ + uint32_t polling_interval = 0; + + /* HIGH-speed endpoints */ + if(pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Sets the data transfer polling interval for high speed transfers. + Values between 1..16 are allowed. Values correspond to interval + of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */ + polling_interval = (((1 <<(HID_HS_BINTERVAL - 1)))/8); + } + else /* LOW and FULL-speed endpoints */ + { + /* Sets the data transfer polling interval for low and full + speed transfers */ + polling_interval = HID_FS_BINTERVAL; + } + + return ((uint32_t)(polling_interval)); +} + +/** + * @brief USBD_HID_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + + +/** + * @brief USBD_HID_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + /* Ensure that the FIFO is empty before a new transfer, this condition could + be caused by a new transfer before the end of the previous transfer */ + ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + return USBD_OK; +} + + +__weak void USBD_HID_GetReport(uint8_t * OutData, int len){ + /** default do ntohing */ +} + +static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + int len; + +#ifdef DEBUG + memcpy(OutDataLog+((nOutData)%8)*8,OutData,8); +#endif + nOutData++; + // data cpy so we can be ready for next usb out and used received data safely + len = USBD_LL_GetRxDataSize (pdev, epnum); + memcpy(OutDataBuffer,OutData, len); + USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, OutData, HID_EPOUT_SIZE); + USBD_HID_GetReport(OutDataBuffer, len); + return USBD_OK; +} + + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- cgit