Skip to content

Commit 116da57

Browse files
fprfpistm
fpr
authored andcommitted
Update HardwareSerial and uart driver for low power mode
Signed-off-by: fpr <[email protected]>
1 parent dcf191f commit 116da57

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

cores/arduino/HardwareSerial.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ void HardwareSerial::init(void)
182182
_serial.tx_tail = 0;
183183
}
184184

185+
void HardwareSerial::configForLowPower(void)
186+
{
187+
#if defined(HAL_PWR_MODULE_ENABLED) && defined(UART_IT_WUF)
188+
// Reconfigure properly Serial instance to use HSI as clock source
189+
end();
190+
uart_config_lowpower(&_serial);
191+
begin(_serial.baudrate, _config);
192+
#endif
193+
}
194+
185195
// Actual interrupt handlers //////////////////////////////////////////////////////////////
186196

187197
void HardwareSerial::_rx_complete_irq(serial_t* obj)
@@ -226,6 +236,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
226236
uint32_t databits = 0;
227237

228238
_serial.baudrate = (uint32_t)baud;
239+
_config = config;
229240

230241
// Manage databits
231242
switch(config & 0x07) {

cores/arduino/HardwareSerial.h

+4
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,15 @@ class HardwareSerial : public Stream
125125
void setRx(PinName _rx);
126126
void setTx(PinName _tx);
127127

128+
friend class STM32LowPower;
129+
128130
// Interrupt handlers
129131
static void _rx_complete_irq(serial_t* obj);
130132
static int _tx_complete_irq(serial_t* obj);
131133
private:
134+
uint8_t _config;
132135
void init(void);
136+
void configForLowPower(void);
133137
};
134138

135139
extern HardwareSerial Serial1;

cores/arduino/stm32/uart.c

+78
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ void uart_init(serial_t *obj)
125125
printf("ERROR: UART pins mismatch\n");
126126
return;
127127
}
128+
128129
// Enable USART clock
129130
#if defined(USART1_BASE)
130131
else if(obj->uart == USART1) {
@@ -288,6 +289,7 @@ void uart_init(serial_t *obj)
288289
huart->Init.Mode = UART_MODE_TX_RX;
289290
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
290291
huart->Init.OverSampling = UART_OVERSAMPLING_16;
292+
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
291293
// huart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
292294

293295
if(HAL_UART_Init(huart) != HAL_OK) {
@@ -403,6 +405,69 @@ void uart_deinit(serial_t *obj)
403405
HAL_UART_DeInit(uart_handlers[obj->index]);
404406
}
405407

408+
#if defined(HAL_PWR_MODULE_ENABLED) && defined(UART_IT_WUF)
409+
/**
410+
* @brief Function called to configure the uart interface for low power
411+
* @param obj : pointer to serial_t structure
412+
* @retval None
413+
*/
414+
void uart_config_lowpower(serial_t *obj)
415+
{
416+
if(obj == NULL) {
417+
return;
418+
}
419+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
420+
/* Ensure HSI clock is enable */
421+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) {
422+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
423+
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
424+
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
425+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
426+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK) {
427+
Error_Handler();
428+
}
429+
}
430+
/* Configure HSI as source clock for low power wakeup clock */
431+
switch (obj->index) {
432+
#if defined(USART1_BASE)
433+
case 0:
434+
if (__HAL_RCC_GET_USART1_SOURCE() != RCC_USART1CLKSOURCE_HSI) {
435+
__HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_HSI);
436+
}
437+
break;
438+
#endif
439+
#if defined(USART2_BASE) && defined(__HAL_RCC_USART2_CONFIG)
440+
case 1:
441+
if (__HAL_RCC_GET_USART2_SOURCE() != RCC_USART2CLKSOURCE_HSI) {
442+
__HAL_RCC_USART2_CONFIG(RCC_USART2CLKSOURCE_HSI);
443+
}
444+
break;
445+
#endif
446+
#if defined(USART3_BASE) && defined(__HAL_RCC_USART3_CONFIG)
447+
case 2:
448+
if (__HAL_RCC_GET_USART3_SOURCE() != RCC_USART3CLKSOURCE_HSI) {
449+
__HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_HSI);
450+
}
451+
break;
452+
#endif
453+
#if defined(UART4_BASE) && defined(__HAL_RCC_UART4_CONFIG)
454+
case 3:
455+
if (__HAL_RCC_GET_UART4_SOURCE() != RCC_UART4CLKSOURCE_HSI) {
456+
__HAL_RCC_UART4_CONFIG(RCC_UART4CLKSOURCE_HSI);
457+
}
458+
break;
459+
#endif
460+
#if defined(UART5_BASE) && defined(__HAL_RCC_UART5_CONFIG)
461+
case 4:
462+
if (__HAL_RCC_GET_UART5_SOURCE() != RCC_UART5CLKSOURCE_HSI) {
463+
__HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_HSI);
464+
}
465+
break;
466+
#endif
467+
}
468+
}
469+
#endif
470+
406471
/**
407472
* @brief write the data on the uart
408473
* @param obj : pointer to serial_t structure
@@ -866,6 +931,19 @@ void UART10_IRQHandler(void)
866931
}
867932
#endif
868933

934+
/**
935+
* @brief HAL UART Call Back
936+
* @param UART handler
937+
* @retval None
938+
*/
939+
void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
940+
{
941+
uint8_t index = uart_index(huart);
942+
serial_t *obj = rx_callback_obj[index];
943+
944+
HAL_UART_Receive_IT(huart, &(obj->recv), 1);
945+
}
946+
869947
#ifdef __cplusplus
870948
}
871949
#endif

cores/arduino/stm32/uart.h

+3
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ struct serial_s {
279279
/* Exported functions ------------------------------------------------------- */
280280
void uart_init(serial_t *obj);
281281
void uart_deinit(serial_t *obj);
282+
#if defined(HAL_PWR_MODULE_ENABLED) && defined(UART_IT_WUF)
283+
void uart_config_lowpower(serial_t *obj);
284+
#endif
282285
size_t uart_write(serial_t *obj, uint8_t data, uint16_t size);
283286
int uart_getc(serial_t *obj, unsigned char* c);
284287
void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t*));

0 commit comments

Comments
 (0)