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 "stm32l4xx.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
36 #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
37 #include "sx126x-board.h"
38 #elif defined( LR1110MB1XXS )
39 #include "lr1110-board.h"
40 #elif defined( SX1272MB2DAS)
41 #include "sx1272-board.h"
42 #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
43 #include "sx1276-board.h"
44 #endif
45 #include "board.h"
46
47 /*!
48 * Unique Devices IDs register set ( STM32L4xxx )
49 */
50 #define ID1 ( 0x1FFF7590 )
51 #define ID2 ( 0x1FFF7594 )
52 #define ID3 ( 0x1FFF7594 )
53
54 /*!
55 * LED GPIO pins objects
56 */
57 Gpio_t Led1;
58 Gpio_t Led2;
59
60 /*
61 * MCU objects
62 */
63 Adc_t Adc;
64 Uart_t Uart2;
65
66 #if defined( LR1110MB1XXS )
67 extern lr1110_t LR1110;
68 #endif
69
70 /*!
71 * Initializes the unused GPIO to a know status
72 */
73 static void BoardUnusedIoInit( void );
74
75 /*!
76 * Initializes FLASH memory operations for EEPROM_Emul package
77 */
78 static void InitFlashMemoryOperations( void );
79
80 /*!
81 * System Clock Configuration
82 */
83 static void SystemClockConfig( void );
84
85 /*!
86 * System Clock Re-Configuration when waking up from STOP mode
87 */
88 static void SystemClockReConfig( void );
89
90 /*!
91 * Flag to indicate if the MCU is Initialized
92 */
93 static bool McuInitialized = false;
94
95 /*!
96 * Flag used to indicate if board is powered from the USB
97 */
98 static bool UsbIsConnected = false;
99
100 /*!
101 * UART2 FIFO buffers size
102 */
103 #define UART2_FIFO_TX_SIZE 1024
104 #define UART2_FIFO_RX_SIZE 1024
105
106 uint8_t Uart2TxBuffer[UART2_FIFO_TX_SIZE];
107 uint8_t Uart2RxBuffer[UART2_FIFO_RX_SIZE];
108
BoardCriticalSectionBegin(uint32_t * mask)109 void BoardCriticalSectionBegin( uint32_t *mask )
110 {
111 *mask = __get_PRIMASK( );
112 __disable_irq( );
113 }
114
BoardCriticalSectionEnd(uint32_t * mask)115 void BoardCriticalSectionEnd( uint32_t *mask )
116 {
117 __set_PRIMASK( *mask );
118 }
119
BoardInitPeriph(void)120 void BoardInitPeriph( void )
121 {
122
123 }
124
BoardInitMcu(void)125 void BoardInitMcu( void )
126 {
127 if( McuInitialized == false )
128 {
129 HAL_Init( );
130
131 InitFlashMemoryOperations( );
132
133 // LEDs
134 GpioInit( &Led1, LED_1, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
135 GpioInit( &Led2, LED_2, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
136
137 SystemClockConfig( );
138
139 UsbIsConnected = true;
140
141 FifoInit( &Uart2.FifoTx, Uart2TxBuffer, UART2_FIFO_TX_SIZE );
142 FifoInit( &Uart2.FifoRx, Uart2RxBuffer, UART2_FIFO_RX_SIZE );
143 // Configure your terminal for 8 Bits data (7 data bit + 1 parity bit), no parity and no flow ctrl
144 UartInit( &Uart2, UART_2, UART_TX, UART_RX );
145 UartConfig( &Uart2, RX_TX, 921600, UART_8_BIT, UART_1_STOP_BIT, NO_PARITY, NO_FLOW_CTRL );
146
147 RtcInit( );
148
149 BoardUnusedIoInit( );
150 if( GetBoardPowerSource( ) == BATTERY_POWER )
151 {
152 // Disables OFF mode - Enables lowest power mode (STOP)
153 LpmSetOffMode( LPM_APPLI_ID, LPM_DISABLE );
154 }
155 }
156 else
157 {
158 SystemClockReConfig( );
159 }
160
161 AdcInit( &Adc, NC ); // Just initialize ADC
162
163 #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
164 SpiInit( &SX126x.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
165 SX126xIoInit( );
166 #elif defined( LR1110MB1XXS )
167 SpiInit( &LR1110.spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
168 lr1110_board_init_io( &LR1110 );
169 #elif defined( SX1272MB2DAS )
170 SpiInit( &SX1272.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
171 SX1272IoInit( );
172 #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
173 SpiInit( &SX1276.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
174 SX1276IoInit( );
175 #endif
176
177 if( McuInitialized == false )
178 {
179 McuInitialized = true;
180 #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
181 SX126xIoDbgInit( );
182 // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
183 #elif defined( LR1110MB1XXS )
184 lr1110_board_init_dbg_io( &LR1110 );
185 // WARNING: If necessary the TCXO control is initialized by SX126xInit function.
186 #elif defined( SX1272MB2DAS )
187 SX1272IoDbgInit( );
188 SX1272IoTcxoInit( );
189 #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
190 SX1276IoDbgInit( );
191 SX1276IoTcxoInit( );
192 #endif
193 }
194 }
195
BoardResetMcu(void)196 void BoardResetMcu( void )
197 {
198 CRITICAL_SECTION_BEGIN( );
199
200 //Restart system
201 NVIC_SystemReset( );
202 }
203
BoardDeInitMcu(void)204 void BoardDeInitMcu( void )
205 {
206 AdcDeInit( &Adc );
207
208 #if defined( SX1261MBXBAS ) || defined( SX1262MBXCAS ) || defined( SX1262MBXDAS )
209 SpiDeInit( &SX126x.Spi );
210 SX126xIoDeInit( );
211 #elif defined( LR1110MB1XXS )
212 SpiDeInit( &LR1110.spi );
213 lr1110_board_deinit_io( &LR1110 );
214 #elif defined( SX1272MB2DAS )
215 SpiDeInit( &SX1272.Spi );
216 SX1272IoDeInit( );
217 #elif defined( SX1276MB1LAS ) || defined( SX1276MB1MAS )
218 SpiDeInit( &SX1276.Spi );
219 SX1276IoDeInit( );
220 #endif
221 }
222
BoardGetRandomSeed(void)223 uint32_t BoardGetRandomSeed( void )
224 {
225 return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
226 }
227
BoardGetUniqueId(uint8_t * id)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 /*!
241 * Factory power supply
242 */
243 #define VDDA_VREFINT_CAL ( ( uint32_t ) 3000 ) // mV
244
245 /*!
246 * VREF calibration value
247 */
248 #define VREFINT_CAL ( *( uint16_t* ) ( ( uint32_t ) 0x1FFF75AA ) )
249
250 /*
251 * Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at
252 * a temperature of 110 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV).
253 */
254 #define TEMP30_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FFF75A8 ) )
255
256 /* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at
257 *a temperature of 30 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
258 #define TEMP110_CAL_ADDR ( *( uint16_t* ) ( ( uint32_t ) 0x1FFF75CA ) )
259
260 /* Vdda value with which temperature sensor has been calibrated in production
261 (+-10 mV). */
262 #define VDDA_TEMP_CAL ( ( uint32_t ) 3000 )
263
264 /*!
265 * Battery thresholds
266 */
267 #define BATTERY_MAX_LEVEL 3000 // mV
268 #define BATTERY_MIN_LEVEL 2400 // mV
269 #define BATTERY_SHUTDOWN_LEVEL 2300 // mV
270
271 #define BATTERY_LORAWAN_UNKNOWN_LEVEL 255
272 #define BATTERY_LORAWAN_MAX_LEVEL 254
273 #define BATTERY_LORAWAN_MIN_LEVEL 1
274 #define BATTERY_LORAWAN_EXT_PWR 0
275
276 #define COMPUTE_TEMPERATURE( TS_ADC_DATA, VDDA_APPLI ) \
277 ( ( ( ( ( ( ( int32_t )( ( TS_ADC_DATA * VDDA_APPLI ) / VDDA_TEMP_CAL ) - ( int32_t ) TEMP30_CAL_ADDR ) ) * \
278 ( int32_t )( 110 - 30 ) ) \
279 << 8 ) / \
280 ( int32_t )( TEMP110_CAL_ADDR - TEMP30_CAL_ADDR ) ) + \
281 ( 30 << 8 ) )
282
283 static uint16_t BatteryVoltage = BATTERY_MAX_LEVEL;
284
BoardBatteryMeasureVoltage(void)285 uint16_t BoardBatteryMeasureVoltage( void )
286 {
287 uint16_t vref = 0;
288
289 // Read the current Voltage
290 vref = AdcReadChannel( &Adc, ADC_CHANNEL_VREFINT );
291
292 // Compute and return the Voltage in millivolt
293 return ( ( ( uint32_t ) VDDA_VREFINT_CAL * VREFINT_CAL ) / vref );
294 }
295
BoardGetBatteryVoltage(void)296 uint32_t BoardGetBatteryVoltage( void )
297 {
298 return BatteryVoltage;
299 }
300
BoardGetBatteryLevel(void)301 uint8_t BoardGetBatteryLevel( void )
302 {
303 uint8_t batteryLevel = 0;
304
305 BatteryVoltage = BoardBatteryMeasureVoltage( );
306
307 if( GetBoardPowerSource( ) == USB_POWER )
308 {
309 batteryLevel = BATTERY_LORAWAN_EXT_PWR;
310 }
311 else
312 {
313 if( BatteryVoltage >= BATTERY_MAX_LEVEL )
314 {
315 batteryLevel = BATTERY_LORAWAN_MAX_LEVEL;
316 }
317 else if( ( BatteryVoltage > BATTERY_MIN_LEVEL ) && ( BatteryVoltage < BATTERY_MAX_LEVEL ) )
318 {
319 batteryLevel =
320 ( ( 253 * ( BatteryVoltage - BATTERY_MIN_LEVEL ) ) / ( BATTERY_MAX_LEVEL - BATTERY_MIN_LEVEL ) ) + 1;
321 }
322 else if( ( BatteryVoltage > BATTERY_SHUTDOWN_LEVEL ) && ( BatteryVoltage <= BATTERY_MIN_LEVEL ) )
323 {
324 batteryLevel = 1;
325 }
326 else // if( BatteryVoltage <= BATTERY_SHUTDOWN_LEVEL )
327 {
328 batteryLevel = BATTERY_LORAWAN_UNKNOWN_LEVEL;
329 }
330 }
331 return batteryLevel;
332 }
333
BoardGetTemperature(void)334 int16_t BoardGetTemperature( void )
335 {
336 uint16_t tempRaw = 0;
337
338 BatteryVoltage = BoardBatteryMeasureVoltage( );
339
340 tempRaw = AdcReadChannel( &Adc, ADC_CHANNEL_TEMPSENSOR );
341
342 // Compute and return the temperature in degree celcius * 256
343 return ( int16_t ) COMPUTE_TEMPERATURE( tempRaw, BatteryVoltage );
344 }
345
BoardUnusedIoInit(void)346 static void BoardUnusedIoInit( void )
347 {
348 HAL_DBGMCU_EnableDBGSleepMode( );
349 HAL_DBGMCU_EnableDBGStopMode( );
350 HAL_DBGMCU_EnableDBGStandbyMode( );
351 }
352
SystemClockConfig(void)353 void SystemClockConfig( void )
354 {
355 RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
356 RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
357 RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
358
359 __HAL_RCC_PWR_CLK_ENABLE( );
360
361 __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
362
363 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_LSE;
364 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
365 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
366 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
367 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
368 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
369 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
370 RCC_OscInitStruct.PLL.PLLM = 1;
371 RCC_OscInitStruct.PLL.PLLN = 40;
372 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
373 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
374 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
375 if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
376 {
377 assert_param( LMN_STATUS_ERROR );
378 }
379
380 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
381 RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
382 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
383 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
384 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
385 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
386 if( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_4 ) != HAL_OK )
387 {
388 assert_param( LMN_STATUS_ERROR );
389 }
390
391 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
392 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
393 if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInit ) != HAL_OK )
394 {
395 assert_param( LMN_STATUS_ERROR );
396 }
397
398 HAL_SYSTICK_Config( HAL_RCC_GetHCLKFreq( ) / 1000 );
399
400 HAL_SYSTICK_CLKSourceConfig( SYSTICK_CLKSOURCE_HCLK );
401
402 // SysTick_IRQn interrupt configuration
403 HAL_NVIC_SetPriority( SysTick_IRQn, 0, 0 );
404 }
405
406 /*!
407 * \brief Programmable Voltage Detector (PVD) Configuration
408 * PVD set to level 6 for a threshold around 2.9V.
409 * \param None
410 * \retval None
411 */
PVD_Config(void)412 static void PVD_Config( void )
413 {
414 PWR_PVDTypeDef sConfigPVD;
415 sConfigPVD.PVDLevel = PWR_PVDLEVEL_6;
416 sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING;
417 if( HAL_PWR_ConfigPVD( &sConfigPVD ) != HAL_OK )
418 {
419 assert_param( LMN_STATUS_ERROR );
420 }
421
422 // Enable PVD
423 HAL_PWR_EnablePVD( );
424
425 // Enable and set PVD Interrupt priority
426 HAL_NVIC_SetPriority( PVD_PVM_IRQn, 0, 0 );
427 HAL_NVIC_EnableIRQ( PVD_PVM_IRQn );
428 }
429
430 /*!
431 * \brief Initializes the EEPROM emulation module.
432 *
433 * \remark This function is defined in eeprom-board.c file
434 */
435 void EepromMcuInit( void );
436
InitFlashMemoryOperations(void)437 static void InitFlashMemoryOperations( void )
438 {
439 // Enable and set FLASH Interrupt priority
440 // FLASH interrupt is used for the purpose of pages clean up under interrupt
441 HAL_NVIC_SetPriority( FLASH_IRQn, 0, 0 );
442 HAL_NVIC_EnableIRQ( FLASH_IRQn );
443
444 // Unlock the Flash Program Erase controller
445 HAL_FLASH_Unlock( );
446
447 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
448 // Clear OPTVERR bit and PEMPTY flag if set
449 if( __HAL_FLASH_GET_FLAG( FLASH_FLAG_OPTVERR ) != RESET )
450 {
451 __HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_OPTVERR );
452 }
453
454 if( __HAL_FLASH_GET_FLAG( FLASH_FLAG_PEMPTY ) != RESET )
455 {
456 __HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_PEMPTY );
457 }
458 #endif /* defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) */
459
460 // Enable Power Control clock
461 __HAL_RCC_PWR_CLK_ENABLE();
462 #if defined (USE_STM32L4XX_NUCLEO_144)
463 HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN2 );
464 #endif /* defined (USE_STM32L4XX_NUCLEO_144) */
465
466 // Configure Programmable Voltage Detector (PVD) (optional)
467 // PVD interrupt is used to suspend the current application flow in case
468 // a power-down is detected, allowing the flash interface to finish any
469 // ongoing operation before a reset is triggered.
470 PVD_Config( );
471
472 // Initialize the EEPROM emulation driver
473 EepromMcuInit( );
474
475 // Lock the Flash Program Erase controller
476 HAL_FLASH_Lock( );
477 }
478
SystemClockReConfig(void)479 void SystemClockReConfig( void )
480 {
481 RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
482 RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
483 uint32_t pFLatency = 0;
484
485 CRITICAL_SECTION_BEGIN( );
486
487 // In case nvic had a pending IT, the arm doesn't enter stop mode
488 // Hence the pll is not switched off and will cause HAL_RCC_OscConfig return
489 // an error
490 if ( __HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL )
491 {
492 // Enable Power Control clock
493 __HAL_RCC_PWR_CLK_ENABLE( );
494
495 // Get the Oscillators configuration according to the internal RCC registers */
496 HAL_RCC_GetOscConfig( &RCC_OscInitStruct );
497
498 // Enable PLL
499 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE;
500 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
501 if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
502 {
503 while( 1 );
504 }
505
506 /* Get the Clocks configuration according to the internal RCC registers */
507 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
508
509 /* Select PLL as system clock source and keep HCLK, PCLK1 and PCLK2 clocks dividers as before */
510 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
511 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
512 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
513 {
514 while(1);
515 }
516 }
517 else
518 {
519 // MCU did not enter stop mode beacuse NVIC had a pending IT
520 }
521
522 CRITICAL_SECTION_END( );
523 }
524
SysTick_Handler(void)525 void SysTick_Handler( void )
526 {
527 HAL_IncTick( );
528 HAL_SYSTICK_IRQHandler( );
529 }
530
GetBoardPowerSource(void)531 uint8_t GetBoardPowerSource( void )
532 {
533 if( UsbIsConnected == false )
534 {
535 return BATTERY_POWER;
536 }
537 else
538 {
539 return USB_POWER;
540 }
541 }
542
543 /**
544 * \brief Enters Low Power Stop Mode
545 *
546 * \note ARM exists the function when waking up
547 */
LpmEnterStopMode(void)548 void LpmEnterStopMode( void)
549 {
550 CRITICAL_SECTION_BEGIN( );
551
552 BoardDeInitMcu( );
553
554 CRITICAL_SECTION_END( );
555
556 // Enter Stop Mode
557 HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
558 }
559
560 /*!
561 * \brief Exists Low Power Stop Mode
562 */
LpmExitStopMode(void)563 void LpmExitStopMode( void )
564 {
565 // Disable IRQ while the MCU is not running on HSI
566 CRITICAL_SECTION_BEGIN( );
567
568 // Initilizes the peripherals
569 BoardInitMcu( );
570
571 CRITICAL_SECTION_END( );
572 }
573
574 /*!
575 * \brief Enters Low Power Sleep Mode
576 *
577 * \note ARM exits the function when waking up
578 */
LpmEnterSleepMode(void)579 void LpmEnterSleepMode( void)
580 {
581 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
582 }
583
584 /*!
585 * \brief Indicates if an erasing operation is on going.
586 *
587 * \remark This function is defined in eeprom-board.c file
588 *
589 * \retval isEradingOnGoing Returns true is an erasing operation is on going.
590 */
591 bool EepromMcuIsErasingOnGoing( void );
592
BoardLowPowerHandler(void)593 void BoardLowPowerHandler( void )
594 {
595 // Wait for any cleanup to complete before entering standby/shutdown mode
596 while( EepromMcuIsErasingOnGoing( ) == true ){ }
597
598 __disable_irq( );
599 /*!
600 * If an interrupt has occurred after __disable_irq( ), it is kept pending
601 * and cortex will not enter low power anyway
602 */
603
604 LpmEnterLowPower( );
605
606 __enable_irq( );
607 }
608
609 #if !defined ( __CC_ARM )
610
611 /*
612 * Function to be used by stdout for printf etc
613 */
_write(int fd,const void * buf,size_t count)614 int _write( int fd, const void *buf, size_t count )
615 {
616 while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
617 return count;
618 }
619
620 /*
621 * Function to be used by stdin for scanf etc
622 */
_read(int fd,const void * buf,size_t count)623 int _read( int fd, const void *buf, size_t count )
624 {
625 size_t bytesRead = 0;
626 while( UartGetBuffer( &Uart2, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
627 // Echo back the character
628 while( UartPutBuffer( &Uart2, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
629 return bytesRead;
630 }
631
632 #else
633
634 #include <stdio.h>
635
636 // Keil compiler
fputc(int c,FILE * stream)637 int fputc( int c, FILE *stream )
638 {
639 while( UartPutChar( &Uart2, ( uint8_t )c ) != 0 );
640 return c;
641 }
642
fgetc(FILE * stream)643 int fgetc( FILE *stream )
644 {
645 uint8_t c = 0;
646 while( UartGetChar( &Uart2, &c ) != 0 );
647 // Echo back the character
648 while( UartPutChar( &Uart2, c ) != 0 );
649 return ( int )c;
650 }
651
652 #endif
653
654 #ifdef USE_FULL_ASSERT
655
656 #include <stdio.h>
657
658 /*
659 * Function Name : assert_failed
660 * Description : Reports the name of the source file and the source line number
661 * where the assert_param error has occurred.
662 * Input : - file: pointer to the source file name
663 * - line: assert_param error line source number
664 * Output : None
665 * Return : None
666 */
assert_failed(uint8_t * file,uint32_t line)667 void assert_failed( uint8_t* file, uint32_t line )
668 {
669 /* User can add his own implementation to report the file name and line number,
670 ex: printf("Wrong parameters value: file %s on line %lu\n", file, line) */
671
672 printf( "Wrong parameters value: file %s on line %lu\n", ( const char* )file, line );
673 /* Infinite loop */
674 while( 1 )
675 {
676 }
677 }
678 #endif
679