Wakeup and Standby systems
This commit is contained in:
@@ -3,17 +3,127 @@
|
||||
#include "BSP_POWER.h"
|
||||
#include "lptim.h"
|
||||
#include "ulog.h"
|
||||
#include "rtc.h"
|
||||
#include "fdcan.h"
|
||||
#include "i2c.h"
|
||||
#include "sdmmc.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "BSP_GPIO.h"
|
||||
|
||||
#define LPTIM_CLK 500 // Hz
|
||||
#define SLEEP_TIME 10 // seconds to wait
|
||||
#define SLEEP_TICK_TIME 1 // seconds to wait
|
||||
#define STAY_AWAKE_TIME 60 // seconds to stay awake without K15
|
||||
|
||||
|
||||
|
||||
// Start the sleep counter check
|
||||
void BSP_POWER_Init() {
|
||||
uint16_t counter = LPTIM_CLK * SLEEP_TIME;
|
||||
uint16_t counter = LPTIM_CLK * SLEEP_TICK_TIME;
|
||||
HAL_LPTIM_Counter_Start_IT(&hlptim4, counter);
|
||||
}
|
||||
|
||||
|
||||
// This should be called as soon as possible after wakeup
|
||||
void BSP_POWER_WakeUp() {
|
||||
|
||||
/* Check if the system has resumed from StandBy mode */
|
||||
if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
|
||||
{
|
||||
/* Clear Standby flag */
|
||||
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
|
||||
}
|
||||
|
||||
|
||||
if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF) != 0U)
|
||||
{
|
||||
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* The Following Wakeup sequence is highly recommended prior to each Standby mode entry
|
||||
mainly when using more than one wakeup source this is to not miss any wakeup event.
|
||||
- Disable all used wakeup sources,
|
||||
- Clear all related wakeup flags,
|
||||
- Re-enable all used wakeup sources,
|
||||
- Enter the Standby mode.
|
||||
*/
|
||||
void BSP_POWER_EnterStandby() {
|
||||
|
||||
// We need to disable all Periperals to minimize parasitic currents
|
||||
HAL_I2C_DeInit(&hi2c1);
|
||||
HAL_I2C_MspDeInit(&hi2c1);
|
||||
HAL_I2C_DeInit(&hi2c2);
|
||||
HAL_I2C_MspDeInit(&hi2c2);
|
||||
HAL_FDCAN_DeInit(&hfdcan1);
|
||||
HAL_FDCAN_MspDeInit(&hfdcan1);
|
||||
HAL_FDCAN_DeInit(&hfdcan2);
|
||||
HAL_FDCAN_MspDeInit(&hfdcan2);
|
||||
HAL_SD_MspDeInit(&hsd1);
|
||||
|
||||
// These Pins interfere with the WAKEUP PINS
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1| GPIO_PIN_3);
|
||||
|
||||
// cut the power for the Slaves and unused peripherals
|
||||
BSP_GPIO_ClsOff();
|
||||
BSP_GPIO_PeriperalsOff();
|
||||
BSP_GPIO_RadioOff();
|
||||
|
||||
|
||||
|
||||
// Here now the showdown
|
||||
PWREx_WakeupPinTypeDef sPinParams;
|
||||
|
||||
/* Disable used wakeup source: PWR_WAKEUP_PIN1 */
|
||||
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2);
|
||||
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
|
||||
|
||||
HAL_PWREx_ClearPendingEvent();
|
||||
/* Clear all related wakeup flags */
|
||||
HAL_PWREx_ClearWakeupFlag(PWR_WAKEUP_FLAG_ALL);
|
||||
HAL_PWREx_ClearWakeupFlag(PWR_WAKEUP_PIN1);
|
||||
HAL_PWREx_ClearWakeupFlag(PWR_WAKEUP_PIN2);
|
||||
|
||||
/* Clear all related wakeup flags */
|
||||
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
|
||||
|
||||
|
||||
//HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0xFFFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
|
||||
HAL_PWREx_ClearWakeupFlag(PWR_WAKEUP_PIN1);
|
||||
|
||||
sPinParams.WakeUpPin = PWR_WAKEUP_PIN1;
|
||||
sPinParams.PinPolarity = PWR_PIN_POLARITY_HIGH;
|
||||
sPinParams.PinPull = PWR_PIN_PULL_DOWN;
|
||||
HAL_PWREx_EnableWakeUpPin(&sPinParams);
|
||||
|
||||
sPinParams.WakeUpPin = PWR_WAKEUP_PIN2;
|
||||
sPinParams.PinPolarity = PWR_PIN_POLARITY_HIGH;
|
||||
sPinParams.PinPull = PWR_PIN_PULL_DOWN;
|
||||
HAL_PWREx_EnableWakeUpPin(&sPinParams);
|
||||
|
||||
|
||||
/* Enter the Standby mode */
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
|
||||
}
|
||||
|
||||
uint32_t sec_without_k15 = 0;
|
||||
|
||||
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim) {
|
||||
|
||||
if(hlptim == &hlptim4) {
|
||||
// 1s timer check if K15 is set
|
||||
if (!BSP_GPIO_K15isSet()) {
|
||||
sec_without_k15++;
|
||||
} else {
|
||||
sec_without_k15 = 0;
|
||||
}
|
||||
|
||||
if (sec_without_k15 > STAY_AWAKE_TIME) {
|
||||
BSP_POWER_EnterStandby();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,3 +7,7 @@
|
||||
void BSP_POWER_Init();
|
||||
|
||||
|
||||
void BSP_POWER_WakeUp();
|
||||
|
||||
|
||||
void BSP_POWER_EnterStandby();
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "BSP_INA.h"
|
||||
#include "BSP_POWER.h"
|
||||
#include "LightTask.h"
|
||||
#include "BSP_GPIO.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -65,12 +66,20 @@ const osThreadAttr_t defaultTask_attributes = {
|
||||
.priority = (osPriority_t) osPriorityNormal,
|
||||
};
|
||||
|
||||
osThreadId_t waitForStartConfirmHandle;
|
||||
const osThreadAttr_t waitForStartConfirm_attributes = {
|
||||
.name = "waitForStartConfirm",
|
||||
.stack_size = 128 * 4,
|
||||
.priority = (osPriority_t) osPriorityNormal,
|
||||
};
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
void StartDefaultTask(void *argument);
|
||||
void WaitForStartConfirm_Task(void *argument);
|
||||
|
||||
extern void MX_USB_DEVICE_Init(void);
|
||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||
@@ -99,7 +108,6 @@ return __HAL_TIM_GetCounter(&htim2);
|
||||
*/
|
||||
void MX_FREERTOS_Init(void) {
|
||||
/* USER CODE BEGIN Init */
|
||||
BSP_POWER_Init();
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* USER CODE BEGIN RTOS_MUTEX */
|
||||
@@ -123,6 +131,9 @@ void MX_FREERTOS_Init(void) {
|
||||
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
|
||||
waitForStartConfirmHandle = osThreadNew(WaitForStartConfirm_Task, NULL, &waitForStartConfirm_attributes);
|
||||
|
||||
ULOG_INFO("Setup UsbDataHandler");
|
||||
UsbDataHandler_Start();
|
||||
ULOG_INFO("Setup CanDataTask");
|
||||
@@ -200,5 +211,34 @@ void StartDefaultTask(void *argument)
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
void WaitForStartConfirm_Task(void *argument) {
|
||||
|
||||
// wait for up to 1 s and check if either K15 is set or we got a Car CAN message
|
||||
// once one of these is true, we can start the power systems.
|
||||
// after waiting for 1s, the system should shutdown / go to standby mode
|
||||
uint32_t tick = osKernelGetTickCount();
|
||||
uint32_t delayTime = 50; // Set the initial delay time to 50ms
|
||||
uint32_t maxDelayTime = 1000; // Set the maximum delay time to 1000ms
|
||||
|
||||
while(1) {
|
||||
osDelayUntil(tick);
|
||||
tick += delayTime;
|
||||
if(BSP_GPIO_K15isSet() || CanDataTask_gotCarCanMessage()) {
|
||||
BSP_GPIO_ClsOn();
|
||||
BSP_GPIO_RadioOn();
|
||||
ULOG_INFO("Power systems started");
|
||||
osThreadExit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(tick > maxDelayTime) {
|
||||
BSP_POWER_EnterStandby();
|
||||
ULOG_INFO("System in standby mode");
|
||||
osThreadExit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE END Application */
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "ulog.h"
|
||||
#include "stdio.h"
|
||||
#include "BSP_POWER.h"
|
||||
#include "BSP_GPIO.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -81,7 +83,7 @@ void ULOG_SendLPUART(ulog_level_t level, char *msg);
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
@@ -108,7 +110,7 @@ int main(void)
|
||||
PeriphCommonClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
BSP_POWER_WakeUp();
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
@@ -129,40 +131,18 @@ int main(void)
|
||||
MX_TIM2_Init();
|
||||
MX_LPTIM4_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
ULOG_INIT();
|
||||
ULOG_SUBSCRIBE(ULOG_SendLPUART,ULOG_DEBUG_LEVEL);
|
||||
GPIO_PinState K15 = HAL_GPIO_ReadPin(K15_Detect_GPIO_Port, K15_Detect_Pin);
|
||||
while (K15 == GPIO_PIN_RESET)
|
||||
{
|
||||
K15 = HAL_GPIO_ReadPin(K15_Detect_GPIO_Port, K15_Detect_Pin);
|
||||
ULOG_DEBUG("Wait for K15 Signal Wait Wait Wait");
|
||||
HAL_Delay(100);
|
||||
}
|
||||
|
||||
|
||||
GPIO_PinState HL = HAL_GPIO_ReadPin(Headlight_Detect_GPIO_Port, Headlight_Detect_Pin);
|
||||
while (HL == GPIO_PIN_RESET)
|
||||
{
|
||||
HL = HAL_GPIO_ReadPin(Headlight_Detect_GPIO_Port, Headlight_Detect_Pin);
|
||||
ULOG_DEBUG("Wait for K15 Signal Wait Wait Wait");
|
||||
HAL_Delay(100);
|
||||
}
|
||||
|
||||
BSP_GPIO_PeriperalsOn();
|
||||
BSP_POWER_Init();
|
||||
ULOG_INIT();
|
||||
ULOG_SUBSCRIBE(ULOG_SendLPUART,ULOG_DEBUG_LEVEL);
|
||||
ULOG_DEBUG("Setup Logger");
|
||||
HAL_GPIO_WritePin(Periph_Power_GPIO_Port,Periph_Power_Pin,GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CLS_POWER_GPIO_Port, CLS_POWER_Pin, GPIO_PIN_SET);
|
||||
ULOG_DEBUG("Enable Power on CLS and Periph");
|
||||
gCLS_DEVICE_ADDRESS = 0x11;
|
||||
gCLS_DEVICE_ADDRESS = 0x11; // Address is set to master
|
||||
ULOG_DEBUG("Setting Global CLS address to 0b10001");
|
||||
ULOG_DEBUG("Init Kernel and start schedule");
|
||||
|
||||
|
||||
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
|
||||
|
||||
/* Init scheduler */
|
||||
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
|
||||
MX_FREERTOS_Init();
|
||||
@@ -364,6 +344,13 @@ void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
|
||||
ULOG_ERROR("Error Handler");
|
||||
osThreadId_t error_thread = osThreadGetId();
|
||||
if(error_thread != NULL) {
|
||||
const char * osThreadGetName(error_thread);
|
||||
ULOG_ERROR("Error in thread: %s", osThreadGetName(error_thread));
|
||||
}
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user