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