Here, alternative functions and classes for STM32. The program contains a class for the I2C software bus, a class for working with a watchdog timer and time delay functions based on DWT. All functions and classes use the HAL library. Functions and classes were written for the microcontroller stm32f103.

Dependents:   STM32_F1XX_Alternative

WatchdogTimer.cpp

Committer:
Yar
Date:
2017-05-24
Revision:
1:0d39ea4dee8b
Parent:
0:2f819bf6cd99

File content as of revision 1:0d39ea4dee8b:

#include "WatchdogTimer.hpp"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_iwdg.h"
#include "mbed.h"

static IWDG_HandleTypeDef hiwdg;
static const uint16_t watchdogFreq = 32000;

// Notes:
// Watchdog timer frequency 32 kHz
// Prescaler: Min_Value = 4 and Max_Value = 256
// Reload: Min_Data = 0 and Max_Data = 0x0FFF = 4095
// TimeOut in seconds = (Reload * Prescaler) / Freq.
// MinTimeOut = (4 * 1) / 32000 = 0.000125 seconds (125 microseconds)
// MaxTimeOut = (256 * 4096) / 32000 = 32.768 seconds
// Reload = time * 32000 / Prescaler

WatchdogTimer::WatchdogTimer() {
    hiwdg.Instance = IWDG;
    hiwdg.Init.Prescaler = IWDG_PRESCALER_256; 
    hiwdg.Init.Reload = 0x0FFF; // 32.768 seconds             
    HAL_IWDG_Init(&hiwdg);
}

WatchdogTimer::WatchdogTimer(float time) {
    hiwdg.Instance = IWDG;
    hiwdg.Init.Prescaler = IWDG_PRESCALER_256; 
    hiwdg.Init.Reload = 0x0FFF; // 32.768 seconds             
    HAL_IWDG_Init(&hiwdg);
    setResponseTime(time);
}

static void setWatchdogTimer(uint32_t time, uint32_t dimensionality) {
    hiwdg.Instance = IWDG;
    if (time <= 125 && dimensionality == 1000000) {
        hiwdg.Init.Prescaler = IWDG_PRESCALER_4; 
        hiwdg.Init.Reload = 1;            
    } else {
        uint32_t _reload = time * watchdogFreq;
        _reload /= dimensionality;
        uint8_t _prescaler = 4;
        while(1) {
            uint32_t _test = _reload / _prescaler;
            if (_test > 0x0FFF) {
                if (_prescaler >= 256) {
                    return; 
                } // if
                _prescaler *= 2;
            } else {
                _reload = _test;
                break; 
            } // if
        } // while
        hiwdg.Instance = IWDG;
        if (_prescaler == 32) {
            hiwdg.Init.Prescaler = IWDG_PRESCALER_32; 
        } else
        if (_prescaler > 32) {
            if (_prescaler <= 64) {
                hiwdg.Init.Prescaler = IWDG_PRESCALER_64; 
            } else {
                if (_prescaler <= 128) {
                    hiwdg.Init.Prescaler = IWDG_PRESCALER_128; 
                } else {
                    hiwdg.Init.Prescaler = IWDG_PRESCALER_256; 
                } // if
            } // if
        } else {
            if (_prescaler >= 16) {
                hiwdg.Init.Prescaler = IWDG_PRESCALER_16; 
            } else {
                if (_prescaler >= 8) {
                    hiwdg.Init.Prescaler = IWDG_PRESCALER_8; 
                } else {
                    hiwdg.Init.Prescaler = IWDG_PRESCALER_4; 
                } // if
            } // if
        } // if
        hiwdg.Init.Reload = _reload; // 32.768 seconds             
        HAL_IWDG_Init(&hiwdg);     
    } // if
}

void WatchdogTimer::setResponseTime_us(uint32_t time) {
    setWatchdogTimer(time, 1000000);
}

void WatchdogTimer::setResponseTime_ms(uint32_t time) {
    setWatchdogTimer(time, 1000);
}

void WatchdogTimer::setResponseTime_s(uint32_t time) {
    setWatchdogTimer(time, 1);
}

void WatchdogTimer::setResponseTime(float time) {
    uint32_t us = time * 1000000;
    setWatchdogTimer(us, 1000000);
}

void WatchdogTimer::refresh(void) {
    HAL_IWDG_Refresh(&hiwdg);
}

void WatchdogTimer::start(void) {
    HAL_IWDG_Start(&hiwdg);
}

WatchdogTimer::enumWatchdogTimer WatchdogTimer::getStatus(void) {
    switch (HAL_IWDG_GetState(&hiwdg)) {
        case HAL_IWDG_STATE_RESET:       // IWDG not yet initialized or disabled
            return WatchdogTimer::RESET;
            //break;
        case HAL_IWDG_STATE_READY:       // IWDG initialized and ready for use  
            return WatchdogTimer::READY;
            //break;
        case HAL_IWDG_STATE_BUSY:        // IWDG internal process is ongoing    
            return WatchdogTimer::BUSY;
            //break;
        case HAL_IWDG_STATE_TIMEOUT:     // IWDG timeout state                  
            return WatchdogTimer::TIMEOUT;
            //break;
        case HAL_IWDG_STATE_ERROR:       // IWDG error state                    
            return WatchdogTimer::ERROR;
            //break;
        default: 
            return WatchdogTimer::UNKNOWN;
            //break;
    }
}

#if (0)
void WatchdogStatus(void) {
    switch (HAL_IWDG_GetState(&hiwdg)) {
        case HAL_IWDG_STATE_RESET:       /*!< IWDG not yet initialized or disabled */
            printf("IWDG not yet initialized or disabled\r\n");
            break;
        case HAL_IWDG_STATE_READY:       /*!< IWDG initialized and ready for use   */
            printf("IIWDG initialized and ready for use\r\n");
            break;
        case HAL_IWDG_STATE_BUSY:        /*!< IWDG internal process is ongoing     */
            printf("IWDG internal process is ongoing\r\n");
            break;
        case HAL_IWDG_STATE_TIMEOUT:     /*!< IWDG timeout state                   */
            printf("IWDG timeout state\r\n");
            break;
        case HAL_IWDG_STATE_ERROR:       /*!< IWDG error state                     */
            printf("IWDG error state\r\n");
            break;
        default: 
            printf("Unknown state\r\n");
            break;
    }
}
#endif