Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

629 lines
16 KiB

  1. /*!
  2. * \file board.c
  3. *
  4. * \brief Target board general functions implementation
  5. *
  6. * \copyright Revised BSD License, see section \ref LICENSE.
  7. *
  8. * \code
  9. * ______ _
  10. * / _____) _ | |
  11. * ( (____ _____ ____ _| |_ _____ ____| |__
  12. * \____ \| ___ | (_ _) ___ |/ ___) _ \
  13. * _____) ) ____| | | || |_| ____( (___| | | |
  14. * (______/|_____)_|_|_| \__)_____)\____)_| |_|
  15. * (C)2013-2017 Semtech
  16. *
  17. * \endcode
  18. *
  19. * \author Miguel Luis ( Semtech )
  20. *
  21. * \author Gregory Cristian ( Semtech )
  22. */
  23. #include "stm32l1xx.h"
  24. #include "utilities.h"
  25. #include "gpio.h"
  26. #include "adc.h"
  27. #include "spi.h"
  28. #include "i2c.h"
  29. #include "uart.h"
  30. #include "timer.h"
  31. #include "sysIrqHandlers.h"
  32. #include "board-config.h"
  33. #include "lpm-board.h"
  34. #include "rtc-board.h"
  35. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  36. #include "sx126x-board.h"
  37. #elif defined( LR1110MB1XXS )
  38. #include "lr1110-board.h"
  39. #elif defined( SX1272MB2DAS)
  40. #include "sx1272-board.h"
  41. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  42. #include "sx1276-board.h"
  43. #endif
  44. #include "board.h"
  45. #include <usb_device.h>
  46. /*!
  47. * Unique Devices IDs register set ( STM32L152x )
  48. */
  49. #define ID1 ( 0x1FF800D0 )
  50. #define ID2 ( 0x1FF800D4 )
  51. #define ID3 ( 0x1FF800E4 )
  52. /*!
  53. * LED GPIO pins objects
  54. */
  55. Gpio_t Led1;
  56. Gpio_t Led2;
  57. /*
  58. * MCU objects
  59. */
  60. Adc_t Adc;
  61. Uart_t Uart2;
  62. #if defined( LR1110MB1XXS )
  63. extern lr1110_t LR1110;
  64. #endif
  65. /*!
  66. * Initializes the unused GPIO to a know status
  67. */
  68. static void BoardUnusedIoInit( void );
  69. /*!
  70. * System Clock Configuration
  71. */
  72. static void SystemClockConfig( void );
  73. /*!
  74. * System Clock Re-Configuration when waking up from STOP mode
  75. */
  76. static void SystemClockReConfig( void );
  77. /*!
  78. * Flag to indicate if the MCU is Initialized
  79. */
  80. static bool McuInitialized = false;
  81. /*!
  82. * Flag used to indicate if board is powered from the USB
  83. */
  84. static bool UsbIsConnected = false;
  85. /*!
  86. * UART2 FIFO buffers size
  87. */
  88. #define UART2_FIFO_TX_SIZE 1024
  89. #define UART2_FIFO_RX_SIZE 1024
  90. uint8_t Uart2TxBuffer[UART2_FIFO_TX_SIZE];
  91. uint8_t Uart2RxBuffer[UART2_FIFO_RX_SIZE];
  92. void BoardCriticalSectionBegin( uint32_t *mask )
  93. {
  94. *mask = __get_PRIMASK( );
  95. __disable_irq( );
  96. }
  97. void BoardCriticalSectionEnd( uint32_t *mask )
  98. {
  99. __set_PRIMASK( *mask );
  100. }
  101. void BoardInitPeriph( void )
  102. {
  103. }
  104. void BoardInitMcu( void )
  105. {
  106. if( McuInitialized == false )
  107. {
  108. HAL_Init( );
  109. #if 0
  110. // LEDs
  111. GpioInit( &Led1, LED_1, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  112. GpioInit( &Led2, LED_2, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  113. #else
  114. GPIO_InitTypeDef GPIO_InitStruct;
  115. __HAL_RCC_GPIOC_CLK_ENABLE();
  116. __HAL_RCC_GPIOH_CLK_ENABLE();
  117. __HAL_RCC_GPIOA_CLK_ENABLE();
  118. __HAL_RCC_GPIOB_CLK_ENABLE();
  119. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3|GPIO_PIN_4, GPIO_PIN_RESET);
  120. /* configure PA3 and PA4 */
  121. GPIO_InitStruct = (GPIO_InitTypeDef){
  122. .Pin = GPIO_PIN_3|GPIO_PIN_4,
  123. .Mode = GPIO_MODE_OUTPUT_PP,
  124. .Pull = GPIO_NOPULL,
  125. .Speed = GPIO_SPEED_FREQ_LOW,
  126. };
  127. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  128. /* configure PB0, PB1, PB10 and PB11 */
  129. GPIO_InitStruct = (GPIO_InitTypeDef){
  130. .Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11,
  131. .Mode = GPIO_MODE_INPUT,
  132. .Pull = GPIO_NOPULL,
  133. .Speed = GPIO_SPEED_FREQ_LOW,
  134. };
  135. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  136. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
  137. /* configure PB8 */
  138. GPIO_InitStruct = (GPIO_InitTypeDef){
  139. .Pin = GPIO_PIN_8,
  140. .Mode = GPIO_MODE_OUTPUT_PP,
  141. .Pull = GPIO_NOPULL,
  142. .Speed = GPIO_SPEED_FREQ_LOW,
  143. };
  144. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  145. #endif
  146. SystemClockConfig( );
  147. UsbIsConnected = true;
  148. FifoInit( &Uart2.FifoTx, Uart2TxBuffer, UART2_FIFO_TX_SIZE );
  149. FifoInit( &Uart2.FifoRx, Uart2RxBuffer, UART2_FIFO_RX_SIZE );
  150. // Configure your terminal for 8 Bits data (7 data bit + 1 parity bit), no parity and no flow ctrl
  151. UartInit( &Uart2, UART_2, UART_TX, UART_RX );
  152. UartConfig( &Uart2, RX_TX, 921600, UART_8_BIT, UART_1_STOP_BIT, NO_PARITY, NO_FLOW_CTRL );
  153. RtcInit( );
  154. BoardUnusedIoInit( );
  155. if( GetBoardPowerSource( ) == BATTERY_POWER )
  156. {
  157. // Disables OFF mode - Enables lowest power mode (STOP)
  158. LpmSetOffMode( LPM_APPLI_ID, LPM_DISABLE );
  159. }
  160. }
  161. else
  162. {
  163. SystemClockReConfig( );
  164. }
  165. MX_USB_DEVICE_Init();
  166. AdcInit( &Adc, PB_15 ); // Just initialize ADC
  167. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  168. SpiInit( &SX126x.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  169. SX126xIoInit( );
  170. #elif defined( LR1110MB1XXS )
  171. SpiInit( &LR1110.spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  172. lr1110_board_init_io( &LR1110 );
  173. #elif defined( SX1272MB2DAS )
  174. SpiInit( &SX1272.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  175. SX1272IoInit( );
  176. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  177. SpiInit( &SX1276.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  178. SX1276IoInit( );
  179. #endif
  180. if( McuInitialized == false )
  181. {
  182. McuInitialized = true;
  183. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  184. SX126xIoDbgInit( );
  185. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  186. #elif defined( LR1110MB1XXS )
  187. lr1110_board_init_dbg_io( &LR1110 );
  188. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  189. #elif defined( SX1272MB2DAS )
  190. SX1272IoDbgInit( );
  191. SX1272IoTcxoInit( );
  192. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  193. SX1276IoDbgInit( );
  194. SX1276IoTcxoInit( );
  195. #endif
  196. }
  197. }
  198. void BoardResetMcu( void )
  199. {
  200. CRITICAL_SECTION_BEGIN( );
  201. //Restart system
  202. NVIC_SystemReset( );
  203. }
  204. void BoardDeInitMcu( void )
  205. {
  206. AdcDeInit( &Adc );
  207. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  208. SpiDeInit( &SX126x.Spi );
  209. SX126xIoDeInit( );
  210. #elif defined( LR1110MB1XXS )
  211. SpiDeInit( &LR1110.spi );
  212. lr1110_board_deinit_io( &LR1110 );
  213. #elif defined( SX1272MB2DAS )
  214. SpiDeInit( &SX1272.Spi );
  215. SX1272IoDeInit( );
  216. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  217. SpiDeInit( &SX1276.Spi );
  218. SX1276IoDeInit( );
  219. #endif
  220. }
  221. uint32_t BoardGetRandomSeed( void )
  222. {
  223. return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
  224. }
  225. void BoardGetUniqueId( uint8_t *id )
  226. {
  227. id[7] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 24;
  228. id[6] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 16;
  229. id[5] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 8;
  230. id[4] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) );
  231. id[3] = ( ( *( uint32_t* )ID2 ) ) >> 24;
  232. id[2] = ( ( *( uint32_t* )ID2 ) ) >> 16;
  233. id[1] = ( ( *( uint32_t* )ID2 ) ) >> 8;
  234. id[0] = ( ( *( uint32_t* )ID2 ) );
  235. }
  236. /*!
  237. * Factory power supply
  238. */
  239. #define VDDA_VREFINT_CAL ( ( uint32_t ) 3000 ) // mV
  240. /*!
  241. * VREF calibration value
  242. */
  243. #define VREFINT_CAL ( *( uint16_t* ) ( ( uint32_t ) 0x1FF800F8 ) )
  244. /*
  245. * Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at
  246. * a temperature of 110 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV).
  247. */
  248. #define TEMP30_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FF8007A ) )
  249. /* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at
  250. *a temperature of 30 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
  251. #define TEMP110_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FF8007E ) )
  252. /* Vdda value with which temperature sensor has been calibrated in production
  253. (+-10 mV). */
  254. #define VDDA_TEMP_CAL ( ( uint32_t ) 3000 )
  255. /*!
  256. * Battery thresholds
  257. */
  258. #define BATTERY_MAX_LEVEL 3000 // mV
  259. #define BATTERY_MIN_LEVEL 2400 // mV
  260. #define BATTERY_SHUTDOWN_LEVEL 2300 // mV
  261. #define BATTERY_LORAWAN_UNKNOWN_LEVEL 255
  262. #define BATTERY_LORAWAN_MAX_LEVEL 254
  263. #define BATTERY_LORAWAN_MIN_LEVEL 1
  264. #define BATTERY_LORAWAN_EXT_PWR 0
  265. #define COMPUTE_TEMPERATURE( TS_ADC_DATA, VDDA_APPLI ) \
  266. ( ( ( ( ( ( ( int32_t )( ( TS_ADC_DATA * VDDA_APPLI ) / VDDA_TEMP_CAL ) - ( int32_t ) TEMP30_CAL_ADDR ) ) * \
  267. ( int32_t )( 110 - 30 ) ) \
  268. << 8 ) / \
  269. ( int32_t )( TEMP110_CAL_ADDR - TEMP30_CAL_ADDR ) ) + \
  270. ( 30 << 8 ) )
  271. static uint16_t BatteryVoltage = BATTERY_MAX_LEVEL;
  272. uint16_t BoardBatteryMeasureVoltage( void )
  273. {
  274. uint16_t vref = 0;
  275. // Read the current Voltage
  276. vref = AdcReadChannel( &Adc, ADC_CHANNEL_VREFINT );
  277. // Compute and return the Voltage in millivolt
  278. return ( ( ( uint32_t ) VDDA_VREFINT_CAL * VREFINT_CAL ) / vref );
  279. }
  280. uint32_t BoardGetBatteryVoltage( void )
  281. {
  282. return BatteryVoltage;
  283. }
  284. uint8_t BoardGetBatteryLevel( void )
  285. {
  286. uint8_t batteryLevel = 0;
  287. BatteryVoltage = BoardBatteryMeasureVoltage( );
  288. if( GetBoardPowerSource( ) == USB_POWER )
  289. {
  290. batteryLevel = BATTERY_LORAWAN_EXT_PWR;
  291. }
  292. else
  293. {
  294. if( BatteryVoltage >= BATTERY_MAX_LEVEL )
  295. {
  296. batteryLevel = BATTERY_LORAWAN_MAX_LEVEL;
  297. }
  298. else if( ( BatteryVoltage > BATTERY_MIN_LEVEL ) && ( BatteryVoltage < BATTERY_MAX_LEVEL ) )
  299. {
  300. batteryLevel =
  301. ( ( 253 * ( BatteryVoltage - BATTERY_MIN_LEVEL ) ) / ( BATTERY_MAX_LEVEL - BATTERY_MIN_LEVEL ) ) + 1;
  302. }
  303. else if( ( BatteryVoltage > BATTERY_SHUTDOWN_LEVEL ) && ( BatteryVoltage <= BATTERY_MIN_LEVEL ) )
  304. {
  305. batteryLevel = 1;
  306. }
  307. else // if( BatteryVoltage <= BATTERY_SHUTDOWN_LEVEL )
  308. {
  309. batteryLevel = BATTERY_LORAWAN_UNKNOWN_LEVEL;
  310. }
  311. }
  312. return batteryLevel;
  313. }
  314. int16_t BoardGetTemperature( void )
  315. {
  316. uint16_t tempRaw = 0;
  317. BatteryVoltage = BoardBatteryMeasureVoltage( );
  318. tempRaw = AdcReadChannel( &Adc, ADC_CHANNEL_TEMPSENSOR );
  319. // Compute and return the temperature in degree celcius * 256
  320. return ( int16_t ) COMPUTE_TEMPERATURE( tempRaw, BatteryVoltage );
  321. }
  322. static void BoardUnusedIoInit( void )
  323. {
  324. HAL_DBGMCU_EnableDBGSleepMode( );
  325. HAL_DBGMCU_EnableDBGStopMode( );
  326. HAL_DBGMCU_EnableDBGStandbyMode( );
  327. }
  328. void SystemClockConfig( void )
  329. {
  330. RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
  331. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
  332. RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
  333. __HAL_RCC_PWR_CLK_ENABLE( );
  334. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  335. RCC_OscInitStruct = (RCC_OscInitTypeDef){
  336. .OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE,
  337. .HSEState = RCC_HSE_ON,
  338. .LSIState = RCC_LSI_ON,
  339. .PLL.PLLState = RCC_PLL_ON,
  340. .PLL.PLLSource = RCC_PLLSOURCE_HSE,
  341. .PLL.PLLMUL = RCC_PLL_MUL12,
  342. .PLL.PLLDIV = RCC_PLL_DIV3,
  343. };
  344. if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
  345. {
  346. assert_param( LMN_STATUS_ERROR );
  347. }
  348. RCC_ClkInitStruct = (RCC_ClkInitTypeDef){
  349. .ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  350. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2,
  351. .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,
  352. .AHBCLKDivider = RCC_SYSCLK_DIV1,
  353. .APB1CLKDivider = RCC_HCLK_DIV1,
  354. .APB2CLKDivider = RCC_HCLK_DIV1,
  355. };
  356. if( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_1 ) != HAL_OK )
  357. {
  358. assert_param( LMN_STATUS_ERROR );
  359. }
  360. PeriphClkInit = (RCC_PeriphCLKInitTypeDef){
  361. .PeriphClockSelection = RCC_PERIPHCLK_RTC,
  362. .RTCClockSelection = RCC_RTCCLKSOURCE_LSI,
  363. };
  364. if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInit ) != HAL_OK )
  365. {
  366. assert_param( LMN_STATUS_ERROR );
  367. }
  368. HAL_SYSTICK_Config( HAL_RCC_GetHCLKFreq( ) / 1000 );
  369. HAL_SYSTICK_CLKSourceConfig( SYSTICK_CLKSOURCE_HCLK );
  370. // SysTick_IRQn interrupt configuration
  371. HAL_NVIC_SetPriority( SysTick_IRQn, 0, 0 );
  372. }
  373. void SystemClockReConfig( void )
  374. {
  375. __HAL_RCC_PWR_CLK_ENABLE( );
  376. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  377. // Enable HSI
  378. __HAL_RCC_HSI_ENABLE( );
  379. // Wait till HSI is ready
  380. while( __HAL_RCC_GET_FLAG( RCC_FLAG_HSIRDY ) == RESET )
  381. {
  382. }
  383. // Enable PLL
  384. __HAL_RCC_PLL_ENABLE( );
  385. // Wait till PLL is ready
  386. while( __HAL_RCC_GET_FLAG( RCC_FLAG_PLLRDY ) == RESET )
  387. {
  388. }
  389. // Select PLL as system clock source
  390. __HAL_RCC_SYSCLK_CONFIG ( RCC_SYSCLKSOURCE_PLLCLK );
  391. // Wait till PLL is used as system clock source
  392. while( __HAL_RCC_GET_SYSCLK_SOURCE( ) != RCC_SYSCLKSOURCE_STATUS_PLLCLK )
  393. {
  394. }
  395. }
  396. void SysTick_Handler( void )
  397. {
  398. HAL_IncTick( );
  399. HAL_SYSTICK_IRQHandler( );
  400. }
  401. uint8_t GetBoardPowerSource( void )
  402. {
  403. if( UsbIsConnected == false )
  404. {
  405. return BATTERY_POWER;
  406. }
  407. else
  408. {
  409. return USB_POWER;
  410. }
  411. }
  412. /**
  413. * \brief Enters Low Power Stop Mode
  414. *
  415. * \note ARM exists the function when waking up
  416. */
  417. void LpmEnterStopMode( void)
  418. {
  419. CRITICAL_SECTION_BEGIN( );
  420. BoardDeInitMcu( );
  421. // Disable the Power Voltage Detector
  422. HAL_PWR_DisablePVD( );
  423. // Clear wake up flag
  424. SET_BIT( PWR->CR, PWR_CR_CWUF );
  425. // Enable Ultra low power mode
  426. HAL_PWREx_EnableUltraLowPower( );
  427. // Enable the fast wake up from Ultra low power mode
  428. HAL_PWREx_EnableFastWakeUp( );
  429. CRITICAL_SECTION_END( );
  430. // Enter Stop Mode
  431. HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
  432. }
  433. /*!
  434. * \brief Exists Low Power Stop Mode
  435. */
  436. void LpmExitStopMode( void )
  437. {
  438. // Disable IRQ while the MCU is not running on HSI
  439. CRITICAL_SECTION_BEGIN( );
  440. // Initilizes the peripherals
  441. BoardInitMcu( );
  442. CRITICAL_SECTION_END( );
  443. }
  444. /*!
  445. * \brief Enters Low Power Sleep Mode
  446. *
  447. * \note ARM exits the function when waking up
  448. */
  449. void LpmEnterSleepMode( void)
  450. {
  451. HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
  452. }
  453. void BoardLowPowerHandler( void )
  454. {
  455. __disable_irq( );
  456. /*!
  457. * If an interrupt has occurred after __disable_irq( ), it is kept pending
  458. * and cortex will not enter low power anyway
  459. */
  460. LpmEnterLowPower( );
  461. __enable_irq( );
  462. }
  463. #if !defined ( __CC_ARM )
  464. /*
  465. * Function to be used by stdout for printf etc
  466. */
  467. int _write( int fd, const void *buf, size_t count )
  468. {
  469. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
  470. return count;
  471. }
  472. /*
  473. * Function to be used by stdin for scanf etc
  474. */
  475. int _read( int fd, const void *buf, size_t count )
  476. {
  477. size_t bytesRead = 0;
  478. while( UartGetBuffer( &Uart2, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
  479. // Echo back the character
  480. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
  481. return bytesRead;
  482. }
  483. #else
  484. #include <stdio.h>
  485. // Keil compiler
  486. int fputc( int c, FILE *stream )
  487. {
  488. while( UartPutChar( &Uart2, ( uint8_t )c ) != 0 );
  489. return c;
  490. }
  491. int fgetc( FILE *stream )
  492. {
  493. uint8_t c = 0;
  494. while( UartGetChar( &Uart2, &c ) != 0 );
  495. // Echo back the character
  496. while( UartPutChar( &Uart2, c ) != 0 );
  497. return ( int )c;
  498. }
  499. #endif
  500. #ifdef USE_FULL_ASSERT
  501. #include <stdio.h>
  502. /*
  503. * Function Name : assert_failed
  504. * Description : Reports the name of the source file and the source line number
  505. * where the assert_param error has occurred.
  506. * Input : - file: pointer to the source file name
  507. * - line: assert_param error line source number
  508. * Output : None
  509. * Return : None
  510. */
  511. void assert_failed( uint8_t* file, uint32_t line )
  512. {
  513. /* User can add his own implementation to report the file name and line number,
  514. ex: printf("Wrong parameters value: file %s on line %lu\n", file, line) */
  515. printf( "Wrong parameters value: file %s on line %lu\n", ( const char* )file, line );
  516. /* Infinite loop */
  517. while( 1 )
  518. {
  519. }
  520. }
  521. #endif