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.
 
 
 
 
 
 

626 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 <sysinit.h>
  46. #include <usb_device.h>
  47. /*!
  48. * Unique Devices IDs register set ( STM32L152x )
  49. */
  50. #define ID1 ( 0x1FF800D0 )
  51. #define ID2 ( 0x1FF800D4 )
  52. #define ID3 ( 0x1FF800E4 )
  53. /*!
  54. * LED GPIO pins objects
  55. */
  56. Gpio_t Led1;
  57. Gpio_t Led2;
  58. /*
  59. * MCU objects
  60. */
  61. Adc_t Adc;
  62. Uart_t Uart2;
  63. #if defined( LR1110MB1XXS )
  64. extern lr1110_t LR1110;
  65. #endif
  66. /*!
  67. * Initializes the unused GPIO to a know status
  68. */
  69. static void BoardUnusedIoInit( void );
  70. /*!
  71. * System Clock Configuration
  72. */
  73. static void SystemClockConfig( void );
  74. /*!
  75. * System Clock Re-Configuration when waking up from STOP mode
  76. */
  77. static void SystemClockReConfig( void );
  78. /*!
  79. * Flag to indicate if the MCU is Initialized
  80. */
  81. static bool McuInitialized = false;
  82. /*!
  83. * Flag used to indicate if board is powered from the USB
  84. */
  85. static bool UsbIsConnected = false;
  86. /*!
  87. * UART2 FIFO buffers size
  88. */
  89. #define UART2_FIFO_TX_SIZE 1024
  90. #define UART2_FIFO_RX_SIZE 1024
  91. uint8_t Uart2TxBuffer[UART2_FIFO_TX_SIZE];
  92. uint8_t Uart2RxBuffer[UART2_FIFO_RX_SIZE];
  93. void BoardCriticalSectionBegin( uint32_t *mask )
  94. {
  95. *mask = __get_PRIMASK( );
  96. __disable_irq( );
  97. }
  98. void BoardCriticalSectionEnd( uint32_t *mask )
  99. {
  100. __set_PRIMASK( *mask );
  101. }
  102. void BoardInitPeriph( void )
  103. {
  104. }
  105. void BoardInitMcu( void )
  106. {
  107. if( McuInitialized == false )
  108. {
  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. AdcInit( &Adc, PB_15 ); // Just initialize ADC
  166. /* setup routing */
  167. __HAL_RI_IOSWITCH_CLOSE(RI_IOSWITCH_CH21);
  168. __HAL_RI_SWITCHCONTROLMODE_ENABLE();
  169. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  170. SpiInit( &SX126x.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  171. SX126xIoInit( );
  172. #elif defined( LR1110MB1XXS )
  173. SpiInit( &LR1110.spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  174. lr1110_board_init_io( &LR1110 );
  175. #elif defined( SX1272MB2DAS )
  176. SpiInit( &SX1272.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  177. SX1272IoInit( );
  178. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  179. SpiInit( &SX1276.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  180. SX1276IoInit( );
  181. #endif
  182. if( McuInitialized == false )
  183. {
  184. McuInitialized = true;
  185. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  186. SX126xIoDbgInit( );
  187. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  188. #elif defined( LR1110MB1XXS )
  189. lr1110_board_init_dbg_io( &LR1110 );
  190. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  191. #elif defined( SX1272MB2DAS )
  192. SX1272IoDbgInit( );
  193. SX1272IoTcxoInit( );
  194. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  195. SX1276IoDbgInit( );
  196. SX1276IoTcxoInit( );
  197. #endif
  198. }
  199. }
  200. SYSINIT_VF(initmcu, SI_SUB_HAL, SI_ORDER_SECOND, BoardInitMcu);
  201. void BoardResetMcu( void )
  202. {
  203. CRITICAL_SECTION_BEGIN( );
  204. //Restart system
  205. NVIC_SystemReset( );
  206. }
  207. void BoardDeInitMcu( void )
  208. {
  209. AdcDeInit( &Adc );
  210. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  211. SpiDeInit( &SX126x.Spi );
  212. SX126xIoDeInit( );
  213. #elif defined( LR1110MB1XXS )
  214. SpiDeInit( &LR1110.spi );
  215. lr1110_board_deinit_io( &LR1110 );
  216. #elif defined( SX1272MB2DAS )
  217. SpiDeInit( &SX1272.Spi );
  218. SX1272IoDeInit( );
  219. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  220. SpiDeInit( &SX1276.Spi );
  221. SX1276IoDeInit( );
  222. #endif
  223. }
  224. uint32_t BoardGetRandomSeed( void )
  225. {
  226. return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
  227. }
  228. void BoardGetUniqueId( uint8_t *id )
  229. {
  230. id[7] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 24;
  231. id[6] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 16;
  232. id[5] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 8;
  233. id[4] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) );
  234. id[3] = ( ( *( uint32_t* )ID2 ) ) >> 24;
  235. id[2] = ( ( *( uint32_t* )ID2 ) ) >> 16;
  236. id[1] = ( ( *( uint32_t* )ID2 ) ) >> 8;
  237. id[0] = ( ( *( uint32_t* )ID2 ) );
  238. }
  239. /*!
  240. * Factory power supply
  241. */
  242. #define VDDA_VREFINT_CAL ( ( uint32_t ) 3000 ) // mV
  243. /*!
  244. * VREF calibration value
  245. */
  246. #define VREFINT_CAL ( *( uint16_t* ) ( ( uint32_t ) 0x1FF800F8 ) )
  247. /*
  248. * Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at
  249. * a temperature of 110 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV).
  250. */
  251. #define TEMP30_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FF8007A ) )
  252. /* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at
  253. *a temperature of 30 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
  254. #define TEMP110_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FF8007E ) )
  255. /* Vdda value with which temperature sensor has been calibrated in production
  256. (+-10 mV). */
  257. #define VDDA_TEMP_CAL ( ( uint32_t ) 3000 )
  258. /*!
  259. * Battery thresholds
  260. */
  261. #define BATTERY_MAX_LEVEL 3000 // mV
  262. #define BATTERY_MIN_LEVEL 2400 // mV
  263. #define BATTERY_SHUTDOWN_LEVEL 2300 // mV
  264. #define BATTERY_LORAWAN_UNKNOWN_LEVEL 255
  265. #define BATTERY_LORAWAN_MAX_LEVEL 254
  266. #define BATTERY_LORAWAN_MIN_LEVEL 1
  267. #define BATTERY_LORAWAN_EXT_PWR 0
  268. #define COMPUTE_TEMPERATURE( TS_ADC_DATA, VDDA_APPLI ) \
  269. ( ( ( ( ( ( ( int32_t )( ( TS_ADC_DATA * VDDA_APPLI ) / VDDA_TEMP_CAL ) - ( int32_t ) TEMP30_CAL_ADDR ) ) * \
  270. ( int32_t )( 110 - 30 ) ) \
  271. << 8 ) / \
  272. ( int32_t )( TEMP110_CAL_ADDR - TEMP30_CAL_ADDR ) ) + \
  273. ( 30 << 8 ) )
  274. static uint16_t BatteryVoltage = BATTERY_MAX_LEVEL;
  275. uint16_t BoardBatteryMeasureVoltage( void )
  276. {
  277. uint16_t vref = 0;
  278. // Read the current Voltage
  279. vref = AdcReadChannel( &Adc, ADC_CHANNEL_VREFINT );
  280. // Compute and return the Voltage in millivolt
  281. return ( ( ( uint32_t ) VDDA_VREFINT_CAL * VREFINT_CAL ) / vref );
  282. }
  283. uint32_t BoardGetBatteryVoltage( void )
  284. {
  285. return BatteryVoltage;
  286. }
  287. uint8_t BoardGetBatteryLevel( void )
  288. {
  289. uint8_t batteryLevel = 0;
  290. BatteryVoltage = BoardBatteryMeasureVoltage( );
  291. if( GetBoardPowerSource( ) == USB_POWER )
  292. {
  293. batteryLevel = BATTERY_LORAWAN_EXT_PWR;
  294. }
  295. else
  296. {
  297. if( BatteryVoltage >= BATTERY_MAX_LEVEL )
  298. {
  299. batteryLevel = BATTERY_LORAWAN_MAX_LEVEL;
  300. }
  301. else if( ( BatteryVoltage > BATTERY_MIN_LEVEL ) && ( BatteryVoltage < BATTERY_MAX_LEVEL ) )
  302. {
  303. batteryLevel =
  304. ( ( 253 * ( BatteryVoltage - BATTERY_MIN_LEVEL ) ) / ( BATTERY_MAX_LEVEL - BATTERY_MIN_LEVEL ) ) + 1;
  305. }
  306. else if( ( BatteryVoltage > BATTERY_SHUTDOWN_LEVEL ) && ( BatteryVoltage <= BATTERY_MIN_LEVEL ) )
  307. {
  308. batteryLevel = 1;
  309. }
  310. else // if( BatteryVoltage <= BATTERY_SHUTDOWN_LEVEL )
  311. {
  312. batteryLevel = BATTERY_LORAWAN_UNKNOWN_LEVEL;
  313. }
  314. }
  315. return batteryLevel;
  316. }
  317. int16_t BoardGetTemperature( void )
  318. {
  319. uint16_t tempRaw = 0;
  320. BatteryVoltage = BoardBatteryMeasureVoltage( );
  321. tempRaw = AdcReadChannel( &Adc, ADC_CHANNEL_TEMPSENSOR );
  322. // Compute and return the temperature in degree celcius * 256
  323. return ( int16_t ) COMPUTE_TEMPERATURE( tempRaw, BatteryVoltage );
  324. }
  325. static void BoardUnusedIoInit( void )
  326. {
  327. HAL_DBGMCU_EnableDBGSleepMode( );
  328. HAL_DBGMCU_EnableDBGStopMode( );
  329. HAL_DBGMCU_EnableDBGStandbyMode( );
  330. }
  331. void SystemClockConfig( void )
  332. {
  333. RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
  334. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
  335. RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
  336. __HAL_RCC_PWR_CLK_ENABLE( );
  337. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  338. RCC_OscInitStruct = (RCC_OscInitTypeDef){
  339. .OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE,
  340. .HSEState = RCC_HSE_ON,
  341. .LSIState = RCC_LSI_ON,
  342. .PLL.PLLState = RCC_PLL_ON,
  343. .PLL.PLLSource = RCC_PLLSOURCE_HSE,
  344. .PLL.PLLMUL = RCC_PLL_MUL12,
  345. .PLL.PLLDIV = RCC_PLL_DIV3,
  346. };
  347. if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
  348. {
  349. assert_param( LMN_STATUS_ERROR );
  350. }
  351. RCC_ClkInitStruct = (RCC_ClkInitTypeDef){
  352. .ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  353. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2,
  354. .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,
  355. .AHBCLKDivider = RCC_SYSCLK_DIV1,
  356. .APB1CLKDivider = RCC_HCLK_DIV1,
  357. .APB2CLKDivider = RCC_HCLK_DIV1,
  358. };
  359. if( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_1 ) != HAL_OK )
  360. {
  361. assert_param( LMN_STATUS_ERROR );
  362. }
  363. PeriphClkInit = (RCC_PeriphCLKInitTypeDef){
  364. .PeriphClockSelection = RCC_PERIPHCLK_RTC,
  365. .RTCClockSelection = RCC_RTCCLKSOURCE_LSI,
  366. };
  367. if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInit ) != HAL_OK )
  368. {
  369. assert_param( LMN_STATUS_ERROR );
  370. }
  371. HAL_SYSTICK_Config( HAL_RCC_GetHCLKFreq( ) / 1000 );
  372. HAL_SYSTICK_CLKSourceConfig( SYSTICK_CLKSOURCE_HCLK );
  373. // SysTick_IRQn interrupt configuration
  374. HAL_NVIC_SetPriority( SysTick_IRQn, 0, 0 );
  375. }
  376. void SystemClockReConfig( void )
  377. {
  378. __HAL_RCC_PWR_CLK_ENABLE( );
  379. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  380. // Enable HSI
  381. __HAL_RCC_HSI_ENABLE( );
  382. // Wait till HSI is ready
  383. while( __HAL_RCC_GET_FLAG( RCC_FLAG_HSIRDY ) == RESET )
  384. {
  385. }
  386. // Enable PLL
  387. __HAL_RCC_PLL_ENABLE( );
  388. // Wait till PLL is ready
  389. while( __HAL_RCC_GET_FLAG( RCC_FLAG_PLLRDY ) == RESET )
  390. {
  391. }
  392. // Select PLL as system clock source
  393. __HAL_RCC_SYSCLK_CONFIG ( RCC_SYSCLKSOURCE_PLLCLK );
  394. // Wait till PLL is used as system clock source
  395. while( __HAL_RCC_GET_SYSCLK_SOURCE( ) != RCC_SYSCLKSOURCE_STATUS_PLLCLK )
  396. {
  397. }
  398. }
  399. uint8_t GetBoardPowerSource( void )
  400. {
  401. if( UsbIsConnected == false )
  402. {
  403. return BATTERY_POWER;
  404. }
  405. else
  406. {
  407. return USB_POWER;
  408. }
  409. }
  410. /**
  411. * \brief Enters Low Power Stop Mode
  412. *
  413. * \note ARM exists the function when waking up
  414. */
  415. void LpmEnterStopMode( void)
  416. {
  417. CRITICAL_SECTION_BEGIN( );
  418. BoardDeInitMcu( );
  419. // Disable the Power Voltage Detector
  420. HAL_PWR_DisablePVD( );
  421. // Clear wake up flag
  422. SET_BIT( PWR->CR, PWR_CR_CWUF );
  423. // Enable Ultra low power mode
  424. HAL_PWREx_EnableUltraLowPower( );
  425. // Enable the fast wake up from Ultra low power mode
  426. HAL_PWREx_EnableFastWakeUp( );
  427. CRITICAL_SECTION_END( );
  428. // Enter Stop Mode
  429. HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
  430. }
  431. /*!
  432. * \brief Exists Low Power Stop Mode
  433. */
  434. void LpmExitStopMode( void )
  435. {
  436. // Disable IRQ while the MCU is not running on HSI
  437. CRITICAL_SECTION_BEGIN( );
  438. // Initilizes the peripherals
  439. BoardInitMcu( );
  440. CRITICAL_SECTION_END( );
  441. }
  442. /*!
  443. * \brief Enters Low Power Sleep Mode
  444. *
  445. * \note ARM exits the function when waking up
  446. */
  447. void LpmEnterSleepMode( void)
  448. {
  449. HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
  450. }
  451. void BoardLowPowerHandler( void )
  452. {
  453. __disable_irq( );
  454. /*!
  455. * If an interrupt has occurred after __disable_irq( ), it is kept pending
  456. * and cortex will not enter low power anyway
  457. */
  458. LpmEnterLowPower( );
  459. __enable_irq( );
  460. }
  461. #if !defined ( __CC_ARM )
  462. /*
  463. * Function to be used by stdout for printf etc
  464. */
  465. int _write( int fd, const void *buf, size_t count )
  466. {
  467. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
  468. return count;
  469. }
  470. /*
  471. * Function to be used by stdin for scanf etc
  472. */
  473. int _read( int fd, const void *buf, size_t count )
  474. {
  475. size_t bytesRead = 0;
  476. while( UartGetBuffer( &Uart2, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
  477. // Echo back the character
  478. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
  479. return bytesRead;
  480. }
  481. #else
  482. #include <stdio.h>
  483. // Keil compiler
  484. int fputc( int c, FILE *stream )
  485. {
  486. while( UartPutChar( &Uart2, ( uint8_t )c ) != 0 );
  487. return c;
  488. }
  489. int fgetc( FILE *stream )
  490. {
  491. uint8_t c = 0;
  492. while( UartGetChar( &Uart2, &c ) != 0 );
  493. // Echo back the character
  494. while( UartPutChar( &Uart2, c ) != 0 );
  495. return ( int )c;
  496. }
  497. #endif
  498. #ifdef USE_FULL_ASSERT
  499. #include <stdio.h>
  500. /*
  501. * Function Name : assert_failed
  502. * Description : Reports the name of the source file and the source line number
  503. * where the assert_param error has occurred.
  504. * Input : - file: pointer to the source file name
  505. * - line: assert_param error line source number
  506. * Output : None
  507. * Return : None
  508. */
  509. void assert_failed( uint8_t* file, uint32_t line )
  510. {
  511. /* User can add his own implementation to report the file name and line number,
  512. ex: printf("Wrong parameters value: file %s on line %lu\n", file, line) */
  513. printf( "Wrong parameters value: file %s on line %lu\n", ( const char* )file, line );
  514. /* Infinite loop */
  515. while( 1 )
  516. {
  517. }
  518. }
  519. #endif