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
Diff: WatchdogTimer.cpp
- Revision:
- 0:2f819bf6cd99
diff -r 000000000000 -r 2f819bf6cd99 WatchdogTimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WatchdogTimer.cpp Wed May 24 19:04:12 2017 +0000 @@ -0,0 +1,155 @@ +#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 \ No newline at end of file