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