Problem with USBD_HID_GetReportTrigger() with USB-HID for STM32L4P5 under Keil RTX4

Dear readers,

 

I’m developing a SW project with KEIL µVision V5.35 and the STM32CubeMX (V6.4) tool. The target processor is the STM32L4P5VETx and everything goes well until I added a USB device to the project.

 

Detail informations version are :

Informations from “Manage Run-Time Environment” are :

  • CMSIS Core V5.6.0
  • CMSIS Keil RTX V2.82.0
  • CMSIS Driver USB Device (API) V2.3.0
  • ARM Compiler V1.7.2
  • USB MD-Plus V6.15.0

Informations from “Select with Select Software Packs” are :

  • ARM::CMSIS V5.9.0
  • ARM::CMSIS-Driver V2.7.1
  • Keil::ARM_Compiler V1.7.2
  • Keil::MDK-Middleware V7.13.0
  • Keil::STM32L4xx_DFP V2.6.1

 

I join main.c file as well as extra configuration files (see extra files).  

 

I try to send USB HID frame with 0x2 as modifier (byte 0) and a F1 key (bye N°2 0x3A) to generate a SHIFT-F1 key to a USB HOST target (PC).

If I analyze with (Free Device Monitoring Studio), I view that USB stack send 2 frames and a first frame beginning with a 0 bye value (see LOG_Free_Device_Monitoring_Studio.txt file for detail information) .

 

The normal USB frame is :

0x02 0x00 0x3A 0x00 0x00 0x00 0x00 0x00

Result USB frames are :

0x00 0x02 0x00 0x3A 0x00 0x00 0x00 0x00

0x00

 

 

Do you have a way to analyze why Keil USB stack (USB_Dbg_CM3.LIB) is wrong with USBD_HID_GetReportTrigger() function ?

Is there is other version work better ?

 

Thanks, by advance for the support.

Gabriel GRANGE

Associated files with advanced information :

LOG_Free_Device_Monitoring_Studio.txt

 

LOG_Free_Device_Monitoring_Studio.txt
000005: PnP Event: Device Connected (UP), 2022-06-21 14:55:42,1197503 +10,7110252 (1. Device: K-USB-Device)
The USB device has just been connected to the system.
000006: Get Descriptor Request (DOWN), 2022-06-21 14:55:42,1199180 +0,0001677 (1. Device: K-USB-Device)
Descriptor Type: Device
Descriptor Index: 0x0
Transfer Buffer Size: 0x12 bytes
000007: Control Transfer (UP), 2022-06-21 14:55:42,1203408 +0,0004228. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: Control Pipe
 12 01 10 01 00 00 00 08 51 C2 00 00 00 01 01 02   ........QÂ......
 03 01                                             ..
Setup Packet
 80 06 00 01 00 00 12 00                           €.......
Recipient: Device
Request Type: Standard
Direction: Device->Host
Request: 0x6 (GET_DESCRIPTOR)
Value: 0x100
Index: 0x0
Length: 0x12
000008: Get Descriptor Request (DOWN), 2022-06-21 14:55:42,1203462 +0,0000054 (1. Device: K-USB-Device)
Descriptor Type: Configuration
Descriptor Index: 0x0
Transfer Buffer Size: 0x9 bytes


000009: Control Transfer (UP), 2022-06-21 14:55:42,1206706 +0,0003244. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: Control Pipe
 09 02 29 00 01 01 00 80 FA                        ..)....€ú
Setup Packet
 80 06 00 02 00 00 09 00                           €.......
Recipient: Device
Request Type: Standard
Direction: Device->Host
Request: 0x6 (GET_DESCRIPTOR)
Value: 0x200
Index: 0x0
Length: 0x9

000010: Get Descriptor Request (DOWN), 2022-06-21 14:55:42,1206747 +0,0000041 (1. Device: K-USB-Device)
Descriptor Type: Configuration
Descriptor Index: 0x0
Transfer Buffer Size: 0x29 bytes


000011: Control Transfer (UP), 2022-06-21 14:55:42,1214423 +0,0007676. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: Control Pipe
 09 02 29 00 01 01 00 80 FA 09 04 00 00 02 03 00   ..)....€ú.......
 00 04 09 21 11 01 00 01 22 3F 00 07 05 81 03 04   ...!...."?.....
 00 10 07 05 01 03 04 00 10                        .........
Setup Packet
 80 06 00 02 00 00 29 00                           €.....).
Recipient: Device
Request Type: Standard
Direction: Device->Host
Request: 0x6 (GET_DESCRIPTOR)
Value: 0x200
Index: 0x0
Length: 0x29
000012: Select Configuration (DOWN), 2022-06-21 14:55:42,1214674 +0,0000251 (1. Device: K-USB-Device)
Configuration Index: 1

000013: Select Configuration (UP), 2022-06-21 14:55:42,1223805 +0,0000003. (1. Device: K-USB-Device) Status: 0x00000000
Configuration Index: 1
Configuration Handle: 0xe57f2b20
000014: Class-Specific Request (DOWN), 2022-06-21 14:55:42,1223848 +0,0000043 (1. Device: K-USB-Device)
Destination: Interface, Index 0
Reserved Bits: 34
Request: 0xa
Value: 0x0
Send 0x0 bytes to the device

000015: Control Transfer (UP), 2022-06-21 14:55:42,1225655 +0,0001807. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: Control Pipe
Setup Packet
 21 0A 00 00 00 00 00 00                           !.......
Recipient: Interface
Request Type: Class
Direction: Host->Device
Request: 0xa (Unknown)
Value: 0x0
Index: 0x0
Length: 0x0

000016: Get Descriptor Request (DOWN), 2022-06-21 14:55:42,1227308 +0,0001653 (1. Device: K-USB-Device)
Descriptor Type: HID Report Descriptor
Descriptor Index: 0x0
Transfer Buffer Size: 0x7f bytes


000017: Control Transfer (UP), 2022-06-21 14:55:42,1234892 +0,0007584. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: Control Pipe
 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01   ....¡....à)ç..%.
 75 01 95 08 81 02 95 01 75 08 81 01 95 03 75 01   u.•..•.u..•.u.
 05 08 19 01 29 03 91 02 95 01 75 05 91 01 95 06   ....).‘.•.u.‘.•.
 75 08 15 00 25 65 05 07 19 00 29 65 81 00 C0      u...%e....)e.À
Setup Packet
 81 06 00 22 00 00 7F 00                           .."...
Recipient: Interface
Request Type: Standard
Direction: Device->Host
Request: 0x6 (GET_DESCRIPTOR)
Value: 0x2200
Index: 0x0
Length: 0x7f
000020: PnP Event: Query ID (UP), 2022-06-21 14:55:42,1266351 +0,0007890 (1. Device: K-USB-Device)
Device ID: USB\VID_C251&PID_0000

000021: PnP Event: Query ID (UP), 2022-06-21 14:55:42,1272950 +0,0006599 (1. Device: K-USB-Device)
Hardware IDs: USB\VID_C251&PID_0000&REV_0100, USB\VID_C251&PID_0000

000022: Bulk or Interrupt Transfer (DOWN), 2022-06-21 14:55:42,1516730 +0,0243780 (1. Device: K-USB-Device)
Pipe Handle: 0xdc474c30 (Endpoint Address: 0x1)
Send 0x1 bytes to the device
 01                                                .

000024: Bulk or Interrupt Transfer (UP), 2022-06-21 14:55:48,5678974 +6,3999311. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: 0xf5d37970 (Endpoint Address: 0x81)
Get 0x8 bytes from the device
 00 02 00 3A 00 00 00 00                           ...:....

000026: Bulk or Interrupt Transfer (UP), 2022-06-21 14:55:48,5995305 +0,0316229. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: 0xf5d37970 (Endpoint Address: 0x81)
Get 0x1 bytes from the device
 00                                                .

000028: Bulk or Interrupt Transfer (UP), 2022-06-21 14:55:48,6799046 +0,0803713. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: 0xf5d37970 (Endpoint Address: 0x81)
Get 0x8 bytes from the device
 00 00 00 00 00 00 00 00                           ........

000030: Bulk or Interrupt Transfer (UP), 2022-06-21 14:55:48,7115202 +0,0315860. (1. Device: K-USB-Device) Status: 0x00000000
Pipe Handle: 0xf5d37970 (Endpoint Address: 0x81)
Get 0x1 bytes from the device
 00 

main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */
// System CPU definitions
#include "stm32l4xx_hal.h"              // Keil::Device:STM32Cube HAL:Common
#include "stm32l4xx_hal_conf.h"         // Keil::Device:STM32Cube HAL:Common
// Kernel definitions
#include "cmsis_os.h"                  // ARM::CMSIS:RTOS:Keil RTX
// System definitions
#include "rl_usb.h"
#include <string.h>
#include <stdio.h>

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
PCD_HandleTypeDef hpcd_USB_OTG_FS;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	volatile int ret;

	osKernelInitialize();               // Initialize RTOS Kernel for setup
  /* USER CODE END 1 */
	
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_OTG_FS_PCD_Init();
  /* USER CODE BEGIN 2 */



	// Test si l'interruption BDT est fonctionnelle
	HAL_Delay(3);	
	osKernelStart(); 
	osDelay(3);
	
	// Init de la couche USB de fourni par Keil 
	// La gestion IT et bas niveau du block USB du STM32F4P5 est supportée par Keil
	/*
	enum  	usbStatus {
  usbOK = 0U ,
  usbTimeout ,
  usbInvalidParameter ,
  usbThreadError = 0x10U ,
  usbTimerError ,
  usbSemaphoreError ,
  usbMutexError ,
  usbControllerError = 0x20U ,
  usbDeviceError ,
  usbDriverError ,
  usbDriverBusy ,
  usbMemoryError ,
  usbNotConfigured ,
  usbClassErrorADC ,
  usbClassErrorCDC ,
  usbClassErrorHID ,
  usbClassErrorMSC ,
  usbClassErrorCustom ,
  usbUnsupportedClass ,
  usbTransferStall = 0x40U ,
  usbTransferError ,
  usbUnknownError = 0xFFU
	}*/
	ret=USBD_Initialize(0);       // USB Device 0 Initialization
	ret=USBD_SetSerialNumber(0, "1234");  // USB Device 0 new Serial Number
	ret=USBD_Connect(0);          // USB Device 0 Connect    	

	// Do initializations and start Centralp application tasks 
	// Attention, cette temporisation doit etre respecter sous peine de faire 
	//            planter la pile USB Keil en cas de redémarrage suite à un WATCHDOG
	//						Le plantage est present avec un HOST sous Linux
	osDelay(2000);


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

{
uint8_t ucHidBuffer[8];
	
memset(ucHidBuffer, 0, sizeof(ucHidBuffer));
ucHidBuffer[0]=2;
ucHidBuffer[2]=0x3A;	
ret=USBD_Configured(0);
if( ret ){
ret=USBD_HID_GetReportTrigger(0U, 0U, (uint8_t *)ucHidBuffer, 8U );
osDelay(100U);                      // 100 ms delay
}

memset(ucHidBuffer, 0, sizeof(ucHidBuffer));
ret=USBD_HID_GetReportTrigger(0U, 0U, (uint8_t *)ucHidBuffer, 8U );
	
}
		osDelay(1000);

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 3;
  RCC_OscInitStruct.PLL.PLLN = 21;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USB_OTG_FS Initialization Function
  * @param None
  * @retval None
  */
static void MX_USB_OTG_FS_PCD_Init(void)
{

  /* USER CODE BEGIN USB_OTG_FS_Init 0 */

  /* USER CODE END USB_OTG_FS_Init 0 */

  /* USER CODE BEGIN USB_OTG_FS_Init 1 */

  /* USER CODE END USB_OTG_FS_Init 1 */
  hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
  hpcd_USB_OTG_FS.Init.dev_endpoints = 6;
  hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
  hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
  hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
  hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
  hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE;
  hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
  hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
  if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USB_OTG_FS_Init 2 */

  /* USER CODE END USB_OTG_FS_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM6 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM6) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

RTX_Conf_CM.c

/*----------------------------------------------------------------------------
 *      CMSIS-RTOS  -  RTX
 *----------------------------------------------------------------------------
 *      Name:    RTX_Conf_CM.C
 *      Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
 *      Rev.:    V4.70.1
 *----------------------------------------------------------------------------
 *
 * Copyright (c) 1999-2009 KEIL, 2009-2016 ARM Germany GmbH. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 *---------------------------------------------------------------------------*/
 
#include "cmsis_os.h"
 

/*----------------------------------------------------------------------------
 *      RTX User configuration part BEGIN
 *---------------------------------------------------------------------------*/
 
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
// <h>Thread Configuration
// =======================
//
//   <o>Number of concurrent running user threads <1-250>
//   <i> Defines max. number of user threads that will run at the same time.
//   <i> Default: 6
#ifndef OS_TASKCNT
 #define OS_TASKCNT     12
#endif
 
//   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
//   <i> Defines default stack size for threads with osThreadDef stacksz = 0
//   <i> Default: 200
#ifndef OS_STKSIZE
 #define OS_STKSIZE     256      // this stack size value is in words
#endif
 
//   <o>Main Thread stack size [bytes] <64-32768:8><#/4>
//   <i> Defines stack size for main thread.
//   <i> Default: 200
#ifndef OS_MAINSTKSIZE
 #define OS_MAINSTKSIZE 192      // this stack size value is in words
#endif
 
//   <o>Number of threads with user-provided stack size <0-250>
//   <i> Defines the number of threads with user-provided stack size.
//   <i> Default: 0
#ifndef OS_PRIVCNT
 #define OS_PRIVCNT     0
#endif
 
//   <o>Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4>
//   <i> Defines the combined stack size for threads with user-provided stack size.
//   <i> Default: 0
#ifndef OS_PRIVSTKSIZE
 #define OS_PRIVSTKSIZE 4096       // this stack size value is in words
#endif
 
//   <q>Stack overflow checking
//   <i> Enable stack overflow checks at thread switch.
//   <i> Enabling this option increases slightly the execution time of a thread switch.
#ifndef OS_STKCHECK
 #define OS_STKCHECK    1
#endif
 
//   <q>Stack usage watermark
//   <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
//   <i> Enabling this option increases significantly the execution time of osThreadCreate.
#ifndef OS_STKINIT
#define OS_STKINIT      1
#endif
 
//   <o>Processor mode for thread execution 
//     <0=> Unprivileged mode 
//     <1=> Privileged mode
//   <i> Default: Privileged mode
#ifndef OS_RUNPRIV
 #define OS_RUNPRIV     1
#endif
 
// </h>
 
// <h>RTX Kernel Timer Tick Configuration
// ======================================
//   <q> Use Cortex-M SysTick timer as RTX Kernel Timer
//   <i> Cortex-M processors provide in most cases a SysTick timer that can be used as 
//   <i> as time-base for RTX.
#ifndef OS_SYSTICK
 #define OS_SYSTICK     1
#endif
//
//   <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
//   <i> Defines the input frequency of the RTOS Kernel Timer.  
//   <i> When the Cortex-M SysTick timer is used, the input clock 
//   <i> is on most systems identical with the core clock.
#ifndef OS_CLOCK
 #define OS_CLOCK       84000000
#endif
 
//   <o>RTX Timer tick interval value [us] <1-1000000>
//   <i> The RTX Timer tick interval value is used to calculate timeout values.
//   <i> When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer.
//   <i> Default: 1000  (1ms)
#ifndef OS_TICK
 #define OS_TICK        1000
#endif
 
// </h>
 
// <h>System Configuration
// =======================
//
// <e>Round-Robin Thread switching
// ===============================
//
// <i> Enables Round-Robin Thread switching.
#ifndef OS_ROBIN
 #define OS_ROBIN       1
#endif
 
//   <o>Round-Robin Timeout [ticks] <1-1000>
//   <i> Defines how long a thread will execute before a thread switch.
//   <i> Default: 5
#ifndef OS_ROBINTOUT
 #define OS_ROBINTOUT   5
#endif
 
// </e>
 
// <e>User Timers
// ==============
//   <i> Enables user Timers
#ifndef OS_TIMERS
 #define OS_TIMERS      1
#endif
 
//   <o>Timer Thread Priority
//                        <1=> Low
//     <2=> Below Normal  <3=> Normal  <4=> Above Normal
//                        <5=> High
//                        <6=> Realtime (highest)
//   <i> Defines priority for Timer Thread
//   <i> Default: High
#ifndef OS_TIMERPRIO
 #define OS_TIMERPRIO   5
#endif
 
//   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
//   <i> Defines stack size for Timer thread.
//   <i> Default: 200
#ifndef OS_TIMERSTKSZ
 #define OS_TIMERSTKSZ  64     // this stack size value is in words
#endif
 
//   <o>Timer Callback Queue size <1-32>
//   <i> Number of concurrent active timer callback functions.
//   <i> Default: 4
#ifndef OS_TIMERCBQS
 #define OS_TIMERCBQS   32
#endif
 
// </e>
 
//   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
//                         <12=> 12 entries  <16=> 16 entries
//                         <24=> 24 entries  <32=> 32 entries
//                         <48=> 48 entries  <64=> 64 entries
//                         <96=> 96 entries
//   <i> ISR functions store requests to this buffer,
//   <i> when they are called from the interrupt handler.
//   <i> Default: 16 entries
#ifndef OS_FIFOSZ
 #define OS_FIFOSZ      16
#endif
 
// </h>
 
//------------- <<< end of configuration section >>> -----------------------
 
// Standard library system mutexes
// ===============================
//  Define max. number system mutexes that are used to protect 
//  the arm standard runtime library. For microlib they are not used.
#ifndef OS_MUTEXCNT
 #define OS_MUTEXCNT    8
#endif
 
/*----------------------------------------------------------------------------
 *      RTX User configuration part END
 *---------------------------------------------------------------------------*/
 
#define OS_TRV          ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
 

/*----------------------------------------------------------------------------
 *      Global Functions
 *---------------------------------------------------------------------------*/
 
/*--------------------------- os_idle_demon ---------------------------------*/

/// \brief The idle demon is running when no other thread is ready to run
void os_idle_demon (void) {
 
  for (;;) {
    /* HERE: include optional user code to be executed when no thread runs.*/
  }
}
 
#if (OS_SYSTICK == 0)   // Functions for alternative timer as RTX kernel timer
 
/*--------------------------- os_tick_init ----------------------------------*/
 
/// \brief Initializes an alternative hardware timer as RTX kernel timer
/// \return                             IRQ number of the alternative hardware timer
int os_tick_init (void) {
  return (-1);  /* Return IRQ number of timer (0..239) */
}
 
/*--------------------------- os_tick_val -----------------------------------*/
 
/// \brief Get alternative hardware timer's current value (0 .. OS_TRV)
/// \return                             Current value of the alternative hardware timer
uint32_t os_tick_val (void) {
  return (0);
}
 
/*--------------------------- os_tick_ovf -----------------------------------*/
 
/// \brief Get alternative hardware timer's  overflow flag
/// \return                             Overflow flag\n
///                                     - 1 : overflow
///                                     - 0 : no overflow
uint32_t os_tick_ovf (void) {
  return (0);
}
 
/*--------------------------- os_tick_irqack --------------------------------*/
 
/// \brief Acknowledge alternative hardware timer interrupt
void os_tick_irqack (void) {
  /* ... */
}
 
#endif   // (OS_SYSTICK == 0)
 
/*--------------------------- os_error --------------------------------------*/
 
/* OS Error Codes */
#define OS_ERROR_STACK_OVF      1
#define OS_ERROR_FIFO_OVF       2
#define OS_ERROR_MBX_OVF        3
#define OS_ERROR_TIMER_OVF      4
 
extern osThreadId svcThreadGetId (void);
 
/// \brief Called when a runtime error is detected
/// \param[in]   error_code   actual error code that has been detected
void os_error (uint32_t error_code) {
 
  /* HERE: include optional code to be executed on runtime error. */
  switch (error_code) {
    case OS_ERROR_STACK_OVF:
      /* Stack overflow detected for the currently running task. */
      /* Thread can be identified by calling svcThreadGetId().   */
      break;
    case OS_ERROR_FIFO_OVF:
      /* ISR FIFO Queue buffer overflow detected. */
      break;
    case OS_ERROR_MBX_OVF:
      /* Mailbox overflow detected. */
      break;
    case OS_ERROR_TIMER_OVF:
      /* User Timer Callback Queue overflow detected. */
      break;
    default:
      break;
  }
  for (;;);
}
 

/*----------------------------------------------------------------------------
 *      RTX Configuration Functions
 *---------------------------------------------------------------------------*/
 
#include "RTX_CM_lib.h"
 
/*----------------------------------------------------------------------------
 * end of file
 *---------------------------------------------------------------------------*/

STCubeGenerated.ioc

#MicroXplorer Configuration settings - do not modify
File.Version=6
GPIO.groupedBy=
KeepUserPlacement=false
Mcu.Family=STM32L4
Mcu.IP0=NVIC
Mcu.IP1=RCC
Mcu.IP2=SYS
Mcu.IP3=USB_OTG_FS
Mcu.IPNb=4
Mcu.Name=STM32L4P5V(G-E)Tx
Mcu.Package=LQFP100
Mcu.Pin0=PC14-OSC32_IN (PC14)
Mcu.Pin1=PC15-OSC32_OUT (PC15)
Mcu.Pin10=PB4 (NJTRST)
Mcu.Pin11=VP_SYS_VS_tim6
Mcu.Pin2=PH0-OSC_IN (PH0)
Mcu.Pin3=PH1-OSC_OUT (PH1)
Mcu.Pin4=PA11
Mcu.Pin5=PA12
Mcu.Pin6=PA13 (JTMS/SWDIO)
Mcu.Pin7=PA14 (JTCK/SWCLK)
Mcu.Pin8=PA15 (JTDI)
Mcu.Pin9=PB3 (JTDO/TRACESWO)
Mcu.PinsNb=12
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32L4P5VETx
MxCube.Version=6.4.0
MxDb.Version=DB.6.0.40
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:false\:true
NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:true
NVIC.TimeBase=TIM6_DAC_IRQn
NVIC.TimeBaseIP=TIM6
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PA11.Mode=Device_Only
PA11.Signal=USB_OTG_FS_DM
PA12.Mode=Device_Only
PA12.Signal=USB_OTG_FS_DP
PA13\ (JTMS/SWDIO).Mode=JTAG_5_pins
PA13\ (JTMS/SWDIO).Signal=SYS_JTMS-SWDIO
PA14\ (JTCK/SWCLK).Mode=JTAG_5_pins
PA14\ (JTCK/SWCLK).Signal=SYS_JTCK-SWCLK
PA15\ (JTDI).Mode=JTAG_5_pins
PA15\ (JTDI).Signal=SYS_JTDI
PB3\ (JTDO/TRACESWO).Mode=JTAG_5_pins
PB3\ (JTDO/TRACESWO).Signal=SYS_JTDO-SWO
PB4\ (NJTRST).Mode=JTAG_5_pins
PB4\ (NJTRST).Signal=SYS_JTRST
PC14-OSC32_IN\ (PC14).Mode=LSE-External-Oscillator
PC14-OSC32_IN\ (PC14).Signal=RCC_OSC32_IN
PC15-OSC32_OUT\ (PC15).Mode=LSE-External-Oscillator
PC15-OSC32_OUT\ (PC15).Signal=RCC_OSC32_OUT
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32L4P5VETx
ProjectManager.FirmwarePackage=STM32Cube FW_L4 V1.17.2
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=STCubeGenerated.ioc
ProjectManager.ProjectName=STCubeGenerated
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=MDK-ARM V5
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true
RCC.ADCFreq_Value=48000000
RCC.AHBFreq_Value=84000000
RCC.APB1Freq_Value=84000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=84000000
RCC.CRSFreq_Value=48000000
RCC.CortexFreq_Value=84000000
RCC.DFSDMFreq_Value=84000000
RCC.FCLKCortexFreq_Value=84000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=84000000
RCC.HSE_VALUE=24000000
RCC.HSI48_VALUE=48000000
RCC.HSI_VALUE=16000000
RCC.I2C1Freq_Value=84000000
RCC.I2C2Freq_Value=84000000
RCC.I2C3Freq_Value=84000000
RCC.I2C4Freq_Value=84000000
RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,DFSDMFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,LCDTFTFreq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSI_VALUE,OCTOSPIMFreq_Value,PLLM1,PLLM2,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSAI2PoutputFreq_Value,PLLSAI2QoutputFreq_Value,PLLSAI2RoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value,VCOSAI2OutputFreq_Value
RCC.LCDTFTFreq_Value=48000000
RCC.LPTIM1Freq_Value=84000000
RCC.LPTIM2Freq_Value=84000000
RCC.LPUART1Freq_Value=84000000
RCC.LSCOPinFreq_Value=32000
RCC.LSI_VALUE=32000
RCC.MCO1PinFreq_Value=84000000
RCC.MSI_VALUE=4000000
RCC.OCTOSPIMFreq_Value=84000000
RCC.PLLM1=3
RCC.PLLM2=3
RCC.PLLN=21
RCC.PLLPoutputFreq_Value=84000000
RCC.PLLQoutputFreq_Value=84000000
RCC.PLLRCLKFreq_Value=84000000
RCC.PLLSAI1N=12
RCC.PLLSAI1PoutputFreq_Value=48000000
RCC.PLLSAI1QoutputFreq_Value=48000000
RCC.PLLSAI1RoutputFreq_Value=48000000
RCC.PLLSAI2PoutputFreq_Value=96000000
RCC.PLLSAI2QoutputFreq_Value=96000000
RCC.PLLSAI2RoutputFreq_Value=96000000
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.PWRFreq_Value=84000000
RCC.RNGFreq_Value=48000000
RCC.SAI1Freq_Value=48000000
RCC.SAI2Freq_Value=48000000
RCC.SDMMCFreq_Value=84000000
RCC.SYSCLKFreq_VALUE=84000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.UART4Freq_Value=84000000
RCC.UART5Freq_Value=84000000
RCC.USART1Freq_Value=84000000
RCC.USART2Freq_Value=84000000
RCC.USART3Freq_Value=84000000
RCC.USBFreq_Value=48000000
RCC.VCOInput2Freq_Value=8000000
RCC.VCOInput3Freq_Value=24000000
RCC.VCOInputFreq_Value=8000000
RCC.VCOOutputFreq_Value=168000000
RCC.VCOSAI1OutputFreq_Value=96000000
RCC.VCOSAI2OutputFreq_Value=192000000
USB_OTG_FS.IPParameters=VirtualMode
USB_OTG_FS.VirtualMode=Device_Only
VP_SYS_VS_tim6.Mode=TIM6
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
board=custom

system_stm32l4xx.c

/**
  ******************************************************************************
  * @file    system_stm32l4xx.c
  * @author  MCD Application Team
  * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
  *
  *   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_stm32l4xx.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.
  *
  *   After each device reset the MSI (4 MHz) is used as system clock source.
  *   Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to
  *   configure the system clock before to branch to main program.
  *
  *   This file configures the system clock as follows:
  *=============================================================================
  *-----------------------------------------------------------------------------
  *        System Clock source                    | MSI
  *-----------------------------------------------------------------------------
  *        SYSCLK(Hz)                             | 4000000
  *-----------------------------------------------------------------------------
  *        HCLK(Hz)                               | 4000000
  *-----------------------------------------------------------------------------
  *        AHB Prescaler                          | 1
  *-----------------------------------------------------------------------------
  *        APB1 Prescaler                         | 1
  *-----------------------------------------------------------------------------
  *        APB2 Prescaler                         | 1
  *-----------------------------------------------------------------------------
  *        PLL_M                                  | 1
  *-----------------------------------------------------------------------------
  *        PLL_N                                  | 8
  *-----------------------------------------------------------------------------
  *        PLL_P                                  | 7
  *-----------------------------------------------------------------------------
  *        PLL_Q                                  | 2
  *-----------------------------------------------------------------------------
  *        PLL_R                                  | 2
  *-----------------------------------------------------------------------------
  *        PLLSAI1_P                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI1_Q                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI1_R                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_P                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_Q                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_R                              | NA
  *-----------------------------------------------------------------------------
  *        Require 48MHz for USB OTG FS,          | Disabled
  *        SDIO and RNG clock                     |
  *-----------------------------------------------------------------------------
  *=============================================================================
  ******************************************************************************
  * @attention
  *
  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Apache License, Version 2.0,
  * 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/Apache-2.0
  *
  ******************************************************************************
  */

/** @addtogroup CMSIS
  * @{
  */

/** @addtogroup stm32l4xx_system
  * @{
  */

/** @addtogroup STM32L4xx_System_Private_Includes
  * @{
  */

#include "stm32l4xx.h"

/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_TypesDefinitions
  * @{
  */

/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_Defines
  * @{
  */

#if !defined  (HSE_VALUE)
  #define HSE_VALUE    8000000U  /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */

#if !defined  (MSI_VALUE)
  #define MSI_VALUE    4000000U  /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */

#if !defined  (HSI_VALUE)
  #define HSI_VALUE    16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */

/* Note: Following vector table addresses must be defined in line with linker
         configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */

#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */

#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM1_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */

/******************************************************************************/
/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_Macros
  * @{
  */

/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_Variables
  * @{
  */
  /* The SystemCoreClock 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; then there
               is no need to call the 2 first functions listed above, since SystemCoreClock
               variable is updated automatically.
  */
  uint32_t SystemCoreClock = 4000000U;

  const uint8_t  AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
  const uint8_t  APBPrescTable[8] =  {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
  const uint32_t MSIRangeTable[12] = {100000U,   200000U,   400000U,   800000U,  1000000U,  2000000U, \
                                      4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U};
/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes
  * @{
  */

/**
  * @}
  */

/** @addtogroup STM32L4xx_System_Private_Functions
  * @{
  */

/**
  * @brief  Setup the microcontroller system.
  * @retval None
  */

void SystemInit(void)
{
#if defined(USER_VECT_TAB_ADDRESS)
  /* Configure the Vector Table location -------------------------------------*/
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif

  /* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  SCB->CPACR |= ((3UL << 20U)|(3UL << 22U));  /* set CP10 and CP11 Full Access */
#endif

  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set MSION bit */
  RCC->CR |= RCC_CR_MSION;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000U;

  /* Reset HSEON, CSSON , HSION, and PLLON bits */
  RCC->CR &= 0xEAF6FFFFU;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x00001000U;

  /* Reset HSEBYP bit */
  RCC->CR &= 0xFFFBFFFFU;

  /* Disable all interrupts */
  RCC->CIER = 0x00000000U;
}

/**
  * @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 MSI, SystemCoreClock will contain the MSI_VALUE(*)
  *
  *           - 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(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
  *
  *         (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  *             4 MHz) but the real value may vary depending on the variations
  *             in voltage and temperature.
  *
  *         (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  *              16 MHz) but the real value may vary depending on the variations
  *              in voltage and temperature.
  *
  *         (***) HSE_VALUE is a constant defined in stm32l4xx_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.
  *
  * @retval None
  */
void SystemCoreClockUpdate(void)
{
  uint32_t tmp, msirange, pllvco, pllsource, pllm, pllr;

  /* Get MSI Range frequency--------------------------------------------------*/
  if ((RCC->CR & RCC_CR_MSIRGSEL) == 0U)
  { /* MSISRANGE from RCC_CSR applies */
    msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U;
  }
  else
  { /* MSIRANGE from RCC_CR applies */
    msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U;
  }
  /*MSI frequency range in HZ*/
  msirange = MSIRangeTable[msirange];

  /* Get SYSCLK source -------------------------------------------------------*/
  switch (RCC->CFGR & RCC_CFGR_SWS)
  {
    case 0x00:  /* MSI used as system clock source */
      SystemCoreClock = msirange;
      break;

    case 0x04:  /* HSI used as system clock source */
      SystemCoreClock = HSI_VALUE;
      break;

    case 0x08:  /* HSE used as system clock source */
      SystemCoreClock = HSE_VALUE;
      break;

    case 0x0C:  /* PLL used as system clock  source */
      /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
         SYSCLK = PLL_VCO / PLLR
         */
      pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
      pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ;

      switch (pllsource)
      {
        case 0x02:  /* HSI used as PLL clock source */
          pllvco = (HSI_VALUE / pllm);
          break;

        case 0x03:  /* HSE used as PLL clock source */
          pllvco = (HSE_VALUE / pllm);
          break;

        default:    /* MSI used as PLL clock source */
          pllvco = (msirange / pllm);
          break;
      }
      pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U);
      pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U;
      SystemCoreClock = pllvco/pllr;
      break;

    default:
      SystemCoreClock = msirange;
      break;
  }
  /* Compute HCLK clock frequency --------------------------------------------*/
  /* Get HCLK prescaler */
  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
  /* HCLK clock frequency */
  SystemCoreClock >>= tmp;
}


/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

USB_Debug.c

/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB
 * Copyright (c) 2004-2019 Arm Limited (or its affiliates). All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USB_Debug.c
 * Purpose: USB Host/Device Debug Configuration
 * Rev.:    V1.0.0
 *----------------------------------------------------------------------------*/

//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

// <e>USB Host Debug
// <i>Enable USB Host debugging with Event Recorder
#define USBH_DEBUG_EVR                  1

//   <o>Core <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Core event recording
#define USBH_DEBUG_EVR_Core             3

//   <o>Driver <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Driver event recording
#define USBH_DEBUG_EVR_Driver           1

//   <o>Custom Class <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Custom Class event recording
#define USBH_DEBUG_EVR_CC               1

//   <o>Communication Device Class (CDC) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Communication Device Class event recording
#define USBH_DEBUG_EVR_CDC              1

//   <o>Human Interface Device class (HID) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Human Interface Device class event recording
#define USBH_DEBUG_EVR_HID              3

//   <o>Mass Storage Class (MSC) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Host Mass Storage Class event recording
#define USBH_DEBUG_EVR_MSC              1
// </e>

// <e>USB Device Debug
// <i>Enable USB Device debugging with Event Recorder
#define USBD_DEBUG_EVR                  0

//   <o>Core <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Core event recording
#define USBD_DEBUG_EVR_Core             1

//   <o>Driver <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Driver event recording
#define USBD_DEBUG_EVR_Driver           1

//   <o>Custom Class <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Custom Class event recording
#define USBD_DEBUG_EVR_CC               1

//   <o>Audio Device Class (ADC) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Audio Device Class event recording
#define USBD_DEBUG_EVR_ADC              1

//   <o>Communication Device Class (CDC) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Communication Device Class event recording
#define USBD_DEBUG_EVR_CDC              1

//   <o>Human Interface Device class (HID) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Human Interface Device class event recording
#define USBD_DEBUG_EVR_HID              1

//   <o>Mass Storage Class (MSC) <0=>Off <1=>Errors <2=>Errors + API <3=>All
//   <i>Configure USB Device Mass Storage Class event recording
#define USBD_DEBUG_EVR_MSC              1
// </e>

//------------- <<< end of configuration section >>> ---------------------------


#include "RTE_Components.h"

#ifdef    RTE_USB_Core_Debug

#ifdef    RTE_USB_Device_0
#include "usbd_debug.h"
#endif

#ifdef    RTE_USB_Host_0
#include "usbh_debug.h"
#endif

#endif // RTE_USB_Core_Debug

USBD_Config_0.c

/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB:Device
 * Copyright (c) 2004-2019 Arm Limited (or its affiliates). All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USBD_Config_0.c
 * Purpose: USB Device Configuration
 * Rev.:    V5.2.0
 *------------------------------------------------------------------------------
 * Use the following configuration settings in the Device Class configuration
 * files to assign a Device Class to this USB Device 0.
 *
 * Configuration Setting               Value
 * ---------------------               -----
 * Assign Device Class to USB Device # = 0
 *----------------------------------------------------------------------------*/

//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

// <h>USB Device 0
//   <o>Connect to hardware via Driver_USBD# <0-255>
//   <i>Select driver control block for hardware interface.
#define USBD0_PORT                      0

//   <o.0>High-speed
//   <i>Enable High-speed functionality (if device supports it).
#define USBD0_HS                        1

//   <h>Device Settings
//   <i>These settings are used to create the Device Descriptor
//     <o>Max Endpoint 0 Packet Size
//     <i>Maximum packet size for Endpoint 0 (bMaxPacketSize0).
//       <8=>8 Bytes <16=>16 Bytes <32=>32 Bytes <64=>64 Bytes
#define USBD0_MAX_PACKET0               64

//     <o.0..15>Vendor ID <0x0000-0xFFFF>
//     <i>Vendor ID assigned by USB-IF (idVendor).
#define USBD0_DEV_DESC_IDVENDOR         0xC251

//     <o.0..15>Product ID <0x0000-0xFFFF>
//     <i>Product ID assigned by manufacturer (idProduct).
#define USBD0_DEV_DESC_IDPRODUCT        0x0000

//     <o.0..15>Device Release Number <0x0000-0xFFFF>
//     <i>Device Release Number in binary-coded decimal (bcdDevice)
#define USBD0_DEV_DESC_BCDDEVICE        0x0100

//   </h>

//   <h>Configuration Settings
//   <i>These settings are used to create the Configuration Descriptor.
//     <o.6>Power
//     <i>Default Power Setting (D6: of bmAttributes).
//       <0=>Bus-powered
//       <1=>Self-powered
//     <o.5>Remote Wakeup
//     <i>Configuration support for Remote Wakeup (D5: of bmAttributes).
#define USBD0_CFG_DESC_BMATTRIBUTES     0x80

//     <o.0..7>Maximum Power Consumption (in mA) <0-510><#/2>
//     <i>Maximum Power Consumption of USB Device from bus in this
//     <i>specific configuration when device is fully operational (bMaxPower).
#define USBD0_CFG_DESC_BMAXPOWER        250

//   </h>

//   <h>String Settings
//   <i>These settings are used to create the String Descriptor.
//     <o.0..15>Language ID <0x0000-0xFCFF>
//     <i>English (United States) = 0x0409.
#define USBD0_STR_DESC_LANGID           0x0409

//     <s.126>Manufacturer String
//     <i>String Descriptor describing Manufacturer.
#define USBD0_STR_DESC_MAN              L"Centralp"

//     <s.126>Product String
//     <i>String Descriptor describing Product.
#define USBD0_STR_DESC_PROD             L"K-USB-Device"

//     <e.0>Serial Number String
//     <i>Enable Serial Number String.
//     <i>If disabled Serial Number String will not be assigned to USB Device.
#define USBD0_STR_DESC_SER_EN           1

//       <s.126>Default value
//       <i>Default device's Serial Number String.
#define USBD0_STR_DESC_SER              L"0001A0000000"

//       <o.0..7>Maximum Length (in characters) <0-126>
//       <i>Specifies the maximum number of Serial Number String characters that can be set at run-time.
//       <i>Maximum value is 126. Use value 0 to disable RAM allocation for string.
#define USBD0_STR_DESC_SER_MAX_LEN      16

//     </e>
//   </h>

//   <h>Microsoft OS Descriptors Settings
//   <i>These settings are used to create the Microsoft OS Descriptors.
//     <e.0>OS String
//     <i>Enable creation of Microsoft OS String and Extended Compat ID OS Feature Descriptors.
#define USBD0_OS_DESC_EN                1

//       <o.0..7>Vendor Code <0x01-0xFF>
//       <i>Specifies Vendor Code used to retrieve OS Feature Descriptors.
#define USBD0_OS_DESC_VENDOR_CODE       0x01

//     </e>
//   </h>

//   <o>Control Transfer Buffer Size <64-65536:64>
//   <i>Specifies size of buffer used for Control Transfers.
//   <i>It should be at least as big as maximum packet size for Endpoint 0.
#define USBD0_EP0_BUF_SIZE              128

//   <h>OS Resources Settings
//   <i>These settings are used to optimize usage of OS resources.
//     <o>Core Thread Stack Size <64-65536>
#define USBD0_CORE_THREAD_STACK_SIZE    1024

//        Core Thread Priority
#define USBD0_CORE_THREAD_PRIORITY      osPriorityAboveNormal

//   </h>
// </h>


#include "RTE_Components.h"

#ifdef  RTE_USB_Device_CustomClass_0
#include "USBD_Config_CustomClass_0.h"
#endif
#ifdef  RTE_USB_Device_CustomClass_1
#include "USBD_Config_CustomClass_1.h"
#endif
#ifdef  RTE_USB_Device_CustomClass_2
#include "USBD_Config_CustomClass_2.h"
#endif
#ifdef  RTE_USB_Device_CustomClass_3
#include "USBD_Config_CustomClass_3.h"
#endif

#ifdef  RTE_USB_Device_HID_0
#include "USBD_Config_HID_0.h"
#endif
#ifdef  RTE_USB_Device_HID_1
#include "USBD_Config_HID_1.h"
#endif
#ifdef  RTE_USB_Device_HID_2
#include "USBD_Config_HID_2.h"
#endif
#ifdef  RTE_USB_Device_HID_3
#include "USBD_Config_HID_3.h"
#endif

#ifdef  RTE_USB_Device_MSC_0
#include "USBD_Config_MSC_0.h"
#endif
#ifdef  RTE_USB_Device_MSC_1
#include "USBD_Config_MSC_1.h"
#endif
#ifdef  RTE_USB_Device_MSC_2
#include "USBD_Config_MSC_2.h"
#endif
#ifdef  RTE_USB_Device_MSC_3
#include "USBD_Config_MSC_3.h"
#endif

#ifdef  RTE_USB_Device_CDC_0
#include "USBD_Config_CDC_0.h"
#endif
#ifdef  RTE_USB_Device_CDC_1
#include "USBD_Config_CDC_1.h"
#endif
#ifdef  RTE_USB_Device_CDC_2
#include "USBD_Config_CDC_2.h"
#endif
#ifdef  RTE_USB_Device_CDC_3
#include "USBD_Config_CDC_3.h"
#endif
#ifdef  RTE_USB_Device_CDC_4
#include "USBD_Config_CDC_4.h"
#endif
#ifdef  RTE_USB_Device_CDC_5
#include "USBD_Config_CDC_5.h"
#endif
#ifdef  RTE_USB_Device_CDC_6
#include "USBD_Config_CDC_6.h"
#endif
#ifdef  RTE_USB_Device_CDC_7
#include "USBD_Config_CDC_7.h"
#endif

#ifdef  RTE_USB_Device_ADC_0
#include "USBD_Config_ADC_0.h"
#endif
#ifdef  RTE_USB_Device_ADC_1
#include "USBD_Config_ADC_1.h"
#endif
#ifdef  RTE_USB_Device_ADC_2
#include "USBD_Config_ADC_2.h"
#endif
#ifdef  RTE_USB_Device_ADC_3
#include "USBD_Config_ADC_3.h"
#endif

#include "usbd_config.h"

USBD_Config_HID_0.h

/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB:Device
 * Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USBD_Config_HID_0.h
 * Purpose: USB Device Human Interface Device class (HID) Configuration
 * Rev.:    V5.0.2
 *----------------------------------------------------------------------------*/

//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

// <h>USB Device: Human Interface Device class (HID) 0
//   <o>Assign Device Class to USB Device # <0-3>
//   <i>Select USB Device that is used for this Device Class instance
#define USBD_HID0_DEV                             0

//   <h>Interrupt Endpoint Settings
//   <i>By default, the settings match the first USB Class instance in a USB Device.
//   <i>Endpoint conflicts are flagged by compile-time error messages.
//
//     <h>Interrupt IN Endpoint Settings
//       <o.0..3>Interrupt IN Endpoint Number
//                 <1=>1   <2=>2   <3=>3   <4=>4   <5=>5   <6=>6   <7=>7
//         <8=>8   <9=>9   <10=>10 <11=>11 <12=>12 <13=>13 <14=>14 <15=>15
#define USBD_HID0_EP_INT_IN                       1

//       <h>Endpoint Settings
//         <i>Parameters are used to create Endpoint Descriptors
//         <i>and for memory allocation in the USB component.
//
//         <h>Full/Low-speed (High-speed disabled)
//         <i>Parameters apply when High-speed is disabled in USBD_Config_n.c
//           <o.0..6>Maximum Endpoint Packet Size (in bytes) <0-64>
//           <i>Specifies the physical packet size used for information exchange.
//           <i>Maximum value is 64.
#define USBD_HID0_EP_INT_IN_WMAXPACKETSIZE        64

//           <o.0..7>Endpoint polling Interval (in ms) <1-255>
//           <i>Specifies the frequency of requests initiated by USB Host for getting data.
#define USBD_HID0_EP_INT_IN_BINTERVAL             16

//         </h>

//         <h>High-speed
//         <i>Parameters apply when High-speed is enabled in USBD_Config_n.c
//
//           <o.0..10>Maximum Endpoint Packet Size (in bytes) <0-1024>
//           <i>Specifies the physical packet size used for information exchange.
//           <i>Maximum value is 1024.
//           <o.11..12>Additional transactions per microframe
//           <i>Additional transactions improve communication performance.
//             <0=>None <1=>1 additional <2=>2 additional
#define USBD_HID0_EP_INT_IN_HS_WMAXPACKETSIZE     64

//           <o.0..4>Endpoint polling Interval (in 125 us intervals)
//           <i>Specifies the frequency of requests initiated by USB Host for getting data.
//             <1=>    1 <2=>    2 <3=>     4 <4=>     8
//             <5=>   16 <6=>   32 <7=>    64 <8=>   128
//             <9=>  256 <10=> 512 <11=> 1024 <12=> 2048
//             <13=>4096 <14=>8192 <15=>16384 <16=>32768
#define USBD_HID0_EP_INT_IN_HS_BINTERVAL          5

//         </h>
//       </h>
//     </h>

//     <h>Interrupt OUT Endpoint Settings
//       <o.0..3>Interrupt OUT Endpoint Number
//         <i>When OUT Endpoint is set to "Not used" the USB Host uses
//         <i>the Control Endpoint 0 for Out Reports.
//         <0=>Not used
//                 <1=>1   <2=>2   <3=>3   <4=>4   <5=>5   <6=>6   <7=>7
//         <8=>8   <9=>9   <10=>10 <11=>11 <12=>12 <13=>13 <14=>14 <15=>15
#define USBD_HID0_EP_INT_OUT                      1

//       <h>Endpoint Settings
//         <i>Parameters are used to create USB Descriptors, HID Device Descriptor
//         <i>and for memory allocation in the USB component.
//
//         <h>Full/Low-speed (High-speed disabled)
//         <i>Parameters apply when High-speed is disabled in USBD_Config_n.c
//           <o.0..6>Maximum Endpoint Packet Size (in bytes) <0-64>
//           <i>Specifies the physical packet size used for information exchange.
//           <i>Maximum value is 64.
#define USBD_HID0_EP_INT_OUT_WMAXPACKETSIZE       4

//           <o.0..7>Endpoint polling Interval (in ms) <1-255>
//           <i>Specifies the frequency of requests sent by USB Host for setting data.
#define USBD_HID0_EP_INT_OUT_BINTERVAL            16

//         </h>

//         <h>High-speed
//         <i>Parameters apply when High-speed is enabled in USBD_Config_n.c
//
//           <o.0..10>Maximum Endpoint Packet Size (in bytes) <0-1024>
//           <i>Specifies the physical packet size used for information exchange.
//           <i>Maximum value is 1024.
//           <o.11..12>Additional transactions per microframe
//           <i>Additional transactions improve communication performance.
//             <0=>None <1=>1 additional <2=>2 additional
#define USBD_HID0_EP_INT_OUT_HS_WMAXPACKETSIZE    4

//           <o.0..4>Endpoint polling Interval (in 125 us intervals)
//           <i>Specifies the frequency of requests sent by USB Host for setting data.
//             <1=>    1 <2=>    2 <3=>     4 <4=>     8
//             <5=>   16 <6=>   32 <7=>    64 <8=>   128
//             <9=>  256 <10=> 512 <11=> 1024 <12=> 2048
//             <13=>4096 <14=>8192 <15=>16384 <16=>32768
#define USBD_HID0_EP_INT_OUT_HS_BINTERVAL         5

//         </h>
//       </h>
//     </h>
//   </h>

//   <h>Human Interface Device Class Settings
//   <i>Parameters are used to create USB Descriptors, USB HID Report Descriptor
//   <i>and for memory allocation in the USB component.
//
//     <s.126>HID Interface String
#define USBD_HID0_STR_DESC                        L"USB_HID_KBD"

//     <o.0..4>Number of Input Reports <1-32>
//     <i>Configures max 'rid' value for USBD_HID0_GetReport and USBD_HID_GetReportTrigger
#define USBD_HID0_IN_REPORT_NUM                   8

//     <o.0..4>Number of Output Reports <1-32>
//     <i>Configures max 'rid' value for USBD_HID0_SetReport
#define USBD_HID0_OUT_REPORT_NUM                  16

//     <o.0..15>Maximum Input Report Size (in bytes) <1-65535>
//     <i>Allocates memory and configures 'len' value for USBD_HID0_GetReport
//     <i>and USBD_HID_GetReportTrigger
#define USBD_HID0_IN_REPORT_MAX_SZ                8

//     <o.0..15>Maximum Output Report Size (in bytes) <1-65535>
//     <i>Allocates memory and configures 'len' value for USBD_HID0_SetReport
//     <i>when rtype=HID_REPORT_OUTPUT.
#define USBD_HID0_OUT_REPORT_MAX_SZ               16

//     <o.0..15>Maximum Feature Report Size (in bytes) <1-65535>
//     <i>Allocates memory and configures 'len' value for USBD_HID0_SetReport
//     <i>when rtype=HID_REPORT_FEATURE
#define USBD_HID0_FEAT_REPORT_MAX_SZ              63

//     <e.0>Use User Provided HID Report Descriptor
//     <i>User needs to provide HID Report Descriptor in array
//     <i>const uint8_t usbd_hid0_report_descriptor[]
#define USBD_HID0_USER_REPORT_DESCRIPTOR          1

//       <o>User Provided HID Report Descriptor Size (in bytes) <1-65535>
#define USBD_HID0_USER_REPORT_DESCRIPTOR_SIZE     63

//     </e>
//   </h>

//   <h>OS Resources Settings
//   <i>These settings are used to optimize usage of OS resources.
//     <o>Human Interface Device Class Thread Stack Size <64-65536>
#define USBD_HID0_THREAD_STACK_SIZE               512

//        Human Interface Device Class Thread Priority
#define USBD_HID0_THREAD_PRIORITY                 osPriorityAboveNormal

//   </h>
// </h>

USBD_HID_Keyboard.c

/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB:Device:HID
 * Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USBD_User_HID_Mouse_0.c
 * Purpose: USB Device Human Interface Device class (HID) User module
 * Rev.:    V6.3.4
 *----------------------------------------------------------------------------*/
/**
 * \addtogroup usbd_hidFunctions
 *
 * USBD_User_HID_Mouse_0.c implements the application specific 
 * functionality of the HID class and is used to receive and send data reports
 * to the USB Host.
 *
 * The implementation must match the configuration file USBD_Config_HID_0.h.
 * The following values in USBD_Config_HID_0.h affect the user code:
 *
 *  - 'Endpoint polling Interval' specifies the frequency of requests
 *    initiated by USB Host for \ref USBD_HIDn_GetReport.
 *
 *  - 'Number of Output Reports' configures the values for \em rid of
 *    \ref USBD_HIDn_SetReport.
 *
 *  - 'Number of Input Reports' configures the values for \em rid of
 *    \ref USBD_HIDn_GetReport and \ref USBD_HID_GetReportTrigger.
 *
 *  - 'Maximum Input Report Size' specifies the maximum value for:
 *       - return of \ref USBD_HIDn_GetReport
 *       - len of \ref USBD_HID_GetReportTrigger.
 *
 *  - 'Maximum Output Report Size' specifies the maximum value for \em len
 *    in \ref USBD_HIDn_SetReport for rtype=HID_REPORT_OUTPUT
 *
 *  - 'Maximum Feature Report Size' specifies the maximum value for \em len
 *    in \ref USBD_HIDn_SetReport for rtype=HID_REPORT_FEATURE
 *
 *  - 'Use User Provided HID Report Descriptor' has to be enabled
 * 
 *  - 'User Provided HID Report Descriptor Size' has to be correctly set to
 *    size of User Provided HID Report Descriptor. This information can be
 *    retrieved from map file.
 *    (for example for mouse this value has to be set to 52, keyboard is 63)
 *
 */
 
 
//! [code_USBD_User_HID_Keyboard]
 
#include <stdint.h>
 
#include "rl_usb.h"
 
// User Provided HID Report Descriptor
// for standard keyboard (size of this descriptor is 63 bytes)
// From https://www.microchip.com/forums/m816038.aspx
// Adatpation by Centralp https://community.arm.com/support-forums/f/keil-forum/52780/stm32f4-usbd-keyboard-problem-with-usb_cm3_l-lib
extern const uint8_t usbd_hid0_report_descriptor[63];
/*LDRA_NOANALYSIS*/
/*LDRA n'est pas capable de voir que les macros definissent 2 octets : erreur */
/*LDRA : Array initialisation has insufficient items. : usbd_hid0_report_descriptor[*]; given=32, expected=63 */
const uint8_t usbd_hid0_report_descriptor[63] = {
  HID_UsagePage(HID_USAGE_PAGE_GENERIC),       // 0x05, 0x01, // Usage Page (Generic Desktop),
  HID_Usage(HID_USAGE_GENERIC_KEYBOARD),       // 0x09, 0x06, // Usage (Keyboard),
  HID_Collection(HID_Application),             // 0xA1, 0x01, // Collection (Application),
      HID_UsagePage(HID_USAGE_PAGE_KEYBOARD),  // 0x05, 0x07, // Usage Page (Key Codes);
      HID_UsageMin(HID_USAGE_KEYBOARD_LCTRL),  //  0x19, 0xE0, // Usage Minimum (224),
      HID_UsageMax(HID_USAGE_KEYBOARD_RGUI),   //  0x29, 0xE7, // Usage Maximum (231),
      HID_LogicalMin(0),  //  0x15, 0x00, // Logical Minimum (0),
      HID_LogicalMax(1),  //  0x25, 0x01, // Logical Maximum (1),
      HID_ReportSize(1),  //  0x75, 0x01, // Report Size (1),
      HID_ReportCount(8), //  0x95, 0x08, // Report Count (8),
			HID_Input(HID_Data | HID_Variable | HID_Absolute), //  0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte
      HID_ReportCount(1), //  0x95, 0x01, // Report Count (1),
      HID_ReportSize(8),  //  0x75, 0x08, // Report Size (8),
      HID_Input(HID_Constant),  //  0x81, 0x01, // Input (Constant), ; Reserved byte
      HID_ReportCount(3), //  0x95, 0x05, // Report Count (5),
      HID_ReportSize(1),  //  0x75, 0x01, // Report Size (1), 
      HID_UsagePage(HID_USAGE_PAGE_LED),   // 0x05, 0x08, // Usage Page (Page# for LEDs),	
      HID_UsageMin(1),  //  0x19, 0x01, // Usage Minimum (1),
      HID_UsageMax(3),  //  0x29, 0x05, // Usage Maxmimum (5),
			HID_Output(2),		//  0x91, 0x02, // Output (Data, Variable, Absolute), ; LED report
      HID_ReportCount(1), //  0x95, 0x01, // Report Count (1),
      HID_ReportSize(5),  //  0x75, 0x03, // Report Size (3),
			HID_Output(HID_Constant), // 0x91, 0x01, // Output (Constant), ; LED report padding
      HID_ReportCount(6), //  0x95, 0x06, // Report Count (6),
      HID_ReportSize(8),  //  0x75, 0x08, // Report Size (8),
      HID_LogicalMin(0),  //  0x15, 0x00, // Logical Minimum (0),
      HID_LogicalMax(101),//  0x25, 0x65, // Logical Maximum (101),
      HID_UsagePage(HID_USAGE_PAGE_KEYBOARD), //  0x05, 0x07, // Usage Page (Key Codes),
			HID_UsageMin(0),   // 0x19, 0x00, // Usage Minimum (0), 
			HID_UsageMax(101), // 0x29, 0x65, // Usage Maximum (101),
			HID_Input(HID_Data | HID_Array | HID_Absolute),  // 0x81, 0x00, // Input (Data, Array), ; Key arrays (6 bytes)
  HID_EndCollection, // End Collection
};
/*LDRA_ANALYSIS*/


 
// Called during USBD_Uninitialize to de-initialize the USB HID class instance.
void USBD_HID0_Uninitialize (void) {
  // Add code for de-initialization
}
 
 
// \brief Prepare HID Report data to send.
// \param[in]   rtype   report type:
//                - HID_REPORT_INPUT           = input report requested
//                - HID_REPORT_FEATURE         = feature report requested
// \param[in]   req     request type:
//                - USBD_HID_REQ_EP_CTRL       = control endpoint request
//                - USBD_HID_REQ_PERIOD_UPDATE = idle period expiration request
//                - USBD_HID_REQ_EP_INT        = previously sent report on interrupt endpoint request
// \param[in]   rid     report ID (0 if only one report exists).
// \param[out]  buf     buffer containing report data to send.
// \return              number of report data bytes prepared to send or invalid report requested.
//              - value >= 0: number of report data bytes prepared to send
//              - value = -1: invalid report requested
int32_t USBD_HID0_GetReport (uint8_t rtype, uint8_t req, uint8_t rid, uint8_t *buf) {
 
  (void)buf;
 
  switch (rtype) {
    case HID_REPORT_INPUT:
      switch (rid) {
        case 0:
          switch (req) {
            case USBD_HID_REQ_EP_CTRL:        // Explicit USB Host request via Control OUT Endpoint
            case USBD_HID_REQ_PERIOD_UPDATE:  // Periodic USB Host request via Interrupt OUT Endpoint
              // Update buffer for report data, example:
              // buf[0] = 0;       // Data Value = 0
              // buf[1] = 5;       // Data Value = 5
              // return (2);       // Data Size  = 2 bytes
              break;
 
            case USBD_HID_REQ_EP_INT:         // Called after USBD_HID_GetReportTrigger to signal
                                              // data obtained.
              break;
 
            default:
              break;
          }
          break;
 
        default:
          break;
      }
      break;
 
    case HID_REPORT_FEATURE:
      break;
 
    default:
      break;
  }
 
  return (0);
}
 
 
// \brief Process received HID Report data.
// \param[in]   rtype   report type:
//                - HID_REPORT_OUTPUT    = output report received
//                - HID_REPORT_FEATURE   = feature report received
// \param[in]   req     request type:
//                - USBD_HID_REQ_EP_CTRL = report received on control endpoint
//                - USBD_HID_REQ_EP_INT  = report received on interrupt endpoint
// \param[in]   rid     report ID (0 if only one report exists).
// \param[in]   buf     buffer that receives report data.
// \param[in]   len     length of received report data.
// \return      true    received report data processed.
// \return      false   received report data not processed or request not supported.
bool USBD_HID0_SetReport (uint8_t rtype, uint8_t req, uint8_t rid, const uint8_t *buf, int32_t len) {
 
  (void)req;
  (void)rid;
  (void)buf;
  (void)len;
 
  switch (rtype) {
    case HID_REPORT_OUTPUT:
      /*
        buf: Received Data
        len: Received Data Length
      */
      break;
 
    case HID_REPORT_FEATURE:
      break;
 
    default:
      break;
  }
 
  return true;
}
 
//! [code_USBD_User_HID_Keyboard]