Browse Source

usb and sdcard sharing improvements

* Add traceback after watchdog timeout

Add the cpability to perform a traceback following a watchdog timeout.

* Enhanced hardware SPI

Allow use of either SSP0 or SSP1.
Ensure that no data is left in I/O buffers after calls to enable sharing of SSP hardware.

* Make flash emulation of eeprom the default

Make use of flash for eeprom storage the default. This means that usage of eeprom will not cause USB drive mount/unmount operations.

* Allow sharing of SD card

SD card I/O operations from the USB stack take place in idle loop, rather than at interrupt time. Allowing sharing of the SPI bus.

New configuration options to allow usage of the SD card to be specified.

* Fix problem with hardware SPI pins
Andy Shaw 6 years ago
parent
commit
870bfd08f5

+ 318
- 0
Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp View File

@@ -0,0 +1,318 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifdef TARGET_LPC1768
24
+
25
+#include "../../core/macros.h"
26
+#include "../../core/serial.h"
27
+#include <stdarg.h>
28
+
29
+#include "../shared/backtrace/unwinder.h"
30
+#include "../shared/backtrace/unwmemaccess.h"
31
+#include "watchdog.h"
32
+#include <debug_frmwrk.h>
33
+
34
+
35
+// Debug monitor that dumps to the Programming port all status when
36
+// an exception or WDT timeout happens - And then resets the board
37
+
38
+// All the Monitor routines must run with interrupts disabled and
39
+// under an ISR execution context. That is why we cannot reuse the
40
+// Serial interrupt routines or any C runtime, as we don't know the
41
+// state we are when running them
42
+
43
+// A SW memory barrier, to ensure GCC does not overoptimize loops
44
+#define sw_barrier() __asm__ volatile("": : :"memory");
45
+
46
+// (re)initialize UART0 as a monitor output to 250000,n,8,1
47
+static void TXBegin(void) {
48
+}
49
+
50
+// Send character through UART with no interrupts
51
+static void TX(char c) {
52
+  _DBC(c);
53
+}
54
+
55
+// Send String through UART
56
+static void TX(const char* s) {
57
+  while (*s) TX(*s++);
58
+}
59
+
60
+static void TXDigit(uint32_t d) {
61
+  if (d < 10) TX((char)(d+'0'));
62
+  else if (d < 16) TX((char)(d+'A'-10));
63
+  else TX('?');
64
+}
65
+
66
+// Send Hex number thru UART
67
+static void TXHex(uint32_t v) {
68
+  TX("0x");
69
+  for (uint8_t i = 0; i < 8; i++, v <<= 4)
70
+    TXDigit((v >> 28) & 0xF);
71
+}
72
+
73
+// Send Decimal number thru UART
74
+static void TXDec(uint32_t v) {
75
+  if (!v) {
76
+    TX('0');
77
+    return;
78
+  }
79
+
80
+  char nbrs[14];
81
+  char *p = &nbrs[0];
82
+  while (v != 0) {
83
+    *p++ = '0' + (v % 10);
84
+    v /= 10;
85
+  }
86
+  do {
87
+    p--;
88
+    TX(*p);
89
+  } while (p != &nbrs[0]);
90
+}
91
+
92
+// Dump a backtrace entry
93
+static bool UnwReportOut(void* ctx, const UnwReport* bte) {
94
+  int* p = (int*)ctx;
95
+
96
+  (*p)++;
97
+  TX('#'); TXDec(*p); TX(" : ");
98
+  TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
99
+  TX('+'); TXDec(bte->address - bte->function);
100
+  TX(" PC:");TXHex(bte->address); TX('\n');
101
+  return true;
102
+}
103
+
104
+#ifdef UNW_DEBUG
105
+  void UnwPrintf(const char* format, ...) {
106
+    char dest[256];
107
+    va_list argptr;
108
+    va_start(argptr, format);
109
+    vsprintf(dest, format, argptr);
110
+    va_end(argptr);
111
+    TX(&dest[0]);
112
+  }
113
+#endif
114
+
115
+/* Table of function pointers for passing to the unwinder */
116
+static const UnwindCallbacks UnwCallbacks = {
117
+  UnwReportOut,
118
+  UnwReadW,
119
+  UnwReadH,
120
+  UnwReadB
121
+  #if defined(UNW_DEBUG)
122
+   ,UnwPrintf
123
+  #endif
124
+};
125
+
126
+
127
+/**
128
+ * HardFaultHandler_C:
129
+ * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
130
+ * as the parameter. We can then read the values from the stack and place them
131
+ * into local variables for ease of reading.
132
+ * We then read the various Fault Status and Address Registers to help decode
133
+ * cause of the fault.
134
+ * The function ends with a BKPT instruction to force control back into the debugger
135
+ */
136
+extern "C"
137
+void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
138
+
139
+  static const char* causestr[] = {
140
+    "NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
141
+  };
142
+
143
+  UnwindFrame btf;
144
+
145
+  // Dump report to the Programming port (interrupts are DISABLED)
146
+  TXBegin();
147
+  TX("\n\n## Software Fault detected ##\n");
148
+  TX("Cause: "); TX(causestr[cause]); TX('\n');
149
+
150
+  TX("R0   : "); TXHex(((unsigned long)sp[0])); TX('\n');
151
+  TX("R1   : "); TXHex(((unsigned long)sp[1])); TX('\n');
152
+  TX("R2   : "); TXHex(((unsigned long)sp[2])); TX('\n');
153
+  TX("R3   : "); TXHex(((unsigned long)sp[3])); TX('\n');
154
+  TX("R12  : "); TXHex(((unsigned long)sp[4])); TX('\n');
155
+  TX("LR   : "); TXHex(((unsigned long)sp[5])); TX('\n');
156
+  TX("PC   : "); TXHex(((unsigned long)sp[6])); TX('\n');
157
+  TX("PSR  : "); TXHex(((unsigned long)sp[7])); TX('\n');
158
+
159
+  // Configurable Fault Status Register
160
+  // Consists of MMSR, BFSR and UFSR
161
+  TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
162
+
163
+  // Hard Fault Status Register
164
+  TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
165
+
166
+  // Debug Fault Status Register
167
+  TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
168
+
169
+  // Auxiliary Fault Status Register
170
+  TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
171
+
172
+  // Read the Fault Address Registers. These may not contain valid values.
173
+  // Check BFARVALID/MMARVALID to see if they are valid values
174
+  // MemManage Fault Address Register
175
+  TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
176
+
177
+  // Bus Fault Address Register
178
+  TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
179
+
180
+  TX("ExcLR: "); TXHex(lr); TX('\n');
181
+  TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
182
+
183
+  btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
184
+  btf.fp = btf.sp;
185
+  btf.lr = ((unsigned long)sp[5]);
186
+  btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
187
+
188
+  // Perform a backtrace
189
+  TX("\nBacktrace:\n\n");
190
+  int ctr = 0;
191
+  UnwindStart(&btf, &UnwCallbacks, &ctr);
192
+
193
+  // Disable all NVIC interrupts
194
+  NVIC->ICER[0] = 0xFFFFFFFF;
195
+  NVIC->ICER[1] = 0xFFFFFFFF;
196
+
197
+  // Relocate VTOR table to default position
198
+  SCB->VTOR = 0;
199
+
200
+  // Clear cause of reset to prevent entering smoothie bootstrap
201
+  HAL_clear_reset_source();
202
+  // Restart watchdog
203
+  //WDT_Restart(WDT);
204
+  watchdog_init();
205
+
206
+  // Reset controller
207
+  NVIC_SystemReset();
208
+
209
+  while(1) { watchdog_init(); }
210
+}
211
+
212
+extern "C" {
213
+__attribute__((naked)) void NMI_Handler(void) {
214
+  __asm__ __volatile__ (
215
+    ".syntax unified" "\n\t"
216
+    A("tst lr, #4")
217
+    A("ite eq")
218
+    A("mrseq r0, msp")
219
+    A("mrsne r0, psp")
220
+    A("mov r1,lr")
221
+    A("mov r2,#0")
222
+    A("b HardFault_HandlerC")
223
+  );
224
+}
225
+
226
+__attribute__((naked)) void HardFault_Handler(void) {
227
+  __asm__ __volatile__ (
228
+    ".syntax unified" "\n\t"
229
+    A("tst lr, #4")
230
+    A("ite eq")
231
+    A("mrseq r0, msp")
232
+    A("mrsne r0, psp")
233
+    A("mov r1,lr")
234
+    A("mov r2,#1")
235
+    A("b HardFault_HandlerC")
236
+  );
237
+}
238
+
239
+__attribute__((naked)) void MemManage_Handler(void) {
240
+  __asm__ __volatile__ (
241
+    ".syntax unified" "\n\t"
242
+    A("tst lr, #4")
243
+    A("ite eq")
244
+    A("mrseq r0, msp")
245
+    A("mrsne r0, psp")
246
+    A("mov r1,lr")
247
+    A("mov r2,#2")
248
+    A("b HardFault_HandlerC")
249
+  );
250
+}
251
+
252
+__attribute__((naked)) void BusFault_Handler(void) {
253
+  __asm__ __volatile__ (
254
+    ".syntax unified" "\n\t"
255
+    A("tst lr, #4")
256
+    A("ite eq")
257
+    A("mrseq r0, msp")
258
+    A("mrsne r0, psp")
259
+    A("mov r1,lr")
260
+    A("mov r2,#3")
261
+    A("b HardFault_HandlerC")
262
+  );
263
+}
264
+
265
+__attribute__((naked)) void UsageFault_Handler(void) {
266
+  __asm__ __volatile__ (
267
+    ".syntax unified" "\n\t"
268
+    A("tst lr, #4")
269
+    A("ite eq")
270
+    A("mrseq r0, msp")
271
+    A("mrsne r0, psp")
272
+    A("mov r1,lr")
273
+    A("mov r2,#4")
274
+    A("b HardFault_HandlerC")
275
+  );
276
+}
277
+
278
+__attribute__((naked)) void DebugMon_Handler(void) {
279
+  __asm__ __volatile__ (
280
+    ".syntax unified" "\n\t"
281
+    A("tst lr, #4")
282
+    A("ite eq")
283
+    A("mrseq r0, msp")
284
+    A("mrsne r0, psp")
285
+    A("mov r1,lr")
286
+    A("mov r2,#5")
287
+    A("b HardFault_HandlerC")
288
+  );
289
+}
290
+
291
+/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
292
+__attribute__((naked)) void WDT_IRQHandler(void) {
293
+  __asm__ __volatile__ (
294
+    ".syntax unified" "\n\t"
295
+    A("tst lr, #4")
296
+    A("ite eq")
297
+    A("mrseq r0, msp")
298
+    A("mrsne r0, psp")
299
+    A("mov r1,lr")
300
+    A("mov r2,#6")
301
+    A("b HardFault_HandlerC")
302
+  );
303
+}
304
+
305
+__attribute__((naked)) void RSTC_Handler(void) {
306
+  __asm__ __volatile__ (
307
+    ".syntax unified" "\n\t"
308
+    A("tst lr, #4")
309
+    A("ite eq")
310
+    A("mrseq r0, msp")
311
+    A("mrsne r0, psp")
312
+    A("mov r1,lr")
313
+    A("mov r2,#7")
314
+    A("b HardFault_HandlerC")
315
+  );
316
+}
317
+}
318
+#endif // ARDUINO_ARCH_SAM

+ 3
- 0
Marlin/src/HAL/HAL_LPC1768/HAL.h View File

@@ -152,4 +152,7 @@ using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
152 152
 // Parse a G-code word into a pin index
153 153
 int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
154 154
 
155
+#define HAL_IDLETASK 1
156
+void HAL_idletask(void);
157
+
155 158
 #endif // _HAL_LPC1768_H_

+ 43
- 32
Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp View File

@@ -49,7 +49,6 @@
49 49
 #ifdef TARGET_LPC1768
50 50
 
51 51
 #include "../../inc/MarlinConfig.h"
52
-
53 52
 // --------------------------------------------------------------------------
54 53
 // Includes
55 54
 // --------------------------------------------------------------------------
@@ -59,7 +58,6 @@
59 58
 // --------------------------------------------------------------------------
60 59
 // Public functions
61 60
 // --------------------------------------------------------------------------
62
-
63 61
 #if ENABLED(LPC_SOFTWARE_SPI)
64 62
 
65 63
   #include "SoftwareSPI.h"
@@ -127,8 +125,25 @@
127 125
   #include <lpc17xx_ssp.h>
128 126
   #include <lpc17xx_clkpwr.h>
129 127
 
130
-  void spiBegin() {  // setup SCK, MOSI & MISO pins for SSP0
128
+  // decide which HW SPI device to use
129
+  #ifndef LPC_HW_SPI_DEV
130
+    #if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
131
+      #define LPC_HW_SPI_DEV 1
132
+    #else
133
+      #if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18)
134
+        #define LPC_HW_SPI_DEV 0
135
+      #else
136
+        #error "Invalid pins selected for hardware SPI"
137
+      #endif
138
+    #endif
139
+  #endif
140
+  #if (LPC_HW_SPI_DEV == 0)
141
+    #define LPC_SSPn LPC_SSP0
142
+  #else
143
+    #define LPC_SSPn LPC_SSP1
144
+  #endif
131 145
 
146
+  void spiBegin() {  // setup SCK, MOSI & MISO pins for SSP0
132 147
     PINSEL_CFG_Type PinCfg;  // data structure to hold init values
133 148
     PinCfg.Funcnum = 2;
134 149
     PinCfg.OpenDrain = 0;
@@ -147,10 +162,13 @@
147 162
     PinCfg.Portnum = LPC1768_PIN_PORT(MOSI_PIN);
148 163
     PINSEL_ConfigPin(&PinCfg);
149 164
     SET_OUTPUT(MOSI_PIN);
165
+    // divide PCLK by 2 for SSP0
166
+    CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
167
+    spiInit(0);
168
+    SSP_Cmd(LPC_SSPn, ENABLE);  // start SSP running
150 169
   }
151 170
 
152 171
   void spiInit(uint8_t spiRate) {
153
-    SSP_Cmd(LPC_SSP0, DISABLE); // Disable SSP0 before changing rate
154 172
     // table to convert Marlin spiRates (0-5 plus default) into bit rates
155 173
     uint32_t Marlin_speed[7]; // CPSR is always 2
156 174
     Marlin_speed[0] = 8333333; //(SCR:  2)  desired: 8,000,000  actual: 8,333,333  +4.2%  SPI_FULL_SPEED
@@ -160,33 +178,32 @@
160 178
     Marlin_speed[4] =  500000; //(SCR: 49)  desired:   500,000  actual:   500,000         SPI_SPEED_5
161 179
     Marlin_speed[5] =  250000; //(SCR: 99)  desired:   250,000  actual:   250,000         SPI_SPEED_6
162 180
     Marlin_speed[6] =  125000; //(SCR:199)  desired:   125,000  actual:   125,000         Default from HAL.h
163
-
164
-    // divide PCLK by 2 for SSP0
165
-    CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_SSP0, CLKPWR_PCLKSEL_CCLK_DIV_2);
166
-
167 181
     // setup for SPI mode
168 182
     SSP_CFG_Type HW_SPI_init; // data structure to hold init values
169 183
     SSP_ConfigStructInit(&HW_SPI_init);  // set values for SPI mode
170 184
     HW_SPI_init.ClockRate = Marlin_speed[MIN(spiRate, 6)]; // put in the specified bit rate
171
-    SSP_Init(LPC_SSP0, &HW_SPI_init);  // puts the values into the proper bits in the SSP0 registers
185
+    HW_SPI_init.Mode |= SSP_CR1_SSP_EN;
186
+    SSP_Init(LPC_SSPn, &HW_SPI_init);  // puts the values into the proper bits in the SSP0 registers
187
+  }
188
+
172 189
 
173
-    SSP_Cmd(LPC_SSP0, ENABLE);  // start SSP0 running
190
+  static uint8_t doio(uint8_t b) {
191
+    /* send and receive a single byte */
192
+    SSP_SendData(LPC_SSPn, b & 0x00FF);
193
+    while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY));  // wait for it to finish
194
+    return SSP_ReceiveData(LPC_SSPn) & 0x00FF;
174 195
   }
175 196
 
176 197
   void spiSend(uint8_t b) {
177
-    while (!SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL));   // wait for room in the buffer
178
-    SSP_SendData(LPC_SSP0, b & 0x00FF);
179
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
198
+    doio(b);
180 199
   }
181 200
 
182 201
 
183 202
   void spiSend(const uint8_t* buf, size_t n) {
184 203
     if (n == 0) return;
185 204
     for (uint16_t i = 0; i < n; i++) {
186
-      while (!SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL));   // wait for room in the buffer
187
-      SSP_SendData(LPC_SSP0, buf[i] & 0x00FF);
205
+      doio(buf[i]);
188 206
     }
189
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
190 207
   }
191 208
 
192 209
   void spiSend(uint32_t chan, byte b) {
@@ -195,17 +212,9 @@
195 212
   void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
196 213
   }
197 214
 
198
-  static uint8_t get_one_byte() {
199
-    // send a dummy byte so can clock in receive data
200
-    SSP_SendData(LPC_SSP0,0x00FF);
201
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
202
-    return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
203
-  }
204
-
205 215
   // Read single byte from SPI
206 216
   uint8_t spiRec() {
207
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
208
-    return get_one_byte();
217
+    return doio(0xff);
209 218
   }
210 219
 
211 220
   uint8_t spiRec(uint32_t chan) {
@@ -214,22 +223,25 @@
214 223
 
215 224
   // Read from SPI into buffer
216 225
   void spiRead(uint8_t*buf, uint16_t nbyte) {
217
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
218 226
     if (nbyte == 0) return;
219 227
     for (int i = 0; i < nbyte; i++) {
220
-      buf[i] = get_one_byte();
228
+      buf[i] = doio(0xff);
221 229
     }
222 230
   }
223 231
 
224 232
   static uint8_t spiTransfer(uint8_t b) {
225
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
226
-    SSP_SendData(LPC_SSP0, b);  // send the byte
227
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
228
-    return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
233
+    return doio(b);
229 234
   }
230 235
 
231 236
   // Write from buffer to SPI
232 237
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
238
+    uint8_t response;
239
+    response = spiTransfer(token);
240
+
241
+    for (uint16_t i = 0; i < 512; i++) {
242
+      response = spiTransfer(buf[i]);
243
+    }
244
+    UNUSED(response);
233 245
   }
234 246
 
235 247
   /** Begin SPI transaction, set clock, bit order, data mode */
@@ -270,4 +282,3 @@ uint16_t SPIClass::transfer16(uint16_t data) {
270 282
 SPIClass SPI;
271 283
 
272 284
 #endif // TARGET_LPC1768
273
-

+ 9
- 9
Marlin/src/HAL/HAL_LPC1768/fastio.h View File

@@ -39,19 +39,19 @@
39 39
 
40 40
 #define USEABLE_HARDWARE_PWM(pin) useable_hardware_PWM(pin)
41 41
 
42
-#define LPC_PIN(pin)            (gpio_pin(pin))
43
-#define LPC_GPIO(port)          (gpio_port(port))
42
+#define LPC_PIN(pin)            gpio_pin(pin)
43
+#define LPC_GPIO(port)          gpio_port(port)
44 44
 
45
-#define SET_DIR_INPUT(IO)       (gpio_set_input(IO))
46
-#define SET_DIR_OUTPUT(IO)      (gpio_set_output(IO))
45
+#define SET_DIR_INPUT(IO)       gpio_set_input(IO)
46
+#define SET_DIR_OUTPUT(IO)      gpio_set_output(IO)
47 47
 
48
-#define SET_MODE(IO, mode)      (pinMode(IO, mode))
48
+#define SET_MODE(IO, mode)      pinMode(IO, mode)
49 49
 
50
-#define WRITE_PIN_SET(IO)       (gpio_set(IO))
51
-#define WRITE_PIN_CLR(IO)       (gpio_clear(IO))
50
+#define WRITE_PIN_SET(IO)       gpio_set(IO)
51
+#define WRITE_PIN_CLR(IO)       gpio_clear(IO)
52 52
 
53
-#define READ_PIN(IO)            (gpio_get(IO))
54
-#define WRITE_PIN(IO,V)         (gpio_set(IO, V))
53
+#define READ_PIN(IO)            gpio_get(IO)
54
+#define WRITE_PIN(IO,V)         gpio_set(IO, V)
55 55
 
56 56
 /**
57 57
  * Magic I/O routines

+ 43
- 5
Marlin/src/HAL/HAL_LPC1768/main.cpp View File

@@ -9,7 +9,13 @@
9 9
 #include <usb/cdcuser.h>
10 10
 #include <usb/mscuser.h>
11 11
 #include <CDCSerial.h>
12
+#include <usb/mscuser.h>
13
+
14
+extern "C" {
15
+  #include <debug_frmwrk.h>
16
+}
12 17
 
18
+#include "../../sd/cardreader.h"
13 19
 #include "../../inc/MarlinConfig.h"
14 20
 #include "HAL.h"
15 21
 #include "HAL_timers.h"
@@ -41,15 +47,28 @@ void HAL_init() {
41 47
       delay(100);
42 48
     }
43 49
   #endif
44
-
45
-  (void)MSC_SD_Init(0);
46
-
47
-  USB_Init();
50
+  //debug_frmwrk_init();
51
+  //_DBG("\n\nDebug running\n");
52
+  // Initialise the SD card chip select pins as soon as possible
53
+  #ifdef SS_PIN
54
+    digitalWrite(SS_PIN, HIGH);
55
+    pinMode(SS_PIN, OUTPUT);
56
+  #endif
57
+  #ifdef ONBOARD_SD_CS
58
+    digitalWrite(ONBOARD_SD_CS, HIGH);
59
+    pinMode(ONBOARD_SD_CS, OUTPUT);
60
+  #endif
61
+  USB_Init();                               // USB Initialization
62
+  USB_Connect(FALSE);                       // USB clear connection
63
+  delay(1000);                              // Give OS time to notice
48 64
   USB_Connect(TRUE);
49
-
65
+  #ifndef USB_SD_DISABLED
66
+    MSC_SD_Init(0);                         // Enable USB SD card access
67
+  #endif
50 68
   const uint32_t usb_timeout = millis() + 2000;
51 69
   while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
52 70
     delay(50);
71
+    HAL_idletask();
53 72
     #if PIN_EXISTS(LED)
54 73
       TOGGLE(LED_PIN);     // Flash quickly during USB initialization
55 74
     #endif
@@ -68,4 +87,23 @@ void HAL_init() {
68 87
   LPC1768_PWM_init();
69 88
 }
70 89
 
90
+// HAL idle task
91
+void HAL_idletask(void) {
92
+  #if ENABLED(SDSUPPORT) && defined(SHARED_SD_CARD)
93
+    // If Marlin is using the SD card we need to lock it to prevent access from
94
+    // a PC via USB.
95
+    // Other HALs use IS_SD_PRINTING and IS_SD_FILE_OPEN to check for access but
96
+    // this will not reliably detect delete operations. To be safe we will lock
97
+    // the disk if Marlin has it mounted. Unfortuately there is currently no way
98
+    // to unmount the disk from the LCD menu.
99
+    // if (IS_SD_PRINTING || IS_SD_FILE_OPEN)
100
+    if (card.cardOK)
101
+      MSC_Aquire_Lock();
102
+    else
103
+      MSC_Release_Lock();
104
+  #endif
105
+  // Perform USB stack housekeeping
106
+  MSC_RunDeferredCommands();
107
+}
108
+
71 109
 #endif // TARGET_LPC1768

+ 1
- 1
Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h View File

@@ -21,4 +21,4 @@
21 21
  */
22 22
 #include "../shared/persistent_store_api.h"
23 23
 
24
-//#define FLASH_EEPROM
24
+#define FLASH_EEPROM

+ 2
- 2
Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp View File

@@ -116,7 +116,7 @@ bool PersistentStore::access_finish() {
116 116
 }
117 117
 
118 118
 bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
119
-  for (int i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
119
+  for (size_t i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
120 120
   eeprom_dirty = true;
121 121
   crc16(crc, value, size);
122 122
   pos += size;
@@ -125,7 +125,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
125 125
 
126 126
 bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
127 127
   const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
128
-  if (writing) for (int i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
128
+  if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
129 129
   crc16(crc, buff, size);
130 130
   pos += size;
131 131
   return false;  // return true for any error

+ 2
- 1
Marlin/src/HAL/HAL_LPC1768/spi_pins.h View File

@@ -50,7 +50,8 @@
50 50
 #ifndef SS_PIN
51 51
   #define SS_PIN            P1_23
52 52
 #endif
53
-#ifndef SDSS
53
+#if !defined(SDSS) || SDSS == P_NC // get defaulted in pins.h
54
+  #undef SDSS
54 55
   #define SDSS              SS_PIN
55 56
 #endif
56 57
 

+ 1
- 0
Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp View File

@@ -63,6 +63,7 @@
63 63
 #include "SoftwareSPI.h"
64 64
 #include "../../shared/Delay.h"
65 65
 
66
+#undef SPI_SPEED
66 67
 #define SPI_SPEED 3  // About 1 MHz
67 68
 
68 69
 static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;

+ 1
- 0
Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp View File

@@ -62,6 +62,7 @@
62 62
 #include <U8glib.h>
63 63
 #include "SoftwareSPI.h"
64 64
 
65
+#undef SPI_SPEED
65 66
 #define SPI_SPEED 2  // About 2 MHz
66 67
 
67 68
 static uint8_t SPI_speed = 0;

+ 23
- 1
Marlin/src/HAL/HAL_LPC1768/watchdog.cpp View File

@@ -30,7 +30,29 @@
30 30
 #include "watchdog.h"
31 31
 
32 32
 void watchdog_init(void) {
33
-  WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
33
+  #if ENABLED(WATCHDOG_RESET_MANUAL)
34
+    // We enable the watchdog timer, but only for the interrupt.
35
+
36
+    // Configure WDT to only trigger an interrupt
37
+    // Disable WDT interrupt (just in case, to avoid triggering it!)
38
+    NVIC_DisableIRQ(WDT_IRQn);
39
+
40
+    // We NEED memory barriers to ensure Interrupts are actually disabled!
41
+    // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
42
+    __DSB();
43
+    __ISB();
44
+
45
+    // Configure WDT to only trigger an interrupt
46
+    // Initialize WDT with the given parameters
47
+    WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY);
48
+
49
+    // Configure and enable WDT interrupt.
50
+    NVIC_ClearPendingIRQ(WDT_IRQn);
51
+    NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
52
+    NVIC_EnableIRQ(WDT_IRQn);
53
+  #else
54
+    WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
55
+  #endif
34 56
   WDT_Start(WDT_TIMEOUT);
35 57
 }
36 58
 

+ 5
- 5
Marlin/src/pins/pins.h View File

@@ -299,19 +299,19 @@
299 299
 #elif MB(AZSMZ_MINI)
300 300
   #include "pins_AZSMZ_MINI.h"        // LPC1768                                    env:LPC1768
301 301
 #elif MB(AZTEEG_X5_GT)
302
-  #include "pins_AZTEEG_X5_GT.h"      // LPC1769                                    env:LPC1768
302
+  #include "pins_AZTEEG_X5_GT.h"      // LPC1769                                    env:LPC1769
303 303
 #elif MB(AZTEEG_X5_MINI_WIFI)
304
-  #include "pins_AZTEEG_X5_MINI_WIFI.h" // LPC1769                                  env:LPC1768
304
+  #include "pins_AZTEEG_X5_MINI_WIFI.h" // LPC1769                                  env:LPC1769
305 305
 #elif MB(BIQU_BQ111_A4)
306 306
   #include "pins_BIQU_BQ111_A4.h"     // LPC1768                                    env:LPC1768
307 307
 #elif MB(SELENA_COMPACT)
308 308
   #include "pins_SELENA_COMPACT.h"    // LPC1768                                    env:LPC1768
309 309
 #elif MB(COHESION3D_REMIX)
310
-  #include "pins_COHESION3D_REMIX.h"  // LPC1769                                    env:LPC1768
310
+  #include "pins_COHESION3D_REMIX.h"  // LPC1769                                    env:LPC1769
311 311
 #elif MB(COHESION3D_MINI)
312
-  #include "pins_COHESION3D_MINI.h"   // LPC1769                                    env:LPC1768
312
+  #include "pins_COHESION3D_MINI.h"   // LPC1769                                    env:LPC1769
313 313
 #elif MB(SMOOTHIEBOARD)
314
-  #include "pins_SMOOTHIEBOARD.h"     // LPC1769                                    env:LPC1768
314
+  #include "pins_SMOOTHIEBOARD.h"     // LPC1769                                    env:LPC1769
315 315
 
316 316
 //
317 317
 // Other 32-bit Boards

+ 70
- 21
Marlin/src/pins/pins_MKS_SBASE.h View File

@@ -141,8 +141,6 @@
141 141
 // Misc. Functions
142 142
 //
143 143
 #define PS_ON_PIN          P0_25 //TH3 Connector
144
-#define LPC_SOFTWARE_SPI  // MKS_SBASE needs a software SPI because the
145
-                          // selected pins are not on a hardware SPI controller
146 144
 
147 145
 /**
148 146
  * Smart LCD adapter
@@ -185,14 +183,77 @@
185 183
 #define ENET_TXD0          P1_00   // J12-11
186 184
 #define ENET_TXD1          P1_01   // J12-12
187 185
 
188
-// A custom cable is needed. See the README file in the
189
-// Marlin\src\config\examples\Mks\Sbase directory
190 186
 
191
-#define SCK_PIN            P1_22   // J8-2 (moved from EXP2 P0.7)
192
-#define MISO_PIN           P1_23   // J8-3 (moved from EXP2 P0.8)
193
-#define MOSI_PIN           P2_12   // J8-4 (moved from EXP2 P0.5)
194
-#define SS_PIN             P0_28
195
-#define SDSS               P0_06
187
+/*
188
+ * The SBase can share the on-board SD card with a PC via USB the following
189
+ * definitions control this feature:
190
+ */
191
+//#define USB_SD_DISABLED
192
+#define USB_SD_ONBOARD
193
+
194
+/*
195
+ * There are a number of configurations available for the SBase SD card reader.
196
+ * A custom cable can be used to allow access to the LCD based SD card.
197
+ * A standard cable can be used for access to the LCD SD card (but no SD detect).
198
+ * The onboard SD card can be used and optionally shared with a PC via USB.
199
+ */
200
+
201
+//#define SBASE_SD_CUSTOM_CABLE // Use a custom cable to access the SD
202
+//#define SBASE_SD_LCD          // Use the SD drive attached to the LCD
203
+#define SBASE_SD_ONBOARD        // Use the SD drive on the control board
204
+
205
+#ifdef SBASE_SD_CUSTOM_CABLE
206
+  /**
207
+   * A custom cable is needed. See the README file in the
208
+   * Marlin\src\config\examples\Mks\Sbase directory
209
+   * P0.27 is on EXP2 and the on-board SD card's socket. That means it can't be
210
+   * used as the SD_DETECT for the LCD's SD card.
211
+   *
212
+   * The best solution is to use the custom cable to connect the LCD's SD_DETECT
213
+   * to a pin NOT on EXP2.
214
+   *
215
+   * If you can't find a pin to use for the LCD's SD_DETECT then comment out
216
+   * SD_DETECT_PIN entirely and remove that wire from the the custom cable.
217
+   */
218
+  #define SD_DETECT_PIN      P2_11   // J8-5 (moved from EXP2 P0.27)
219
+  #define SCK_PIN            P1_22   // J8-2 (moved from EXP2 P0.7)
220
+  #define MISO_PIN           P1_23   // J8-3 (moved from EXP2 P0.8)
221
+  #define MOSI_PIN           P2_12   // J8-4 (moved from EXP2 P0.9)
222
+  #define SS_PIN             P0_28   // Chip select for SD card used by Marlin
223
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
224
+  #define LPC_SOFTWARE_SPI  // With a custom cable we need software SPI because the
225
+                            // selected pins are not on a hardware SPI controller
226
+#endif
227
+
228
+#ifdef SBASE_SD_LCD
229
+  // use standard cable and header, SPI and SD detect sre shared with on-board SD card
230
+  // hardware SPI is used for both SD cards. The detect pin is shred between the
231
+  // LCD and onboard SD readers so we disable it.
232
+  #define SD_DETECT_PIN      P0_27
233
+  #undef SD_DETECT_PIN
234
+  #define SCK_PIN            P0_07
235
+  #define MISO_PIN           P0_08
236
+  #define MOSI_PIN           P0_09
237
+  #define SS_PIN             P0_28   // Chip select for SD card used by Marlin
238
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
239
+#endif
240
+
241
+#ifdef SBASE_SD_ONBOARD
242
+  // The external SD card is not used. Hardware SPI is used to access the card.
243
+  #ifdef USB_SD_ONBOARD
244
+    // When sharing the SD card with a PC we want the menu options to
245
+    // mount/unmount the card and refresh it. So we disable card detect.
246
+    #define SHARED_SD_CARD
247
+    #undef SD_DETECT_PIN
248
+  #else
249
+    #define SD_DETECT_PIN      P0_27
250
+  #endif
251
+  #define SCK_PIN            P0_07
252
+  #define MISO_PIN           P0_08
253
+  #define MOSI_PIN           P0_09
254
+  #define SS_PIN             P0_06   // Chip select for SD card used by Marlin
255
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
256
+#endif
196 257
 
197 258
 /**
198 259
  * Example for trinamic drivers using the J8 connector on MKs Sbase.
@@ -238,18 +299,6 @@
238 299
 #endif
239 300
 
240 301
 /**
241
- * P0.27 is on EXP2 and the on-board SD card's socket. That means it can't be
242
- * used as the SD_DETECT for the LCD's SD card.
243
- *
244
- * The best solution is to use the custom cable to connect the LCD's SD_DETECT
245
- * to a pin NOT on EXP2.
246
- *
247
- * If you can't find a pin to use for the LCD's SD_DETECT then comment out
248
- * SD_DETECT_PIN entirely and remove that wire from the the custom cable.
249
- */
250
-#define SD_DETECT_PIN      P2_11   // J8-5 (moved from EXP2 P0.27)
251
-
252
-/**
253 302
  *  PWMs
254 303
  *
255 304
  *  There are 6 PWMs.  Each PWM can be assigned to one of two pins.

+ 6
- 0
platformio.ini View File

@@ -153,6 +153,9 @@ platform          = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/ma
153 153
 framework         = arduino
154 154
 board             = nxp_lpc1768
155 155
 build_flags       = -DTARGET_LPC1768 -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags}
156
+# debug options for backtrace
157
+#  -funwind-tables
158
+#  -mpoke-function-name
156 159
 lib_ldf_mode      = off
157 160
 extra_scripts     = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
158 161
 src_filter        = ${common.default_src_filter} +<src/HAL/HAL_LPC1768>
@@ -165,6 +168,9 @@ platform          = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/ma
165 168
 framework         = arduino
166 169
 board             = nxp_lpc1769
167 170
 build_flags       = -DTARGET_LPC1768 -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags}
171
+# debug options for backtrace
172
+#  -funwind-tables
173
+#  -mpoke-function-name
168 174
 lib_ldf_mode      = off
169 175
 extra_scripts     = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
170 176
 src_filter        = ${common.default_src_filter} +<src/HAL/HAL_LPC1768>

Loading…
Cancel
Save