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 MultiTech

wakeup.c

Committer:
ruairisdad
Date:
2015-08-07
Revision:
3:321cf5e5b89b
Parent:
1:e52ae6584f1c

File content as of revision 3:321cf5e5b89b:

#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;
}