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.
 
 
 
 
 
 

666 lines
17 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 "delay.h"
  26. #include "gpio.h"
  27. #include "adc.h"
  28. #include "spi.h"
  29. #include "i2c.h"
  30. #include "uart.h"
  31. #include "timer.h"
  32. #include "gps.h"
  33. #include "mpl3115.h"
  34. #include "mag3110.h"
  35. #include "mma8451.h"
  36. #include "sx9500.h"
  37. #include "sysIrqHandlers.h"
  38. #include "board-config.h"
  39. #include "lpm-board.h"
  40. #include "rtc-board.h"
  41. #include "sx1272-board.h"
  42. #include "board.h"
  43. /*!
  44. * Unique Devices IDs register set ( STM32L152x )
  45. */
  46. #define ID1 ( 0x1FF800D0 )
  47. #define ID2 ( 0x1FF800D4 )
  48. #define ID3 ( 0x1FF800E4 )
  49. /*!
  50. * LED GPIO pins objects
  51. */
  52. Gpio_t LedRed; // Active Low
  53. Gpio_t LedYellow; // Active Low
  54. Gpio_t LedGreen; // Active Low
  55. Gpio_t LedUsr; // Active High
  56. /*!
  57. * PushButton GPIO pin object
  58. */
  59. Gpio_t PushButton;
  60. /*
  61. * MCU objects
  62. */
  63. Adc_t Adc;
  64. I2c_t I2c;
  65. Uart_t Uart1;
  66. Uart_t Uart2;
  67. /*!
  68. * Initializes the unused GPIO to a know status
  69. */
  70. static void BoardUnusedIoInit( void );
  71. /*!
  72. * System Clock Configuration
  73. */
  74. static void SystemClockConfig( void );
  75. /*!
  76. * System Clock Re-Configuration when waking up from STOP mode
  77. */
  78. static void SystemClockReConfig( void );
  79. /*!
  80. * Flag to indicate if the MCU is Initialized
  81. */
  82. static bool McuInitialized = false;
  83. /*!
  84. * Flag used to indicate if board is powered from the USB
  85. */
  86. static bool UsbIsConnected = false;
  87. /*!
  88. * UART2 FIFO buffers size
  89. */
  90. #define UART2_FIFO_TX_SIZE 2048
  91. #define UART2_FIFO_RX_SIZE 2048
  92. uint8_t Uart2TxBuffer[UART2_FIFO_TX_SIZE];
  93. uint8_t Uart2RxBuffer[UART2_FIFO_RX_SIZE];
  94. /*!
  95. * Holds the bord version.
  96. */
  97. static Version_t BoardVersion = { 0 };
  98. void BoardCriticalSectionBegin( uint32_t *mask )
  99. {
  100. *mask = __get_PRIMASK( );
  101. __disable_irq( );
  102. }
  103. void BoardCriticalSectionEnd( uint32_t *mask )
  104. {
  105. __set_PRIMASK( *mask );
  106. }
  107. void BoardInitPeriph( void )
  108. {
  109. Gpio_t ioPin;
  110. // Init the GPIO pins
  111. GpioInit( &LedRed, LED_RED, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  112. GpioInit( &LedYellow, LED_YELLOW, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  113. GpioInit( &LedGreen, LED_GREEN, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  114. GpioInit( &LedUsr, LED_USR, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  115. GpioInit( &PushButton, PC_0, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
  116. GpioInit( &ioPin, IRQ_1_MMA8451, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  117. GpioInit( &ioPin, IRQ_2_MMA8451, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  118. GpioInit( &ioPin, IRQ_MPL3115, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  119. // Init temperature, pressure and altitude sensor
  120. MPL3115Init( );
  121. // Init accelerometer
  122. MMA8451Init( );
  123. // Init SAR
  124. SX9500Init( );
  125. // Init GPS
  126. GpsInit( );
  127. // Switch LED 1, 2, 3, 4 OFF
  128. GpioWrite( &LedRed, 1 );
  129. GpioWrite( &LedYellow, 1 );
  130. GpioWrite( &LedGreen, 1 );
  131. GpioWrite( &LedUsr, 0 );
  132. }
  133. void BoardInitMcu( void )
  134. {
  135. Gpio_t ioPin;
  136. if( McuInitialized == false )
  137. {
  138. HAL_Init( );
  139. SystemClockConfig( );
  140. GpioInit( &ioPin, UART_RX, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  141. if( GpioRead( &ioPin ) == 1 ) // Debug Mode
  142. {
  143. UsbIsConnected = true;
  144. FifoInit( &Uart2.FifoTx, Uart2TxBuffer, UART2_FIFO_TX_SIZE );
  145. FifoInit( &Uart2.FifoRx, Uart2RxBuffer, UART2_FIFO_RX_SIZE );
  146. // Configure your terminal for 8 Bits data (7 data bit + 1 parity bit), no parity and no flow ctrl
  147. UartInit( &Uart2, UART_2, UART_TX, UART_RX );
  148. UartConfig( &Uart2, RX_TX, 921600, UART_8_BIT, UART_1_STOP_BIT, NO_PARITY, NO_FLOW_CTRL );
  149. }
  150. else
  151. {
  152. UsbIsConnected = false;
  153. UartDeInit( &Uart2 );
  154. }
  155. RtcInit( );
  156. BoardUnusedIoInit( );
  157. I2cInit( &I2c, I2C_1, I2C_SCL, I2C_SDA );
  158. if( GetBoardPowerSource( ) == BATTERY_POWER )
  159. {
  160. // Disables OFF mode - Enables lowest power mode (STOP)
  161. LpmSetOffMode( LPM_APPLI_ID, LPM_DISABLE );
  162. }
  163. }
  164. else
  165. {
  166. SystemClockReConfig( );
  167. }
  168. BoardVersion = BoardGetVersion( );
  169. switch( BoardVersion.Fields.Major )
  170. {
  171. case 2:
  172. AdcInit( &Adc, BAT_LEVEL_PIN_PA0 );
  173. break;
  174. case 3:
  175. AdcInit( &Adc, BAT_LEVEL_PIN_PA1 );
  176. break;
  177. default:
  178. break;
  179. }
  180. SpiInit( &SX1272.Spi, SPI_2, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
  181. SX1272IoInit( );
  182. if( McuInitialized == false )
  183. {
  184. McuInitialized = true;
  185. SX1272IoDbgInit( );
  186. SX1272IoTcxoInit( );
  187. }
  188. }
  189. void BoardResetMcu( void )
  190. {
  191. CRITICAL_SECTION_BEGIN( );
  192. //Restart system
  193. NVIC_SystemReset( );
  194. }
  195. void BoardDeInitMcu( void )
  196. {
  197. Gpio_t ioPin;
  198. AdcDeInit( &Adc );
  199. SpiDeInit( &SX1272.Spi );
  200. SX1272IoDeInit( );
  201. GpioInit( &ioPin, OSC_HSE_IN, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  202. GpioInit( &ioPin, OSC_HSE_OUT, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  203. GpioInit( &ioPin, OSC_LSE_IN, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_DOWN, 1 );
  204. GpioInit( &ioPin, OSC_LSE_OUT, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_DOWN, 1 );
  205. }
  206. uint32_t BoardGetRandomSeed( void )
  207. {
  208. return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
  209. }
  210. void BoardGetUniqueId( uint8_t *id )
  211. {
  212. id[7] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 24;
  213. id[6] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 16;
  214. id[5] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 8;
  215. id[4] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) );
  216. id[3] = ( ( *( uint32_t* )ID2 ) ) >> 24;
  217. id[2] = ( ( *( uint32_t* )ID2 ) ) >> 16;
  218. id[1] = ( ( *( uint32_t* )ID2 ) ) >> 8;
  219. id[0] = ( ( *( uint32_t* )ID2 ) );
  220. }
  221. /*!
  222. * Factory power supply
  223. */
  224. #define FACTORY_POWER_SUPPLY 3300 // mV
  225. /*!
  226. * VREF calibration value
  227. */
  228. #define VREFINT_CAL ( *( uint16_t* )0x1FF800F8U )
  229. /*!
  230. * ADC maximum value
  231. */
  232. #define ADC_MAX_VALUE 4095
  233. /*!
  234. * Battery thresholds
  235. */
  236. #define BATTERY_MAX_LEVEL 3700 // mV
  237. #define BATTERY_MIN_LEVEL 1900 // mV
  238. #define BATTERY_SHUTDOWN_LEVEL 1800 // mV
  239. static uint16_t BatteryVoltage = BATTERY_MAX_LEVEL;
  240. uint16_t BoardBatteryMeasureVoltage( void )
  241. {
  242. uint16_t vdd = 0;
  243. uint16_t vref = VREFINT_CAL;
  244. uint16_t vdiv = 0;
  245. uint16_t batteryVoltage = 0;
  246. switch( BoardVersion.Fields.Major )
  247. {
  248. case 2:
  249. vdiv = AdcReadChannel( &Adc, BAT_LEVEL_CHANNEL_PA0 );
  250. break;
  251. case 3:
  252. vdiv = AdcReadChannel( &Adc, BAT_LEVEL_CHANNEL_PA1 );
  253. break;
  254. default:
  255. break;
  256. }
  257. //vref = AdcReadChannel( &Adc, ADC_CHANNEL_VREFINT );
  258. vdd = ( float )FACTORY_POWER_SUPPLY * ( float )VREFINT_CAL / ( float )vref;
  259. batteryVoltage = vdd * ( ( float )vdiv / ( float )ADC_MAX_VALUE );
  260. // vDiv
  261. // Divider bridge VBAT <-> 10k -<--|-->- 10k <-> GND => vBat = 2 * vDiv
  262. batteryVoltage = 2 * batteryVoltage;
  263. return batteryVoltage;
  264. }
  265. uint32_t BoardGetBatteryVoltage( void )
  266. {
  267. return BatteryVoltage;
  268. }
  269. uint8_t BoardGetBatteryLevel( void )
  270. {
  271. uint8_t batteryLevel = 0;
  272. BatteryVoltage = BoardBatteryMeasureVoltage( );
  273. if( GetBoardPowerSource( ) == USB_POWER )
  274. {
  275. batteryLevel = 0;
  276. }
  277. else
  278. {
  279. if( BatteryVoltage >= BATTERY_MAX_LEVEL )
  280. {
  281. batteryLevel = 254;
  282. }
  283. else if( ( BatteryVoltage > BATTERY_MIN_LEVEL ) && ( BatteryVoltage < BATTERY_MAX_LEVEL ) )
  284. {
  285. batteryLevel = ( ( 253 * ( BatteryVoltage - BATTERY_MIN_LEVEL ) ) / ( BATTERY_MAX_LEVEL - BATTERY_MIN_LEVEL ) ) + 1;
  286. }
  287. else if( ( BatteryVoltage > BATTERY_SHUTDOWN_LEVEL ) && ( BatteryVoltage <= BATTERY_MIN_LEVEL ) )
  288. {
  289. batteryLevel = 1;
  290. }
  291. else //if( BatteryVoltage <= BATTERY_SHUTDOWN_LEVEL )
  292. {
  293. batteryLevel = 255;
  294. }
  295. }
  296. return batteryLevel;
  297. }
  298. static void BoardUnusedIoInit( void )
  299. {
  300. Gpio_t ioPin;
  301. if( GetBoardPowerSource( ) == USB_POWER )
  302. {
  303. HAL_DBGMCU_EnableDBGStopMode( );
  304. HAL_DBGMCU_EnableDBGSleepMode( );
  305. HAL_DBGMCU_EnableDBGStandbyMode( );
  306. }
  307. else
  308. {
  309. GpioInit( &ioPin, USB_DM, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  310. GpioInit( &ioPin, USB_DP, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  311. HAL_DBGMCU_DisableDBGSleepMode( );
  312. HAL_DBGMCU_DisableDBGStopMode( );
  313. HAL_DBGMCU_DisableDBGStandbyMode( );
  314. GpioInit( &ioPin, JTAG_TMS, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  315. GpioInit( &ioPin, JTAG_TCK, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  316. GpioInit( &ioPin, JTAG_TDI, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  317. GpioInit( &ioPin, JTAG_TDO, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  318. GpioInit( &ioPin, JTAG_NRST, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  319. }
  320. GpioInit( &ioPin, BOOT_1, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  321. switch( BoardVersion.Fields.Major )
  322. {
  323. case 2:
  324. GpioInit( &ioPin, BAT_LEVEL_PIN_PA0, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  325. break;
  326. case 3:
  327. GpioInit( &ioPin, BAT_LEVEL_PIN_PA1, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  328. break;
  329. default:
  330. break;
  331. }
  332. }
  333. Version_t BoardGetVersion( void )
  334. {
  335. Gpio_t pinPc1;
  336. Gpio_t pinPc7;
  337. Version_t boardVersion = { 0 };
  338. boardVersion.Value = 0;
  339. GpioInit( &pinPc1, BOARD_VERSION_PC1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  340. GpioInit( &pinPc7, BOARD_VERSION_PC7, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  341. uint8_t first = GpioRead( &pinPc1 );
  342. GpioWrite( &pinPc7, 0 );
  343. if( first && !GpioRead( &pinPc1 ) )
  344. {
  345. boardVersion.Fields.Major = 2;
  346. }
  347. else
  348. {
  349. boardVersion.Fields.Major = 3;
  350. }
  351. return boardVersion;
  352. }
  353. void SystemClockConfig( void )
  354. {
  355. RCC_OscInitTypeDef RCC_OscInitStruct;
  356. RCC_ClkInitTypeDef RCC_ClkInitStruct;
  357. RCC_PeriphCLKInitTypeDef PeriphClkInit;
  358. __HAL_RCC_PWR_CLK_ENABLE( );
  359. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  360. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSE;
  361. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  362. RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  363. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  364. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  365. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  366. RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
  367. if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
  368. {
  369. assert_param( LMN_STATUS_ERROR );
  370. }
  371. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
  372. RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  373. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  374. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  375. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  376. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  377. if( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_1 ) != HAL_OK )
  378. {
  379. assert_param( LMN_STATUS_ERROR );
  380. }
  381. PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  382. PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  383. if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInit ) != HAL_OK )
  384. {
  385. assert_param( LMN_STATUS_ERROR );
  386. }
  387. HAL_SYSTICK_Config( HAL_RCC_GetHCLKFreq( ) / 1000 );
  388. HAL_SYSTICK_CLKSourceConfig( SYSTICK_CLKSOURCE_HCLK );
  389. // SysTick_IRQn interrupt configuration
  390. HAL_NVIC_SetPriority( SysTick_IRQn, 0, 0 );
  391. }
  392. void SystemClockReConfig( void )
  393. {
  394. __HAL_RCC_PWR_CLK_ENABLE( );
  395. __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
  396. // Enable HSE
  397. __HAL_RCC_HSE_CONFIG( RCC_HSE_ON );
  398. // Wait till HSE is ready
  399. while( __HAL_RCC_GET_FLAG( RCC_FLAG_HSERDY ) == RESET )
  400. {
  401. }
  402. // Enable PLL
  403. __HAL_RCC_PLL_ENABLE( );
  404. // Wait till PLL is ready
  405. while( __HAL_RCC_GET_FLAG( RCC_FLAG_PLLRDY ) == RESET )
  406. {
  407. }
  408. // Select PLL as system clock source
  409. __HAL_RCC_SYSCLK_CONFIG ( RCC_SYSCLKSOURCE_PLLCLK );
  410. // Wait till PLL is used as system clock source
  411. while( __HAL_RCC_GET_SYSCLK_SOURCE( ) != RCC_SYSCLKSOURCE_STATUS_PLLCLK )
  412. {
  413. }
  414. }
  415. void SysTick_Handler( void )
  416. {
  417. HAL_IncTick( );
  418. HAL_SYSTICK_IRQHandler( );
  419. }
  420. uint8_t GetBoardPowerSource( void )
  421. {
  422. if( UsbIsConnected == false )
  423. {
  424. return BATTERY_POWER;
  425. }
  426. else
  427. {
  428. return USB_POWER;
  429. }
  430. }
  431. /**
  432. * \brief Enters Low Power Stop Mode
  433. *
  434. * \note ARM exists the function when waking up
  435. */
  436. void LpmEnterStopMode( void)
  437. {
  438. CRITICAL_SECTION_BEGIN( );
  439. BoardDeInitMcu( );
  440. // Disable the Power Voltage Detector
  441. HAL_PWR_DisablePVD( );
  442. // Clear wake up flag
  443. SET_BIT( PWR->CR, PWR_CR_CWUF );
  444. // Enable Ultra low power mode
  445. HAL_PWREx_EnableUltraLowPower( );
  446. // Enable the fast wake up from Ultra low power mode
  447. HAL_PWREx_EnableFastWakeUp( );
  448. CRITICAL_SECTION_END( );
  449. // Enter Stop Mode
  450. HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
  451. }
  452. /*!
  453. * \brief Exists Low Power Stop Mode
  454. */
  455. void LpmExitStopMode( void )
  456. {
  457. // Disable IRQ while the MCU is not running on HSI
  458. CRITICAL_SECTION_BEGIN( );
  459. // Initializes the peripherals
  460. BoardInitMcu( );
  461. CRITICAL_SECTION_END( );
  462. }
  463. /*!
  464. * \brief Enters Low Power Sleep Mode
  465. *
  466. * \note ARM exits the function when waking up
  467. */
  468. void LpmEnterSleepMode( void)
  469. {
  470. #ifndef DEBUG
  471. /*!
  472. * Temporarily remove the following call when compiling in debug mode.
  473. *
  474. * Due to an yet unknown reason the PWR_MAINREGULATOR_ON constant gets
  475. * changed inside the function which makes the assert fail.
  476. *
  477. * When compiling in release mode the code operates as expected.
  478. *
  479. * TODO: Check what causes this issue. First guess is that the stack gets
  480. * corrupted somehow.
  481. *
  482. * This function is only called when using the GPS peripheral.
  483. */
  484. HAL_PWR_EnterSLEEPMode( PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI );
  485. #endif
  486. }
  487. void BoardLowPowerHandler( void )
  488. {
  489. __disable_irq( );
  490. /*!
  491. * If an interrupt has occurred after __disable_irq( ), it is kept pending
  492. * and cortex will not enter low power anyway
  493. */
  494. LpmEnterLowPower( );
  495. __enable_irq( );
  496. }
  497. #if !defined ( __CC_ARM )
  498. /*
  499. * Function to be used by stdout for printf etc
  500. */
  501. int _write( int fd, const void *buf, size_t count )
  502. {
  503. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
  504. return count;
  505. }
  506. /*
  507. * Function to be used by stdin for scanf etc
  508. */
  509. int _read( int fd, const void *buf, size_t count )
  510. {
  511. size_t bytesRead = 0;
  512. while( UartGetBuffer( &Uart2, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
  513. // Echo back the character
  514. while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
  515. return bytesRead;
  516. }
  517. #else
  518. #include <stdio.h>
  519. // Keil compiler
  520. int fputc( int c, FILE *stream )
  521. {
  522. while( UartPutChar( &Uart2, ( uint8_t )c ) != 0 );
  523. return c;
  524. }
  525. int fgetc( FILE *stream )
  526. {
  527. uint8_t c = 0;
  528. while( UartGetChar( &Uart2, &c ) != 0 );
  529. // Echo back the character
  530. while( UartPutChar( &Uart2, c ) != 0 );
  531. return ( int )c;
  532. }
  533. #endif
  534. #ifdef USE_FULL_ASSERT
  535. #include <stdio.h>
  536. /*
  537. * Function Name : assert_failed
  538. * Description : Reports the name of the source file and the source line number
  539. * where the assert_param error has occurred.
  540. * Input : - file: pointer to the source file name
  541. * - line: assert_param error line source number
  542. * Output : None
  543. * Return : None
  544. */
  545. void assert_failed( uint8_t* file, uint32_t line )
  546. {
  547. /* User can add his own implementation to report the file name and line number,
  548. ex: printf("Wrong parameters value: file %s on line %lu\n", file, line) */
  549. printf( "Wrong parameters value: file %s on line %lu\n", ( const char* )file, line );
  550. /* Infinite loop */
  551. while( 1 )
  552. {
  553. }
  554. }
  555. #endif