Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

626 Zeilen
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