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.
 
 
 
 
 
 

633 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. /* setup routing */
  168. __HAL_RI_IOSWITCH_CLOSE(RI_IOSWITCH_CH21);
  169. __HAL_RI_SWITCHCONTROLMODE_ENABLE();
  170. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  171. SpiInit( &SX126x.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  172. SX126xIoInit( );
  173. #elif defined( LR1110MB1XXS )
  174. SpiInit( &LR1110.spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  175. lr1110_board_init_io( &LR1110 );
  176. #elif defined( SX1272MB2DAS )
  177. SpiInit( &SX1272.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  178. SX1272IoInit( );
  179. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  180. SpiInit( &SX1276.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  181. SX1276IoInit( );
  182. #endif
  183. if( McuInitialized == false )
  184. {
  185. McuInitialized = true;
  186. #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
  187. SX126xIoDbgInit( );
  188. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  189. #elif defined( LR1110MB1XXS )
  190. lr1110_board_init_dbg_io( &LR1110 );
  191. // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
  192. #elif defined( SX1272MB2DAS )
  193. SX1272IoDbgInit( );
  194. SX1272IoTcxoInit( );
  195. #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
  196. SX1276IoDbgInit( );
  197. SX1276IoTcxoInit( );
  198. #endif
  199. }
  200. }
  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. void SysTick_Handler( void )
  400. {
  401. HAL_IncTick( );
  402. HAL_SYSTICK_IRQHandler( );
  403. }
  404. uint8_t GetBoardPowerSource( void )
  405. {
  406. if( UsbIsConnected == false )
  407. {
  408. return BATTERY_POWER;
  409. }
  410. else
  411. {
  412. return USB_POWER;
  413. }
  414. }
  415. /**
  416. * \brief Enters Low Power Stop Mode
  417. *
  418. * \note ARM exists the function when waking up
  419. */
  420. void LpmEnterStopMode( void)
  421. {
  422. CRITICAL_SECTION_BEGIN( );
  423. BoardDeInitMcu( );
  424. // Disable the Power Voltage Detector
  425. HAL_PWR_DisablePVD( );
  426. // Clear wake up flag
  427. SET_BIT( PWR->CR, PWR_CR_CWUF );
  428. // Enable Ultra low power mode
  429. HAL_PWREx_EnableUltraLowPower( );
  430. // Enable the fast wake up from Ultra low power mode
  431. HAL_PWREx_EnableFastWakeUp( );
  432. CRITICAL_SECTION_END( );
  433. // Enter Stop Mode
  434. HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
  435. }
  436. /*!
  437. * \brief Exists Low Power Stop Mode
  438. */
  439. void LpmExitStopMode( void )
  440. {
  441. // Disable IRQ while the MCU is not running on HSI
  442. CRITICAL_SECTION_BEGIN( );
  443. // Initilizes the peripherals
  444. BoardInitMcu( );
  445. CRITICAL_SECTION_END( );
  446. }
  447. /*!
  448. * \brief Enters Low Power Sleep Mode
  449. *
  450. * \note ARM exits the function when waking up
  451. */
  452. void LpmEnterSleepMode( void)
  453. {
  454. HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
  455. }
  456. void BoardLowPowerHandler( void )
  457. {
  458. __disable_irq( );
  459. /*!
  460. * If an interrupt has occurred after __disable_irq( ), it is kept pending
  461. * and cortex will not enter low power anyway
  462. */
  463. LpmEnterLowPower( );
  464. __enable_irq( );
  465. }
  466. #if !defined ( __CC_ARM )
  467. /*
  468. * Function to be used by stdout for printf etc
  469. */
  470. int _write( int fd, const void *buf, size_t count )
  471. {
  472. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
  473. return count;
  474. }
  475. /*
  476. * Function to be used by stdin for scanf etc
  477. */
  478. int _read( int fd, const void *buf, size_t count )
  479. {
  480. size_t bytesRead = 0;
  481. while( UartGetBuffer( &Uart2, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
  482. // Echo back the character
  483. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
  484. return bytesRead;
  485. }
  486. #else
  487. #include <stdio.h>
  488. // Keil compiler
  489. int fputc( int c, FILE *stream )
  490. {
  491. while( UartPutChar( &Uart2, ( uint8_t )c ) != 0 );
  492. return c;
  493. }
  494. int fgetc( FILE *stream )
  495. {
  496. uint8_t c = 0;
  497. while( UartGetChar( &Uart2, &c ) != 0 );
  498. // Echo back the character
  499. while( UartPutChar( &Uart2, c ) != 0 );
  500. return ( int )c;
  501. }
  502. #endif
  503. #ifdef USE_FULL_ASSERT
  504. #include <stdio.h>
  505. /*
  506. * Function Name : assert_failed
  507. * Description : Reports the name of the source file and the source line number
  508. * where the assert_param error has occurred.
  509. * Input : - file: pointer to the source file name
  510. * - line: assert_param error line source number
  511. * Output : None
  512. * Return : None
  513. */
  514. void assert_failed( uint8_t* file, uint32_t line )
  515. {
  516. /* User can add his own implementation to report the file name and line number,
  517. ex: printf("Wrong parameters value: file %s on line %lu\n", file, line) */
  518. printf( "Wrong parameters value: file %s on line %lu\n", ( const char* )file, line );
  519. /* Infinite loop */
  520. while( 1 )
  521. {
  522. }
  523. }
  524. #endif