|
| 1 | +// Esp32Timer.h |
| 2 | + |
| 3 | +#ifndef __ESP32_TIMER_H__ |
| 4 | +#define __ESP32_TIMER_H__ |
| 5 | + |
| 6 | +extern void systemPrintf(const char * format, ...); |
| 7 | + |
| 8 | +#define TIMG0 0x3ff5f000 |
| 9 | +#define TIMG1 0x3ff60000 |
| 10 | + |
| 11 | +#define TIMG_T0CONFIG_REG 0x0000 // RW |
| 12 | +#define TIMG_T0LO_REG 0x0004 // RO |
| 13 | +#define TIMG_T0HI_REG 0x0008 // RO |
| 14 | +#define TIMG_T0UPDATE_REG 0x000c // WO |
| 15 | +#define TIMG_T0ALARMLO_REG 0x0010 // RW |
| 16 | +#define TIMG_T0ALARMHI_REG 0x0014 // RW |
| 17 | +#define TIMG_T0LOADLO_REG 0x0018 // RW |
| 18 | +#define TIMG_T0LOADHI_REG 0x001c // RW |
| 19 | +#define TIMG_T0LOAD_REG 0x0020 // WO |
| 20 | + |
| 21 | +#define TIMG_T1CONFIG_REG 0x0024 // RW |
| 22 | +#define TIMG_T1LO_REG 0x0028 // RO |
| 23 | +#define TIMG_T1HI_REG 0x002c // RO |
| 24 | +#define TIMG_T1UPDATE_REG 0x0030 // WO |
| 25 | +#define TIMG_T1ALARMLO_REG 0x0034 // RW |
| 26 | +#define TIMG_T1ALARMHI_REG 0x0038 // RW |
| 27 | +#define TIMG_T1LOADLO_REG 0x003c // RW |
| 28 | +#define TIMG_T1LOADHI_REG 0x0040 // RW |
| 29 | +#define TIMG_T1LOAD_REG 0x0044 // WO |
| 30 | + |
| 31 | +#define TIMG_T_WDTCONFIG0_REG 0x0048 // RW |
| 32 | +#define TIMG_T_WDTCONFIG1_REG 0x004c // RW, Clock prescale * 12.5ns |
| 33 | +#define TIMG_T_WDTCONFIG2_REG 0x0050 // RW |
| 34 | +#define TIMG_T_WDTCONFIG3_REG 0x0054 // RW |
| 35 | +#define TIMG_T_WDTCONFIG4_REG 0x0058 // RW |
| 36 | +#define TIMG_T_WDTCONFIG5_REG 0x005c // RW |
| 37 | +#define TIMG_T_WDTFEED_REG 0x0060 // WO |
| 38 | +#define TIMG_T_WDTWPROTECT_REG 0x0064 // RW |
| 39 | + |
| 40 | +#define TIMG_RTCCALICFG_REG 0x0068 // varies |
| 41 | +#define TIMG_RTCCALICFG1_REG 0x006c // RO |
| 42 | + |
| 43 | +#define TIMG_T_INT_ENA_REG 0x0098 // RW |
| 44 | +#define TIMG_T_INT_RAW_REG 0x009c // RO |
| 45 | +#define TIMG_T_INT_ST_REG 0x00a0 // RO |
| 46 | +#define TIMG_T_INT_CLR_REG 0x00a4 // WO |
| 47 | + |
| 48 | +// TIMG_TxCONFIG_REG |
| 49 | +#define TIMG_Tx_EN 0x80000000 // Enable the timer |
| 50 | +#define TIMG_Tx_INCREASE 0x40000000 // Timer value increases every clock tick |
| 51 | +#define TIMG_Tx_AUTORELOAD 0x20000000 // Reload timer upon alarm |
| 52 | +#define TIMG_Tx_DIVIDER 0x1ffff000 // Clock prescale value |
| 53 | +#define TIMG_Tx_EDGE_INT_EN 0x00000800 // Alarm generates edge interrupt |
| 54 | +#define TIMG_Tx_LEVEL_INT_EN 0x00000400 // Alarm generates level interrupt |
| 55 | +#define TIMG_Tx_ALARM_EN 0x00000200 // Alarm enable |
| 56 | + |
| 57 | +// TIMG_T_WDTCONFIG0_REG |
| 58 | +#define TIMG_T_WDT_EN 0x80000000 // Enable MWDT |
| 59 | + |
| 60 | +#define TIMG_T_WDT_STG0 0x60000000 // Stage 0 configuration |
| 61 | +#define TIMG_T_WDT_STG0_RST_SYSTEM 0x60000000 |
| 62 | +#define TIMG_T_WDT_STG0_RST_CPU 0x40000000 |
| 63 | +#define TIMG_T_WDT_STG0_INTERRUPT 0x20000000 |
| 64 | +#define TIMG_T_WDT_STG0_OFF 0x00000000 |
| 65 | + |
| 66 | +#define TIMG_T_WDT_STG1 0x18000000 // Stage 1 configuration |
| 67 | +#define TIMG_T_WDT_STG1_RST_SYSTEM 0x18000000 |
| 68 | +#define TIMG_T_WDT_STG1_RST_CPU 0x10000000 |
| 69 | +#define TIMG_T_WDT_STG1_INTERRUPT 0x08000000 |
| 70 | +#define TIMG_T_WDT_STG1_OFF 0x00000000 |
| 71 | + |
| 72 | +#define TIMG_T_WDT_STG2 0x06000000 // Stage 2 configuration |
| 73 | +#define TIMG_T_WDT_STG2_RST_SYSTEM 0x06000000 |
| 74 | +#define TIMG_T_WDT_STG2_RST_CPU 0x04000000 |
| 75 | +#define TIMG_T_WDT_STG2_INTERRUPT 0x02000000 |
| 76 | +#define TIMG_T_WDT_STG2_OFF 0x00000000 |
| 77 | + |
| 78 | +#define TIMG_T_WDT_STG3 0x01800000 // Stage 3 configuration |
| 79 | +#define TIMG_T_WDT_STG3_RST_SYSTEM 0x01800000 |
| 80 | +#define TIMG_T_WDT_STG3_RST_CPU 0x01000000 |
| 81 | +#define TIMG_T_WDT_STG3_INTERRUPT 0x00800000 |
| 82 | +#define TIMG_T_WDT_STG3_OFF 0x00000000 |
| 83 | + |
| 84 | +#define TIMG_T_WDT_EDGE_INT_EN 0x00400000 // Enable edge interrupts |
| 85 | +#define TIMG_T_WDT_LEVEL_INT_EN 0x00200000 // Enable level interrupts |
| 86 | + |
| 87 | +#define TIMG_T_WDT_CPU_RESET_LENGTH 0x001c0000 // CPU reset pulse width |
| 88 | +#define TIMG_T_WDT_CPU_RESET_3200ns 0x001c0000 |
| 89 | +#define TIMG_T_WDT_CPU_RESET_1600ns 0x00180000 |
| 90 | +#define TIMG_T_WDT_CPU_RESET_800ns 0x00140000 |
| 91 | +#define TIMG_T_WDT_CPU_RESET_500ns 0x00100000 |
| 92 | +#define TIMG_T_WDT_CPU_RESET_400ns 0x000c0000 |
| 93 | +#define TIMG_T_WDT_CPU_RESET_300ns 0x00080000 |
| 94 | +#define TIMG_T_WDT_CPU_RESET_200ns 0x00040000 |
| 95 | +#define TIMG_T_WDT_CPU_RESET_100ns 0x00000000 |
| 96 | + |
| 97 | +#define TIMG_T_WDT_SYS_RESET_LENGTH 0x00038000 // System reset pulse width |
| 98 | +#define TIMG_T_WDT_SYS_RESET_3200ns 0x00038000 |
| 99 | +#define TIMG_T_WDT_SYS_RESET_1600ns 0x00030000 |
| 100 | +#define TIMG_T_WDT_SYS_RESET_800ns 0x00028000 |
| 101 | +#define TIMG_T_WDT_SYS_RESET_500ns 0x00020000 |
| 102 | +#define TIMG_T_WDT_SYS_RESET_400ns 0x00018000 |
| 103 | +#define TIMG_T_WDT_SYS_RESET_300ns 0x00010000 |
| 104 | +#define TIMG_T_WDT_SYS_RESET_200ns 0x00008000 |
| 105 | +#define TIMG_T_WDT_SYS_RESET_100ns 0x00000000 |
| 106 | + |
| 107 | +#define TIMG_T_WDT_FLASHBOOT_MOD_EN 0x00004000 |
| 108 | + |
| 109 | +double printClockPeriod(uint32_t config) |
| 110 | +{ |
| 111 | + uint32_t clocks; |
| 112 | + double clockPeriod; |
| 113 | + double multiplier; |
| 114 | + const char * units; |
| 115 | + |
| 116 | + clocks = config >> 16; |
| 117 | + clockPeriod = 0.0000000125 * clocks; |
| 118 | + if (clockPeriod >= 1.) |
| 119 | + { |
| 120 | + units = "Sec"; |
| 121 | + multiplier = 1; |
| 122 | + } |
| 123 | + else if (clockPeriod >= 0.001) |
| 124 | + { |
| 125 | + units = "mSec"; |
| 126 | + multiplier = 1000.; |
| 127 | + } |
| 128 | + else if (clockPeriod >= 0.000001) |
| 129 | + { |
| 130 | + units = "uSec"; |
| 131 | + multiplier = 1000000; |
| 132 | + } |
| 133 | + else |
| 134 | + { |
| 135 | + units = "nSec"; |
| 136 | + multiplier = 1000000000.; |
| 137 | + } |
| 138 | + systemPrintf(" Clock period: %7.3f %s (%d - 12.5 nSec clocks)", clockPeriod * multiplier, units, clocks); |
| 139 | + return clockPeriod; |
| 140 | +} |
| 141 | + |
| 142 | +void printWdtTimeout(double clockPeriod, uint32_t clocks) |
| 143 | +{ |
| 144 | + double multiplier; |
| 145 | + double timeout; |
| 146 | + const char * units; |
| 147 | + |
| 148 | + timeout = clockPeriod * (double)clocks; |
| 149 | + if (timeout >= 1.) |
| 150 | + { |
| 151 | + units = "Sec"; |
| 152 | + multiplier = 1; |
| 153 | + } |
| 154 | + else if (timeout >= 0.001) |
| 155 | + { |
| 156 | + units = "mSec"; |
| 157 | + multiplier = 1000.; |
| 158 | + } |
| 159 | + else if (timeout >= 0.000000) |
| 160 | + { |
| 161 | + units = "uSec"; |
| 162 | + multiplier = 1000000.; |
| 163 | + } |
| 164 | + else |
| 165 | + { |
| 166 | + units = "nSec"; |
| 167 | + multiplier = 1000000000.; |
| 168 | + } |
| 169 | + systemPrintf(", timeout: %5.1f %s (%d clocks)\r\n", timeout * multiplier, units, clocks); |
| 170 | +} |
| 171 | + |
| 172 | +void printWdt(intptr_t baseAddress) |
| 173 | +{ |
| 174 | + double clockPeriod; |
| 175 | + const char * const config[] = |
| 176 | + { |
| 177 | + "Off", |
| 178 | + "Interrupt", |
| 179 | + "Reset CPU", |
| 180 | + "Reset System" |
| 181 | + }; |
| 182 | + uint32_t protect; |
| 183 | + const int pulseWidth[] = {100, 200, 300, 400, 500, 800, 1600, 3200}; |
| 184 | + uint32_t value[6]; |
| 185 | + |
| 186 | + systemPrintf("0x%08x: Watch Dog Timer\r\n", baseAddress); |
| 187 | + value[0] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG0_REG); |
| 188 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG0_REG\r\n", value[0]); |
| 189 | + value[1] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG1_REG); |
| 190 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG1_REG\r\n", value[1]); |
| 191 | + value[2] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG2_REG); |
| 192 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG2_REG\r\n", value[2]); |
| 193 | + value[3] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG3_REG); |
| 194 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG3_REG\r\n", value[3]); |
| 195 | + value[4] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG4_REG); |
| 196 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG4_REG\r\n", value[4]); |
| 197 | + value[5] = *(uint32_t *)(baseAddress + TIMG_T_WDTCONFIG5_REG); |
| 198 | + systemPrintf(" 0x%08x: TIMG_T_WDTCONFIG5_REG\r\n", value[5]); |
| 199 | + protect = *(uint32_t *)(baseAddress + TIMG_T_WDTWPROTECT_REG); |
| 200 | + systemPrintf(" 0x%08x: TIMG_T_WDTWPROTECT_REG\r\n", protect); |
| 201 | + |
| 202 | + if (value[0] & TIMG_T_WDT_EN) |
| 203 | + { |
| 204 | + // TIMG_T_WDTCONFIG0_REG |
| 205 | + systemPrintf(" Watch dog enabled\r\n"); |
| 206 | + clockPeriod = printClockPeriod(value[1]); |
| 207 | + systemPrintf(" Stage %d: %s", 0, config[(value[0] >> 29) & 3]); |
| 208 | + if (value[0] & TIMG_T_WDT_STG0_RST_SYSTEM) |
| 209 | + printWdtTimeout(clockPeriod, value[2]); |
| 210 | + systemPrintf("\r\n"); |
| 211 | + systemPrintf(" Stage %d: %s", 1, config[(value[0] >> 27) & 3]); |
| 212 | + if (value[0] & TIMG_T_WDT_STG1_RST_SYSTEM) |
| 213 | + printWdtTimeout(clockPeriod, value[3]); |
| 214 | + systemPrintf("\r\n"); |
| 215 | + systemPrintf(" Stage %d: %s", 2, config[(value[0] >> 25) & 3]); |
| 216 | + if (value[0] & TIMG_T_WDT_STG2_RST_SYSTEM) |
| 217 | + printWdtTimeout(clockPeriod, value[4]); |
| 218 | + systemPrintf("\r\n"); |
| 219 | + systemPrintf(" Stage %d: %s", 3, config[(value[0] >> 23) & 3]); |
| 220 | + if (value[0] & TIMG_T_WDT_STG3_RST_SYSTEM) |
| 221 | + printWdtTimeout(clockPeriod, value[5]); |
| 222 | + systemPrintf("\r\n"); |
| 223 | + if ((value[0] & TIMG_T_WDT_STG0_INTERRUPT) |
| 224 | + || (value[0] & TIMG_T_WDT_STG1_INTERRUPT) |
| 225 | + || (value[0] & TIMG_T_WDT_STG2_INTERRUPT) |
| 226 | + || (value[0] & TIMG_T_WDT_STG3_INTERRUPT)) |
| 227 | + { |
| 228 | + if (value[0] & TIMG_T_WDT_EDGE_INT_EN) |
| 229 | + systemPrintf(" Generate edge interrupt\r\n"); |
| 230 | + if (value[0] & TIMG_T_WDT_LEVEL_INT_EN) |
| 231 | + systemPrintf(" Generate level interrupt\r\n"); |
| 232 | + } |
| 233 | + if (((value[0] & TIMG_T_WDT_STG0_RST_SYSTEM) == TIMG_T_WDT_STG0_RST_CPU) |
| 234 | + || ((value[0] & TIMG_T_WDT_STG1_RST_SYSTEM) == TIMG_T_WDT_STG1_RST_CPU) |
| 235 | + || ((value[0] & TIMG_T_WDT_STG2_RST_SYSTEM) == TIMG_T_WDT_STG2_RST_CPU) |
| 236 | + || ((value[0] & TIMG_T_WDT_STG3_RST_SYSTEM) == TIMG_T_WDT_STG3_RST_CPU)) |
| 237 | + { |
| 238 | + systemPrintf(" CPU reset pulse: %d nSec\r\n", pulseWidth[(value[0] >> 18) & 7]); |
| 239 | + } |
| 240 | + if (((value[0] & TIMG_T_WDT_STG0_RST_SYSTEM) == TIMG_T_WDT_STG0_RST_SYSTEM) |
| 241 | + || ((value[0] & TIMG_T_WDT_STG1_RST_SYSTEM) == TIMG_T_WDT_STG1_RST_SYSTEM) |
| 242 | + || ((value[0] & TIMG_T_WDT_STG2_RST_SYSTEM) == TIMG_T_WDT_STG2_RST_SYSTEM) |
| 243 | + || ((value[0] & TIMG_T_WDT_STG3_RST_SYSTEM) == TIMG_T_WDT_STG3_RST_SYSTEM)) |
| 244 | + { |
| 245 | + systemPrintf(" System reset pulse: %d nSec\r\n", pulseWidth[(value[0] >> 15) & 7]); |
| 246 | + } |
| 247 | + if (value[0] & TIMG_T_WDT_FLASHBOOT_MOD_EN) |
| 248 | + systemPrintf(" Flash boot protection enabled\r\n"); |
| 249 | + } |
| 250 | + else |
| 251 | + systemPrintf(" Watch dog disabled\r\n"); |
| 252 | +} |
| 253 | + |
| 254 | +#endif // __ESP32_TIMER_H__ |
0 commit comments