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@1:0d39ea4dee8b, 2017-05-24 (annotated)
- Committer:
- Yar
- Date:
- Wed May 24 20:35:23 2017 +0000
- Revision:
- 1:0d39ea4dee8b
- Parent:
- 0:2f819bf6cd99
Fixed a bug with a delay of milliseconds
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Yar | 0:2f819bf6cd99 | 1 | #include "WatchdogTimer.hpp" |
Yar | 0:2f819bf6cd99 | 2 | #include "stm32f1xx_hal.h" |
Yar | 0:2f819bf6cd99 | 3 | #include "stm32f1xx_hal_iwdg.h" |
Yar | 0:2f819bf6cd99 | 4 | #include "mbed.h" |
Yar | 0:2f819bf6cd99 | 5 | |
Yar | 0:2f819bf6cd99 | 6 | static IWDG_HandleTypeDef hiwdg; |
Yar | 0:2f819bf6cd99 | 7 | static const uint16_t watchdogFreq = 32000; |
Yar | 0:2f819bf6cd99 | 8 | |
Yar | 0:2f819bf6cd99 | 9 | // Notes: |
Yar | 0:2f819bf6cd99 | 10 | // Watchdog timer frequency 32 kHz |
Yar | 0:2f819bf6cd99 | 11 | // Prescaler: Min_Value = 4 and Max_Value = 256 |
Yar | 0:2f819bf6cd99 | 12 | // Reload: Min_Data = 0 and Max_Data = 0x0FFF = 4095 |
Yar | 0:2f819bf6cd99 | 13 | // TimeOut in seconds = (Reload * Prescaler) / Freq. |
Yar | 0:2f819bf6cd99 | 14 | // MinTimeOut = (4 * 1) / 32000 = 0.000125 seconds (125 microseconds) |
Yar | 0:2f819bf6cd99 | 15 | // MaxTimeOut = (256 * 4096) / 32000 = 32.768 seconds |
Yar | 0:2f819bf6cd99 | 16 | // Reload = time * 32000 / Prescaler |
Yar | 0:2f819bf6cd99 | 17 | |
Yar | 0:2f819bf6cd99 | 18 | WatchdogTimer::WatchdogTimer() { |
Yar | 0:2f819bf6cd99 | 19 | hiwdg.Instance = IWDG; |
Yar | 0:2f819bf6cd99 | 20 | hiwdg.Init.Prescaler = IWDG_PRESCALER_256; |
Yar | 0:2f819bf6cd99 | 21 | hiwdg.Init.Reload = 0x0FFF; // 32.768 seconds |
Yar | 0:2f819bf6cd99 | 22 | HAL_IWDG_Init(&hiwdg); |
Yar | 0:2f819bf6cd99 | 23 | } |
Yar | 0:2f819bf6cd99 | 24 | |
Yar | 0:2f819bf6cd99 | 25 | WatchdogTimer::WatchdogTimer(float time) { |
Yar | 0:2f819bf6cd99 | 26 | hiwdg.Instance = IWDG; |
Yar | 0:2f819bf6cd99 | 27 | hiwdg.Init.Prescaler = IWDG_PRESCALER_256; |
Yar | 0:2f819bf6cd99 | 28 | hiwdg.Init.Reload = 0x0FFF; // 32.768 seconds |
Yar | 0:2f819bf6cd99 | 29 | HAL_IWDG_Init(&hiwdg); |
Yar | 0:2f819bf6cd99 | 30 | setResponseTime(time); |
Yar | 0:2f819bf6cd99 | 31 | } |
Yar | 0:2f819bf6cd99 | 32 | |
Yar | 0:2f819bf6cd99 | 33 | static void setWatchdogTimer(uint32_t time, uint32_t dimensionality) { |
Yar | 0:2f819bf6cd99 | 34 | hiwdg.Instance = IWDG; |
Yar | 0:2f819bf6cd99 | 35 | if (time <= 125 && dimensionality == 1000000) { |
Yar | 0:2f819bf6cd99 | 36 | hiwdg.Init.Prescaler = IWDG_PRESCALER_4; |
Yar | 0:2f819bf6cd99 | 37 | hiwdg.Init.Reload = 1; |
Yar | 0:2f819bf6cd99 | 38 | } else { |
Yar | 0:2f819bf6cd99 | 39 | uint32_t _reload = time * watchdogFreq; |
Yar | 0:2f819bf6cd99 | 40 | _reload /= dimensionality; |
Yar | 0:2f819bf6cd99 | 41 | uint8_t _prescaler = 4; |
Yar | 0:2f819bf6cd99 | 42 | while(1) { |
Yar | 0:2f819bf6cd99 | 43 | uint32_t _test = _reload / _prescaler; |
Yar | 0:2f819bf6cd99 | 44 | if (_test > 0x0FFF) { |
Yar | 0:2f819bf6cd99 | 45 | if (_prescaler >= 256) { |
Yar | 0:2f819bf6cd99 | 46 | return; |
Yar | 0:2f819bf6cd99 | 47 | } // if |
Yar | 0:2f819bf6cd99 | 48 | _prescaler *= 2; |
Yar | 0:2f819bf6cd99 | 49 | } else { |
Yar | 0:2f819bf6cd99 | 50 | _reload = _test; |
Yar | 0:2f819bf6cd99 | 51 | break; |
Yar | 0:2f819bf6cd99 | 52 | } // if |
Yar | 0:2f819bf6cd99 | 53 | } // while |
Yar | 0:2f819bf6cd99 | 54 | hiwdg.Instance = IWDG; |
Yar | 0:2f819bf6cd99 | 55 | if (_prescaler == 32) { |
Yar | 0:2f819bf6cd99 | 56 | hiwdg.Init.Prescaler = IWDG_PRESCALER_32; |
Yar | 0:2f819bf6cd99 | 57 | } else |
Yar | 0:2f819bf6cd99 | 58 | if (_prescaler > 32) { |
Yar | 0:2f819bf6cd99 | 59 | if (_prescaler <= 64) { |
Yar | 0:2f819bf6cd99 | 60 | hiwdg.Init.Prescaler = IWDG_PRESCALER_64; |
Yar | 0:2f819bf6cd99 | 61 | } else { |
Yar | 0:2f819bf6cd99 | 62 | if (_prescaler <= 128) { |
Yar | 0:2f819bf6cd99 | 63 | hiwdg.Init.Prescaler = IWDG_PRESCALER_128; |
Yar | 0:2f819bf6cd99 | 64 | } else { |
Yar | 0:2f819bf6cd99 | 65 | hiwdg.Init.Prescaler = IWDG_PRESCALER_256; |
Yar | 0:2f819bf6cd99 | 66 | } // if |
Yar | 0:2f819bf6cd99 | 67 | } // if |
Yar | 0:2f819bf6cd99 | 68 | } else { |
Yar | 0:2f819bf6cd99 | 69 | if (_prescaler >= 16) { |
Yar | 0:2f819bf6cd99 | 70 | hiwdg.Init.Prescaler = IWDG_PRESCALER_16; |
Yar | 0:2f819bf6cd99 | 71 | } else { |
Yar | 0:2f819bf6cd99 | 72 | if (_prescaler >= 8) { |
Yar | 0:2f819bf6cd99 | 73 | hiwdg.Init.Prescaler = IWDG_PRESCALER_8; |
Yar | 0:2f819bf6cd99 | 74 | } else { |
Yar | 0:2f819bf6cd99 | 75 | hiwdg.Init.Prescaler = IWDG_PRESCALER_4; |
Yar | 0:2f819bf6cd99 | 76 | } // if |
Yar | 0:2f819bf6cd99 | 77 | } // if |
Yar | 0:2f819bf6cd99 | 78 | } // if |
Yar | 0:2f819bf6cd99 | 79 | hiwdg.Init.Reload = _reload; // 32.768 seconds |
Yar | 0:2f819bf6cd99 | 80 | HAL_IWDG_Init(&hiwdg); |
Yar | 0:2f819bf6cd99 | 81 | } // if |
Yar | 0:2f819bf6cd99 | 82 | } |
Yar | 0:2f819bf6cd99 | 83 | |
Yar | 0:2f819bf6cd99 | 84 | void WatchdogTimer::setResponseTime_us(uint32_t time) { |
Yar | 0:2f819bf6cd99 | 85 | setWatchdogTimer(time, 1000000); |
Yar | 0:2f819bf6cd99 | 86 | } |
Yar | 0:2f819bf6cd99 | 87 | |
Yar | 0:2f819bf6cd99 | 88 | void WatchdogTimer::setResponseTime_ms(uint32_t time) { |
Yar | 0:2f819bf6cd99 | 89 | setWatchdogTimer(time, 1000); |
Yar | 0:2f819bf6cd99 | 90 | } |
Yar | 0:2f819bf6cd99 | 91 | |
Yar | 0:2f819bf6cd99 | 92 | void WatchdogTimer::setResponseTime_s(uint32_t time) { |
Yar | 0:2f819bf6cd99 | 93 | setWatchdogTimer(time, 1); |
Yar | 0:2f819bf6cd99 | 94 | } |
Yar | 0:2f819bf6cd99 | 95 | |
Yar | 0:2f819bf6cd99 | 96 | void WatchdogTimer::setResponseTime(float time) { |
Yar | 0:2f819bf6cd99 | 97 | uint32_t us = time * 1000000; |
Yar | 0:2f819bf6cd99 | 98 | setWatchdogTimer(us, 1000000); |
Yar | 0:2f819bf6cd99 | 99 | } |
Yar | 0:2f819bf6cd99 | 100 | |
Yar | 0:2f819bf6cd99 | 101 | void WatchdogTimer::refresh(void) { |
Yar | 0:2f819bf6cd99 | 102 | HAL_IWDG_Refresh(&hiwdg); |
Yar | 0:2f819bf6cd99 | 103 | } |
Yar | 0:2f819bf6cd99 | 104 | |
Yar | 0:2f819bf6cd99 | 105 | void WatchdogTimer::start(void) { |
Yar | 0:2f819bf6cd99 | 106 | HAL_IWDG_Start(&hiwdg); |
Yar | 0:2f819bf6cd99 | 107 | } |
Yar | 0:2f819bf6cd99 | 108 | |
Yar | 0:2f819bf6cd99 | 109 | WatchdogTimer::enumWatchdogTimer WatchdogTimer::getStatus(void) { |
Yar | 0:2f819bf6cd99 | 110 | switch (HAL_IWDG_GetState(&hiwdg)) { |
Yar | 0:2f819bf6cd99 | 111 | case HAL_IWDG_STATE_RESET: // IWDG not yet initialized or disabled |
Yar | 0:2f819bf6cd99 | 112 | return WatchdogTimer::RESET; |
Yar | 0:2f819bf6cd99 | 113 | //break; |
Yar | 0:2f819bf6cd99 | 114 | case HAL_IWDG_STATE_READY: // IWDG initialized and ready for use |
Yar | 0:2f819bf6cd99 | 115 | return WatchdogTimer::READY; |
Yar | 0:2f819bf6cd99 | 116 | //break; |
Yar | 0:2f819bf6cd99 | 117 | case HAL_IWDG_STATE_BUSY: // IWDG internal process is ongoing |
Yar | 0:2f819bf6cd99 | 118 | return WatchdogTimer::BUSY; |
Yar | 0:2f819bf6cd99 | 119 | //break; |
Yar | 0:2f819bf6cd99 | 120 | case HAL_IWDG_STATE_TIMEOUT: // IWDG timeout state |
Yar | 0:2f819bf6cd99 | 121 | return WatchdogTimer::TIMEOUT; |
Yar | 0:2f819bf6cd99 | 122 | //break; |
Yar | 0:2f819bf6cd99 | 123 | case HAL_IWDG_STATE_ERROR: // IWDG error state |
Yar | 0:2f819bf6cd99 | 124 | return WatchdogTimer::ERROR; |
Yar | 0:2f819bf6cd99 | 125 | //break; |
Yar | 0:2f819bf6cd99 | 126 | default: |
Yar | 0:2f819bf6cd99 | 127 | return WatchdogTimer::UNKNOWN; |
Yar | 0:2f819bf6cd99 | 128 | //break; |
Yar | 0:2f819bf6cd99 | 129 | } |
Yar | 0:2f819bf6cd99 | 130 | } |
Yar | 0:2f819bf6cd99 | 131 | |
Yar | 0:2f819bf6cd99 | 132 | #if (0) |
Yar | 0:2f819bf6cd99 | 133 | void WatchdogStatus(void) { |
Yar | 0:2f819bf6cd99 | 134 | switch (HAL_IWDG_GetState(&hiwdg)) { |
Yar | 0:2f819bf6cd99 | 135 | case HAL_IWDG_STATE_RESET: /*!< IWDG not yet initialized or disabled */ |
Yar | 0:2f819bf6cd99 | 136 | printf("IWDG not yet initialized or disabled\r\n"); |
Yar | 0:2f819bf6cd99 | 137 | break; |
Yar | 0:2f819bf6cd99 | 138 | case HAL_IWDG_STATE_READY: /*!< IWDG initialized and ready for use */ |
Yar | 0:2f819bf6cd99 | 139 | printf("IIWDG initialized and ready for use\r\n"); |
Yar | 0:2f819bf6cd99 | 140 | break; |
Yar | 0:2f819bf6cd99 | 141 | case HAL_IWDG_STATE_BUSY: /*!< IWDG internal process is ongoing */ |
Yar | 0:2f819bf6cd99 | 142 | printf("IWDG internal process is ongoing\r\n"); |
Yar | 0:2f819bf6cd99 | 143 | break; |
Yar | 0:2f819bf6cd99 | 144 | case HAL_IWDG_STATE_TIMEOUT: /*!< IWDG timeout state */ |
Yar | 0:2f819bf6cd99 | 145 | printf("IWDG timeout state\r\n"); |
Yar | 0:2f819bf6cd99 | 146 | break; |
Yar | 0:2f819bf6cd99 | 147 | case HAL_IWDG_STATE_ERROR: /*!< IWDG error state */ |
Yar | 0:2f819bf6cd99 | 148 | printf("IWDG error state\r\n"); |
Yar | 0:2f819bf6cd99 | 149 | break; |
Yar | 0:2f819bf6cd99 | 150 | default: |
Yar | 0:2f819bf6cd99 | 151 | printf("Unknown state\r\n"); |
Yar | 0:2f819bf6cd99 | 152 | break; |
Yar | 0:2f819bf6cd99 | 153 | } |
Yar | 0:2f819bf6cd99 | 154 | } |
Yar | 0:2f819bf6cd99 | 155 | #endif |