Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Flipper-Zero/STM32CubeWB.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Projects/NUCLEO-WB35CE/Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c')
-rw-r--r--Projects/NUCLEO-WB35CE/Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c572
1 files changed, 572 insertions, 0 deletions
diff --git a/Projects/NUCLEO-WB35CE/Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c b/Projects/NUCLEO-WB35CE/Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c
new file mode 100644
index 000000000..0a3de9762
--- /dev/null
+++ b/Projects/NUCLEO-WB35CE/Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c
@@ -0,0 +1,572 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file Examples_LL/SPI/SPI_TwoBoards_FullDuplex_DMA_Slave_Init/Src/main.c
+ * @author MCD Application Team
+ * @brief This example describes how to send/receive bytes over SPI IP using
+ * the STM32WBxx SPI LL API.
+ * Peripheral initialization done using LL unitary services functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * 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"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* 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 ---------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+
+__IO uint8_t ubButtonPress = 0;
+
+/* Buffer used for transmission */
+uint8_t aTxBuffer[] = "**** SPI_TwoBoards_FullDuplex_DMA communication **** SPI_TwoBoards_FullDuplex_DMA communication **** SPI_TwoBoards_FullDuplex_DMA communication ****";
+uint8_t ubNbDataToTransmit = sizeof(aTxBuffer);
+__IO uint8_t ubTransmissionComplete = 0;
+
+/* Buffer used for reception */
+uint8_t aRxBuffer[sizeof(aTxBuffer)];
+uint8_t ubNbDataToReceive = sizeof(aTxBuffer);
+__IO uint8_t ubReceptionComplete = 0;
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MX_GPIO_Init(void);
+static void MX_DMA_Init(void);
+static void MX_SPI1_Init(void);
+/* USER CODE BEGIN PFP */
+
+void SystemClock_Config(void);
+void Activate_SPI(void);
+void LED_On(void);
+void LED_Blinking(uint32_t Period);
+void WaitAndCheckEndOfTransfer(void);
+uint8_t Buffercmp8(uint8_t *pBuffer1, uint8_t *pBuffer2, uint8_t BufferLength);
+
+/* 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 */
+ /* USER CODE END 1 */
+
+ /* MCU Configuration--------------------------------------------------------*/
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+
+
+ NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* System interrupt 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_DMA_Init();
+ MX_SPI1_Init();
+ /* USER CODE BEGIN 2 */
+
+ /* Configure the DMA1_Channel3 functional parameters */
+ LL_DMA_ConfigTransfer(DMA1,
+ LL_DMA_CHANNEL_3,
+ LL_DMA_DIRECTION_MEMORY_TO_PERIPH | LL_DMA_PRIORITY_HIGH | LL_DMA_MODE_NORMAL |
+ LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT |
+ LL_DMA_PDATAALIGN_BYTE | LL_DMA_MDATAALIGN_BYTE);
+ LL_DMA_ConfigAddresses(DMA1,
+ LL_DMA_CHANNEL_3,
+ (uint32_t)aTxBuffer, LL_SPI_DMA_GetRegAddr(SPI1),
+ LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3));
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, ubNbDataToReceive);
+
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_3, LL_DMAMUX_REQ_SPI1_TX);
+
+
+ /* Configure the DMA1_Channel1 functional parameters */
+ LL_DMA_ConfigTransfer(DMA1,
+ LL_DMA_CHANNEL_1,
+ LL_DMA_DIRECTION_PERIPH_TO_MEMORY | LL_DMA_PRIORITY_HIGH | LL_DMA_MODE_NORMAL |
+ LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT |
+ LL_DMA_PDATAALIGN_BYTE | LL_DMA_MDATAALIGN_BYTE);
+ LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1, LL_SPI_DMA_GetRegAddr(SPI1), (uint32_t)aRxBuffer,
+ LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1));
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, ubNbDataToTransmit);
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_SPI1_RX);
+
+
+ /* Enable DMA interrupts complete/error */
+ LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
+ LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
+
+ /* Initialize FFIFO Threshold */
+ LL_SPI_SetRxFIFOThreshold(SPI1, LL_SPI_RX_FIFO_TH_QUARTER);
+
+ /* Configure SPI1 DMA transfer interrupts */
+ /* Enable DMA TX Interrupt */
+ LL_SPI_EnableDMAReq_TX(SPI1);
+
+ /* Configure SPI1 DMA transfer interrupts */
+ /* Enable DMA RX Interrupt */
+ LL_SPI_EnableDMAReq_RX(SPI1);
+
+ /* Enable the SPI1 peripheral */
+ Activate_SPI();
+
+ /* Wait for the end of the transfer and check received data */
+ /* LED blinking FAST during waiting time */
+ WaitAndCheckEndOfTransfer();
+ /* USER CODE END 2 */
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ while (1)
+ {
+ /* USER CODE END WHILE */
+
+ /* USER CODE BEGIN 3 */
+ }
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
+
+ /* MSI configuration and activation */
+ LL_RCC_MSI_Enable();
+ while(LL_RCC_MSI_IsReady() != 1)
+ {
+ };
+
+ /* Main PLL configuration and activation */
+ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 32, LL_RCC_PLLR_DIV_2);
+ LL_RCC_PLL_Enable();
+ LL_RCC_PLL_EnableDomain_SYS();
+ while(LL_RCC_PLL_IsReady() != 1)
+ {
+ };
+
+ /* Sysclk activation on the main PLL */
+ /* Set CPU1 prescaler*/
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+
+ /* Set CPU2 prescaler*/
+ LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
+
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
+ while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
+ {
+ };
+
+ /* Set AHB SHARED prescaler*/
+ LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1);
+
+ /* Set APB1 prescaler*/
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
+
+ /* Set APB2 prescaler*/
+ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
+
+ LL_Init1msTick(64000000);
+
+ /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
+ LL_SetSystemCoreClock(64000000);
+ /* USER CODE BEGIN Smps */
+
+ /* USER CODE END Smps */
+}
+
+/**
+ * @brief SPI1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_SPI1_Init(void)
+{
+
+ /* USER CODE BEGIN SPI1_Init 0 */
+
+ /* USER CODE END SPI1_Init 0 */
+
+ LL_SPI_InitTypeDef SPI_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* Peripheral clock enable */
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
+
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
+ /**SPI1 GPIO Configuration
+ PA5 ------> SPI1_SCK
+ PA6 ------> SPI1_MISO
+ PA7 ------> SPI1_MOSI
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_5|LL_GPIO_PIN_7;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* SPI1 DMA Init */
+
+ /* SPI1_TX Init */
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_3, LL_DMAMUX_REQ_SPI1_TX);
+
+ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+
+ LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_LOW);
+
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL);
+
+ LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT);
+
+ LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT);
+
+ LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE);
+
+ LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE);
+
+ /* SPI1_RX Init */
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_SPI1_RX);
+
+ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
+
+ LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);
+
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_NORMAL);
+
+ LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
+
+ LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
+
+ LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_BYTE);
+
+ LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_BYTE);
+
+ /* USER CODE BEGIN SPI1_Init 1 */
+
+ /* USER CODE END SPI1_Init 1 */
+ /* SPI1 parameter configuration*/
+ SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
+ SPI_InitStruct.Mode = LL_SPI_MODE_SLAVE;
+ SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
+ SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;
+ SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;
+ SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
+ SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
+ SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
+ SPI_InitStruct.CRCPoly = 7;
+ LL_SPI_Init(SPI1, &SPI_InitStruct);
+ LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
+ LL_SPI_DisableNSSPulseMgt(SPI1);
+ /* USER CODE BEGIN SPI1_Init 2 */
+
+ /* USER CODE END SPI1_Init 2 */
+
+}
+
+/**
+ * Enable DMA controller clock
+ */
+static void MX_DMA_Init(void)
+{
+
+ /* Init with LL driver */
+ /* DMA controller clock enable */
+ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);
+ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
+
+ /* DMA interrupt init */
+ /* DMA1_Channel1_IRQn interrupt configuration */
+ NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
+ NVIC_EnableIRQ(DMA1_Channel1_IRQn);
+ /* DMA1_Channel3_IRQn interrupt configuration */
+ NVIC_SetPriority(DMA1_Channel3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
+ NVIC_EnableIRQ(DMA1_Channel3_IRQn);
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
+
+ /**/
+ LL_GPIO_ResetOutputPin(LED2_GPIO_Port, LED2_Pin);
+
+ /**/
+ GPIO_InitStruct.Pin = LED2_Pin;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ LL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
+
+}
+
+/* USER CODE BEGIN 4 */
+
+/**
+ * @brief This function Activate SPI1
+ * @param None
+ * @retval None
+ */
+void Activate_SPI(void)
+{
+ /* Enable SPI1 */
+ LL_SPI_Enable(SPI1);
+
+ /* Enable DMA Channels */
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
+}
+
+/**
+ * @brief Turn-on LED2.
+ * @param None
+ * @retval None
+ */
+void LED_On(void)
+{
+ /* Turn LED2 on */
+ LL_GPIO_SetOutputPin(LED2_GPIO_PORT, LED2_PIN);
+}
+
+
+/**
+ * @brief Set LED2 to Blinking mode for an infinite loop (toggle period based on value provided as input parameter).
+ * @param Period : Period of time (in ms) between each toggling of LED
+ * This parameter can be user defined values. Pre-defined values used in that example are :
+ * @arg LED_BLINK_FAST : Fast Blinking
+ * @arg LED_BLINK_SLOW : Slow Blinking
+ * @arg LED_BLINK_ERROR : Error specific Blinking
+ * @retval None
+ */
+void LED_Blinking(uint32_t Period)
+{
+ /* Toggle LED2 in an infinite loop */
+ while (1)
+ {
+ LL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
+ LL_mDelay(Period);
+ }
+}
+
+
+/**
+ * @brief Wait end of transfer and check if received Data are well.
+ * @param None
+ * @retval None
+ */
+void WaitAndCheckEndOfTransfer(void)
+{
+ /* 1 - Wait end of transmission */
+ while (ubTransmissionComplete != 1)
+ {
+ }
+ /* Disable DMA1 Tx Channel */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
+ /* 2 - Wait end of reception */
+ while (ubReceptionComplete != 1)
+ {
+ }
+ /* Disable DMA1 Rx Channel */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
+ /* 3 - Compare Transmit data to receive data */
+ if (Buffercmp8((uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, ubNbDataToTransmit))
+ {
+ /* Processing Error */
+ LED_Blinking(LED_BLINK_ERROR);
+ }
+ else
+ {
+ /* Turn On Led if data are well received */
+ LED_On();
+ }
+}
+
+/**
+* @brief Compares two 8-bit buffers and returns the comparison result.
+* @param pBuffer1: pointer to the source buffer to be compared to.
+* @param pBuffer2: pointer to the second source buffer to be compared to the first.
+* @param BufferLength: buffer's length.
+* @retval 0: Comparison is OK (the two Buffers are identical)
+* Value different from 0: Comparison is NOK (Buffers are different)
+*/
+uint8_t Buffercmp8(uint8_t *pBuffer1, uint8_t *pBuffer2, uint8_t BufferLength)
+{
+ while (BufferLength--)
+ {
+ if (*pBuffer1 != *pBuffer2)
+ {
+ return 1;
+ }
+
+ pBuffer1++;
+ pBuffer2++;
+ }
+
+ return 0;
+}
+
+
+/******************************************************************************/
+/* USER IRQ HANDLER TREATMENT Functions */
+/******************************************************************************/
+/**
+ * @brief Function to manage User push-button (SW1)
+ * @param None
+ * @retval None
+ */
+void UserButton_Callback(void)
+{
+ /* Update User push-button (SW1) variable : to be checked in waiting loop in main program */
+ ubButtonPress = 1;
+}
+
+/**
+ * @brief Function called from DMA1 IRQ Handler when Rx transfer is completed
+ * @param None
+ * @retval None
+ */
+void DMA1_ReceiveComplete_Callback(void)
+{
+ /* DMA Rx transfer completed */
+ ubReceptionComplete = 1;
+}
+
+/**
+ * @brief Function called from DMA1 IRQ Handler when Tx transfer is completed
+ * @param None
+ * @retval None
+ */
+void DMA1_TransmitComplete_Callback(void)
+{
+ /* DMA Tx transfer completed */
+ ubTransmissionComplete = 1;
+}
+
+/**
+ * @brief Function called in case of error detected in SPI IT Handler
+ * @param None
+ * @retval None
+ */
+void SPI1_TransferError_Callback(void)
+{
+ /* Disable DMA1 Rx Channel */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
+
+ /* Disable DMA1 Tx Channel */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
+ /* Set LED2 to Blinking mode to indicate error occurs */
+ LED_Blinking(LED_BLINK_ERROR);
+}
+
+
+/* USER CODE END 4 */
+
+/**
+ * @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 */
+
+ /* 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,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/