Browse Source

Fix and add STM32 SDIO DMA (#21476)

Victor Oliveira 4 years ago
parent
commit
6e0b79a33b
No account linked to committer's email address
2 changed files with 197 additions and 123 deletions
  1. 117
    98
      Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
  2. 80
    25
      Marlin/src/gcode/gcode_d.cpp

+ 117
- 98
Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp View File

36
 
36
 
37
   // use USB drivers
37
   // use USB drivers
38
 
38
 
39
-  extern "C" { int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
40
-               int8_t SD_MSC_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
41
-               extern SD_HandleTypeDef hsd;
39
+  extern "C" {
40
+    int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
41
+    int8_t SD_MSC_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
42
+    extern SD_HandleTypeDef hsd;
42
   }
43
   }
43
 
44
 
44
   bool SDIO_Init() {
45
   bool SDIO_Init() {
75
     #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
76
     #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
76
   #endif
77
   #endif
77
 
78
 
79
+  // Fixed
80
+  #define SDIO_D0_PIN   PC8
81
+  #define SDIO_D1_PIN   PC9
82
+  #define SDIO_D2_PIN   PC10
83
+  #define SDIO_D3_PIN   PC11
84
+  #define SDIO_CK_PIN   PC12
85
+  #define SDIO_CMD_PIN  PD2
86
+
78
   SD_HandleTypeDef hsd;  // create SDIO structure
87
   SD_HandleTypeDef hsd;  // create SDIO structure
88
+  // F4 support one dma for RX and another for TX.
89
+  // But Marlin will never do read and write at same time, so we use always one dma for both.
90
+  DMA_HandleTypeDef hdma_sdio;
79
 
91
 
80
   /*
92
   /*
81
     SDIO_INIT_CLK_DIV is 118
93
     SDIO_INIT_CLK_DIV is 118
96
 
108
 
97
   // Target Clock, configurable. Default is 18MHz, from STM32F1
109
   // Target Clock, configurable. Default is 18MHz, from STM32F1
98
   #ifndef SDIO_CLOCK
110
   #ifndef SDIO_CLOCK
99
-    #define SDIO_CLOCK                         18000000       /* 18 MHz */
111
+    #define SDIO_CLOCK 18000000 // 18 MHz
100
   #endif
112
   #endif
101
 
113
 
102
   // SDIO retries, configurable. Default is 3, from STM32F1
114
   // SDIO retries, configurable. Default is 3, from STM32F1
103
   #ifndef SDIO_READ_RETRIES
115
   #ifndef SDIO_READ_RETRIES
104
-    #define SDIO_READ_RETRIES                  3
116
+    #define SDIO_READ_RETRIES 3
105
   #endif
117
   #endif
106
 
118
 
107
   // SDIO Max Clock (naming from STM Manual, don't change)
119
   // SDIO Max Clock (naming from STM Manual, don't change)
120
   }
132
   }
121
 
133
 
122
   void go_to_transfer_speed() {
134
   void go_to_transfer_speed() {
123
-    SD_InitTypeDef Init;
124
-
125
     /* Default SDIO peripheral configuration for SD card initialization */
135
     /* Default SDIO peripheral configuration for SD card initialization */
126
-    Init.ClockEdge           = hsd.Init.ClockEdge;
127
-    Init.ClockBypass         = hsd.Init.ClockBypass;
128
-    Init.ClockPowerSave      = hsd.Init.ClockPowerSave;
129
-    Init.BusWide             = hsd.Init.BusWide;
130
-    Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
131
-    Init.ClockDiv            = clock_to_divider(SDIO_CLOCK);
136
+    hsd.Init.ClockEdge           = hsd.Init.ClockEdge;
137
+    hsd.Init.ClockBypass         = hsd.Init.ClockBypass;
138
+    hsd.Init.ClockPowerSave      = hsd.Init.ClockPowerSave;
139
+    hsd.Init.BusWide             = hsd.Init.BusWide;
140
+    hsd.Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
141
+    hsd.Init.ClockDiv            = clock_to_divider(SDIO_CLOCK);
132
 
142
 
133
     /* Initialize SDIO peripheral interface with default configuration */
143
     /* Initialize SDIO peripheral interface with default configuration */
134
-    SDIO_Init(hsd.Instance, Init);
144
+    SDIO_Init(hsd.Instance, hsd.Init);
135
   }
145
   }
136
 
146
 
137
   void SD_LowLevel_Init(void) {
147
   void SD_LowLevel_Init(void) {
138
     uint32_t tempreg;
148
     uint32_t tempreg;
139
 
149
 
140
-    __HAL_RCC_SDIO_CLK_ENABLE();
141
     __HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
150
     __HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
142
     __HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
151
     __HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
143
 
152
 
163
     GPIO_InitStruct.Pin = GPIO_PIN_2;
172
     GPIO_InitStruct.Pin = GPIO_PIN_2;
164
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
173
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
165
 
174
 
166
-    #if DISABLED(STM32F1xx)
167
-      // TODO: use __HAL_RCC_SDIO_RELEASE_RESET() and __HAL_RCC_SDIO_CLK_ENABLE();
168
-      RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk;  // take SDIO out of reset
169
-      RCC->APB2ENR  |=  RCC_APB2RSTR_SDIORST_Msk;  // enable SDIO clock
170
-      // Enable the DMA2 Clock
175
+    // Setup DMA
176
+    #if defined(STM32F1xx)
177
+      hdma_sdio.Init.Mode = DMA_NORMAL;
178
+      hdma_sdio.Instance = DMA2_Channel4;
179
+      HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
180
+    #elif defined(STM32F4xx)
181
+      hdma_sdio.Init.Mode = DMA_PFCTRL;
182
+      hdma_sdio.Instance = DMA2_Stream3;
183
+      hdma_sdio.Init.Channel = DMA_CHANNEL_4;
184
+      hdma_sdio.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
185
+      hdma_sdio.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
186
+      hdma_sdio.Init.MemBurst = DMA_MBURST_INC4;
187
+      hdma_sdio.Init.PeriphBurst = DMA_PBURST_INC4;
188
+      HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
189
+    #endif
190
+    HAL_NVIC_EnableIRQ(SDIO_IRQn);
191
+    hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
192
+    hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
193
+    hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
194
+    hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
195
+    hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
196
+    __HAL_LINKDMA(&hsd, hdmarx, hdma_sdio);
197
+    __HAL_LINKDMA(&hsd, hdmatx, hdma_sdio);
198
+
199
+    #if defined(STM32F1xx)
200
+      __HAL_RCC_SDIO_CLK_ENABLE();
201
+      __HAL_RCC_DMA2_CLK_ENABLE();
202
+    #else
203
+      __HAL_RCC_SDIO_FORCE_RESET();
204
+      delay(2);
205
+      __HAL_RCC_SDIO_RELEASE_RESET();
206
+      delay(2);
207
+      __HAL_RCC_SDIO_CLK_ENABLE();
208
+
209
+      __HAL_RCC_DMA2_FORCE_RESET();
210
+      delay(2);
211
+      __HAL_RCC_DMA2_RELEASE_RESET();
212
+      delay(2);
213
+      __HAL_RCC_DMA2_CLK_ENABLE();
171
     #endif
214
     #endif
172
 
215
 
173
     //Initialize the SDIO (with initial <400Khz Clock)
216
     //Initialize the SDIO (with initial <400Khz Clock)
179
 
222
 
180
     // Power up the SDIO
223
     // Power up the SDIO
181
     SDIO_PowerState_ON(SDIO);
224
     SDIO_PowerState_ON(SDIO);
225
+    hsd.Instance = SDIO;
182
   }
226
   }
183
 
227
 
184
   void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
228
   void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
222
           if (!status) break;
266
           if (!status) break;
223
           if (!--retry_Cnt) return false;   // return failing status if retries are exhausted
267
           if (!--retry_Cnt) return false;   // return failing status if retries are exhausted
224
         }
268
         }
269
+        go_to_transfer_speed();
225
       }
270
       }
226
     #endif
271
     #endif
227
 
272
 
228
     return true;
273
     return true;
229
   }
274
   }
230
-  /*
231
-  void init_SDIO_pins(void) {
232
-    GPIO_InitTypeDef GPIO_InitStruct = {0};
233
-
234
-    // SDIO GPIO Configuration
235
-    // PC8     ------> SDIO_D0
236
-    // PC12    ------> SDIO_CK
237
-    // PD2     ------> SDIO_CMD
238
-
239
-    GPIO_InitStruct.Pin = GPIO_PIN_8;
240
-    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
241
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
242
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
243
-    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
244
-    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
245
-
246
-    GPIO_InitStruct.Pin = GPIO_PIN_12;
247
-    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
248
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
249
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
250
-    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
251
-    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
252
 
275
 
253
-    GPIO_InitStruct.Pin = GPIO_PIN_2;
254
-    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
255
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
256
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
257
-    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
258
-    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
259
-  }
260
-  */
261
-  //bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
262
-  //bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
276
+  static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) {
277
+    if(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;
263
 
278
 
264
-  bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
265
-    hsd.Instance = SDIO;
266
-    uint8_t retryCnt = SDIO_READ_RETRIES;
279
+    TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
267
 
280
 
268
-    bool status;
269
-    for (;;) {
270
-      TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
271
-      status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000);  // read one 512 byte block with 500mS timeout
272
-      status |= (bool) HAL_SD_GetCardState(&hsd);     // make sure all is OK
273
-      if (!status) break;       // return passing status
274
-      if (!--retryCnt) break;   // return failing status if retries are exhausted
281
+    HAL_StatusTypeDef ret;
282
+    if (src) {
283
+      hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
284
+      HAL_DMA_Init(&hdma_sdio);
285
+      ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1);
286
+    }
287
+    else {
288
+      hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
289
+      HAL_DMA_Init(&hdma_sdio);
290
+      ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1);
275
     }
291
     }
276
-    return status;
277
-
278
-    /*
279
-    return (bool) ((status_read | status_card) ? 1 : 0);
280
-
281
-    if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false;
282
-    if (blockAddress >= SdCard.LogBlockNbr) return false;
283
-    if ((0x03 & (uint32_t)data)) return false; // misaligned data
284
-
285
-    if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; }
286
 
292
 
287
-    if (!SDIO_CmdReadSingleBlock(blockAddress)) {
288
-      SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS);
289
-      dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL);
293
+    if (ret != HAL_OK) {
294
+      HAL_DMA_Abort_IT(&hdma_sdio);
295
+      HAL_DMA_DeInit(&hdma_sdio);
290
       return false;
296
       return false;
291
     }
297
     }
292
 
298
 
293
-    while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {}
299
+    uint32_t timeout = millis() + 500;
300
+    // Wait the transfer
301
+    while (hsd.State != HAL_SD_STATE_READY) {
302
+      if (millis() > timeout) {
303
+        HAL_DMA_Abort_IT(&hdma_sdio);
304
+        HAL_DMA_DeInit(&hdma_sdio);
305
+        return false;
306
+      }
307
+    }
294
 
308
 
295
-    dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL);
309
+    while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
310
+        || __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }
296
 
311
 
297
-    if (SDIO->STA & SDIO_STA_RXDAVL) {
298
-      while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO;
299
-      SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
300
-      return false;
301
-    }
312
+    HAL_DMA_Abort_IT(&hdma_sdio);
313
+    HAL_DMA_DeInit(&hdma_sdio);
302
 
314
 
303
-    if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) {
304
-      SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
305
-      return false;
306
-    }
307
-    SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
308
-    */
315
+    timeout = millis() + 500;
316
+    while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
317
+      if (millis() > timeout) return false;
309
 
318
 
310
     return true;
319
     return true;
311
   }
320
   }
312
 
321
 
322
+  bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
323
+    uint8_t retries = SDIO_READ_RETRIES;
324
+    while (retries--) if (SDIO_ReadWriteBlock_DMA(block, NULL, dst)) return true;
325
+    return false;
326
+  }
327
+
313
   bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
328
   bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
314
-    hsd.Instance = SDIO;
315
-    uint8_t retryCnt = SDIO_READ_RETRIES;
316
-    bool status;
317
-    for (;;) {
318
-      status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500);  // write one 512 byte block with 500mS timeout
319
-      status |= (bool) HAL_SD_GetCardState(&hsd);     // make sure all is OK
320
-      if (!status) break;       // return passing status
321
-      if (!--retryCnt) break;   // return failing status if retries are exhausted
322
-    }
323
-    return status;
329
+    uint8_t retries = SDIO_READ_RETRIES;
330
+    while (retries--) if (SDIO_ReadWriteBlock_DMA(block, src, NULL)) return true;
331
+    return false;
324
   }
332
   }
325
 
333
 
334
+  #if defined(STM32F1xx)
335
+    #define DMA_IRQ_HANDLER DMA2_Channel4_5_IRQHandler
336
+  #elif defined(STM32F4xx)
337
+    #define DMA_IRQ_HANDLER DMA2_Stream3_IRQHandler
338
+  #else
339
+    #error "Unknown STM32 architecture."
340
+  #endif
341
+
342
+  extern "C" void SDIO_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); }
343
+  extern "C" void DMA_IRQ_HANDLER(void) { HAL_DMA_IRQHandler(&hdma_sdio); }
344
+
326
 #endif // !USBD_USE_CDC_COMPOSITE
345
 #endif // !USBD_USE_CDC_COMPOSITE
327
 #endif // SDIO_SUPPORT
346
 #endif // SDIO_SUPPORT
328
 #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
347
 #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC

+ 80
- 25
Marlin/src/gcode/gcode_d.cpp View File

29
   #include "../libs/hex_print.h"
29
   #include "../libs/hex_print.h"
30
   #include "../HAL/shared/eeprom_if.h"
30
   #include "../HAL/shared/eeprom_if.h"
31
   #include "../HAL/shared/Delay.h"
31
   #include "../HAL/shared/Delay.h"
32
+  #include "../sd/cardreader.h"
32
 
33
 
33
   extern void dump_delay_accuracy_check();
34
   extern void dump_delay_accuracy_check();
34
 
35
 
126
       #endif
127
       #endif
127
 
128
 
128
       case 4: { // D4 Read / Write PIN
129
       case 4: { // D4 Read / Write PIN
129
-        // const uint8_t pin = parser.byteval('P');
130
-        // const bool is_out = parser.boolval('F'),
131
-        //            val = parser.byteval('V', LOW);
130
+        //const bool is_out = parser.boolval('F');
131
+        //const uint8_t pin = parser.byteval('P'),
132
+        //              val = parser.byteval('V', LOW);
132
         if (parser.seenval('X')) {
133
         if (parser.seenval('X')) {
133
           // TODO: Write the hex bytes after the X
134
           // TODO: Write the hex bytes after the X
134
           //while (len--) {
135
           //while (len--) {
135
           //}
136
           //}
136
         }
137
         }
137
         else {
138
         else {
138
-          // while (len--) {
139
-            // TODO: Read bytes from EEPROM
140
-            // print_hex_byte(eeprom_read_byte(*(adr++));
141
-          // }
139
+          //while (len--) {
140
+          //// TODO: Read bytes from EEPROM
141
+          //  print_hex_byte(eeprom_read_byte(adr++));
142
+          //}
142
           SERIAL_EOL();
143
           SERIAL_EOL();
143
         }
144
         }
144
       } break;
145
       } break;
155
           //while (len--) {}
156
           //while (len--) {}
156
         }
157
         }
157
         else {
158
         else {
158
-          // while (len--) {
159
-            // TODO: Read bytes from EEPROM
160
-            // print_hex_byte(eeprom_read_byte(adr++));
161
-          // }
159
+          //while (len--) {
160
+          //// TODO: Read bytes from EEPROM
161
+          //  print_hex_byte(eeprom_read_byte(adr++));
162
+          //}
162
           SERIAL_EOL();
163
           SERIAL_EOL();
163
         }
164
         }
164
       } break;
165
       } break;
186
         SERIAL_ECHOLNPGM("FAILURE: Watchdog did not trigger board reset.");
187
         SERIAL_ECHOLNPGM("FAILURE: Watchdog did not trigger board reset.");
187
       } break;
188
       } break;
188
 
189
 
190
+      #if ENABLED(SDSUPPORT)
191
+
192
+        case 101: { // D101 Test SD Write
193
+          card.openFileWrite("test.gco");
194
+          if (!card.isFileOpen()) {
195
+            SERIAL_ECHOLNPAIR("Failed to open test.gco to write.");
196
+            return;
197
+          }
198
+          __attribute__((aligned(sizeof(size_t)))) uint8_t buf[512];
199
+
200
+          uint16_t c;
201
+          for (c = 0; c < COUNT(buf); c++)
202
+            buf[c] = 'A' + (c % ('Z' - 'A'));
203
+
204
+          c = 1024 * 4;
205
+          while (c--) {
206
+            TERN_(USE_WATCHDOG, watchdog_refresh());
207
+            card.write(buf, COUNT(buf));
208
+          }
209
+          SERIAL_ECHOLNPGM(" done");
210
+          card.closefile();
211
+        } break;
212
+
213
+        case 102: { // D102 Test SD Read
214
+          card.openFileRead("test.gco");
215
+          if (!card.isFileOpen()) {
216
+            SERIAL_ECHOLNPAIR("Failed to open test.gco to read.");
217
+            return;
218
+          }
219
+          __attribute__((aligned(sizeof(size_t)))) uint8_t buf[512];
220
+          uint16_t c = 1024 * 4;
221
+          while (c--) {
222
+            TERN_(USE_WATCHDOG, watchdog_refresh());
223
+            card.read(buf, COUNT(buf));
224
+            bool error = false;
225
+            for (uint16_t i = 0; i < COUNT(buf); i++) {
226
+              if (buf[i] != ('A' + (i % ('Z' - 'A')))) {
227
+                error = true;
228
+                break;
229
+              }
230
+            }
231
+            if (error) {
232
+              SERIAL_ECHOLNPGM(" Read error!");
233
+              break;
234
+            }
235
+          }
236
+          SERIAL_ECHOLNPGM(" done");
237
+          card.closefile();
238
+        } break;
239
+
240
+      #endif // SDSUPPORT
241
+
189
       #if ENABLED(POSTMORTEM_DEBUGGING)
242
       #if ENABLED(POSTMORTEM_DEBUGGING)
190
-      case 451: { // Trigger all kind of faults to test exception catcher
191
-        SERIAL_ECHOLNPGM("Disabling heaters");
192
-        thermalManager.disable_all_heaters();
193
-        delay(1000); // Allow time to print
194
-        volatile uint8_t type[5] = { parser.byteval('T', 1) };
195
-
196
-        // The code below is obviously wrong and it's full of quirks to fool the compiler from optimizing away the code
197
-        switch (type[0]) {
198
-          case 1: default: *(int*)0 = 451; break; // Write at bad address
199
-          case 2: { volatile int a = 0; volatile int b = 452 / a; *(int*)&a = b; } break; // Divide by zero (some CPUs accept this, like ARM)
200
-          case 3: { *(uint32_t*)&type[1] = 453; volatile int a = *(int*)&type[1]; type[0] = a / 255; } break; // Unaligned access (some CPUs accept this)
201
-          case 4: { volatile void (*func)() = (volatile void (*)()) 0xE0000000; func(); } break; // Invalid instruction
243
+
244
+        case 451: { // Trigger all kind of faults to test exception catcher
245
+          SERIAL_ECHOLNPGM("Disabling heaters");
246
+          thermalManager.disable_all_heaters();
247
+          delay(1000); // Allow time to print
248
+          volatile uint8_t type[5] = { parser.byteval('T', 1) };
249
+
250
+          // The code below is obviously wrong and it's full of quirks to fool the compiler from optimizing away the code
251
+          switch (type[0]) {
252
+            case 1: default: *(int*)0 = 451; break; // Write at bad address
253
+            case 2: { volatile int a = 0; volatile int b = 452 / a; *(int*)&a = b; } break; // Divide by zero (some CPUs accept this, like ARM)
254
+            case 3: { *(uint32_t*)&type[1] = 453; volatile int a = *(int*)&type[1]; type[0] = a / 255; } break; // Unaligned access (some CPUs accept this)
255
+            case 4: { volatile void (*func)() = (volatile void (*)()) 0xE0000000; func(); } break; // Invalid instruction
256
+          }
257
+          break;
202
         }
258
         }
203
-        break;
204
-      }
259
+
205
       #endif
260
       #endif
206
     }
261
     }
207
   }
262
   }

Loading…
Cancel
Save