AT Command Set mDot firmware with updated libmDot, to fix endian problem with joining LoRaWAN network
Dependencies: MTS-Serial libmDot mbed-rtos mbed-src
Fork of mDot_AT_firmware by
Diff: wakeup.c
- Revision:
- 0:e2b8246361bc
- Child:
- 1:e52ae6584f1c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wakeup.c Thu Jun 25 14:52:56 2015 +0000 @@ -0,0 +1,153 @@ +#include "stm32f4xx_hal.h" +#include "wakeup.h" + + +static int rtc_inited = 0; +static uint32_t timeout = 10; + +uint32_t wakeup_init(uint32_t seconds) { + RCC_OscInitTypeDef RCC_OscInitStruct; + uint32_t rtc_freq = 0; + + if (rtc_inited) { + if (timeout != seconds) { + timeout = seconds; + HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, timeout, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); + } + return 0; + } + rtc_inited = 1; + + RtcHandle.Instance = RTC; + + // Enable Power clock + __PWR_CLK_ENABLE(); + + // Enable access to Backup domain + HAL_PWR_EnableBkUpAccess(); + + uint32_t count = RTC_ReadBackupRegister(RTC_BKP_DR0); + printf("UPLINK: %lu\r\n", count); + + + // Reset Backup domain + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + + // Enable LSE Oscillator + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ + RCC_OscInitStruct.LSEState = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */ + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { + // Connect LSE to RTC + __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE); + __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); + rtc_freq = LSE_VALUE; + } else { + // Enable LSI clock + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + //error("RTC error: LSI clock initialization failed."); + } + // Connect LSI to RTC + __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI); + __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI); + // [TODO] This value is LSI typical value. To be measured precisely using a timer input capture + rtc_freq = 32000; + } + + // Enable RTC + __HAL_RCC_RTC_ENABLE(); + + RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; + RtcHandle.Init.AsynchPrediv = 127; + RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1; + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; + RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + + if (HAL_RTC_Init(&RtcHandle) != HAL_OK) { + //error("RTC error: RTC initialization failed."); + } + + timeout = seconds; + HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, timeout, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); + + return count; +} + +void wakeup_clear(void) +{ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF); +} + +uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) +{ + __IO uint32_t tmp = 0; + + // Check the parameters + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + // Read the specified register + return (*(__IO uint32_t *)tmp); +} + +void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) +{ + __IO uint32_t tmp = 0; + + // Check the parameters/ + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + // Write the specified register/ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + + +uint8_t TM_WATCHDOG_Init(uint16_t reload) { + uint8_t result = 0; + + /* Check if the system has resumed from IWDG reset */ + if (RCC->CSR & (0x20000000)) { + /* Reset by IWDG */ + result = 1; + + /* Clear reset flags */ + RCC->CSR |= RCC_CSR_RMVF; + } + + /* Enable write access to IWDG_PR and IWDG_RLR registers */ + IWDG->KR = 0x5555; + + /* IWDG counter clock: LSI/32 = 1024Hz */ + IWDG->PR = 0x03; + + reload = 4095; + + printf("WATCHDOG RELOAD: %lu\r\n", reload); + /* Set reload */ + IWDG->RLR = reload; + + /* Reload IWDG counter */ + IWDG->KR = 0xAAAA; + + /* Enable IWDG (the LSI oscillator will be enabled by hardware) */ + IWDG->KR = 0xCCCC; + + /* Return status */ + return result; +} + +void TM_WATCHDOG_Disable(void) { + IWDG->KR = 0x0000; +} + +void TM_WATCHDOG_Reset(void) { + /* Reload IWDG counter */ + IWDG->KR = 0xAAAA; +} \ No newline at end of file