Browse Source

Only set up SPI pins as needed (#19372)

Victor Oliveira 4 years ago
parent
commit
79d4123319
No account linked to committer's email address
1 changed files with 53 additions and 49 deletions
  1. 53
    49
      Marlin/src/HAL/LPC1768/HAL_SPI.cpp

+ 53
- 49
Marlin/src/HAL/LPC1768/HAL_SPI.cpp View File

@@ -39,10 +39,10 @@
39 39
  * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card
40 40
  * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with
41 41
  * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is
42
- * active.  If any of these pins are shared then the software SPI must be used.
42
+ * active. If any of these pins are shared then the software SPI must be used.
43 43
  *
44
- * A more sophisticated hardware SPI can be found at the following link.  This
45
- * implementation has not been fully debugged.
44
+ * A more sophisticated hardware SPI can be found at the following link.
45
+ * This implementation has not been fully debugged.
46 46
  * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
47 47
  */
48 48
 
@@ -170,34 +170,20 @@ static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) {
170 170
   while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ }     // wait until BSY=0
171 171
 }
172 172
 
173
+// Retain the pin init state of the SPI, to avoid init more than once,
174
+// even if more instances of SPIClass exist
175
+static bool spiInitialised[BOARD_NR_SPI] = { false };
176
+
173 177
 SPIClass::SPIClass(uint8_t device) {
174 178
   // Init things specific to each SPI device
175 179
   // clock divider setup is a bit of hack, and needs to be improved at a later date.
176 180
 
177
-  PINSEL_CFG_Type PinCfg;  // data structure to hold init values
178 181
   #if BOARD_NR_SPI >= 1
179 182
     _settings[0].spi_d = LPC_SSP0;
180 183
     _settings[0].dataMode = SPI_MODE0;
181 184
     _settings[0].dataSize = DATA_SIZE_8BIT;
182 185
     _settings[0].clock = SPI_CLOCK_MAX;
183
-    // _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
184
-    PinCfg.Funcnum = 2;
185
-    PinCfg.OpenDrain = 0;
186
-    PinCfg.Pinmode = 0;
187
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_SCK_PIN);
188
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_SCK_PIN);
189
-    PINSEL_ConfigPin(&PinCfg);
190
-    SET_OUTPUT(BOARD_SPI1_SCK_PIN);
191
-
192
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MISO_PIN);
193
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MISO_PIN);
194
-    PINSEL_ConfigPin(&PinCfg);
195
-    SET_INPUT(BOARD_SPI1_MISO_PIN);
196
-
197
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MOSI_PIN);
198
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MOSI_PIN);
199
-    PINSEL_ConfigPin(&PinCfg);
200
-    SET_OUTPUT(BOARD_SPI1_MOSI_PIN);
186
+    //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
201 187
   #endif
202 188
 
203 189
   #if BOARD_NR_SPI >= 2
@@ -205,34 +191,53 @@ SPIClass::SPIClass(uint8_t device) {
205 191
     _settings[1].dataMode = SPI_MODE0;
206 192
     _settings[1].dataSize = DATA_SIZE_8BIT;
207 193
     _settings[1].clock = SPI_CLOCK_MAX;
208
-    // _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
194
+    //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
195
+  #endif
196
+
197
+  setModule(device);
198
+
199
+  // Init the GPDMA controller
200
+  // TODO: call once in the constructor? or each time?
201
+  GPDMA_Init();
202
+}
203
+
204
+void SPIClass::begin() {
205
+  // Init the SPI pins in the first begin call
206
+  if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
207
+      (_currentSetting->spi_d == LPC_SSP1 && spiInitialised[1] == false)) {
208
+    pin_t sck, miso, mosi;
209
+    if (_currentSetting->spi_d == LPC_SSP0) {
210
+      sck = BOARD_SPI1_SCK_PIN;
211
+      miso = BOARD_SPI1_MISO_PIN;
212
+      mosi = BOARD_SPI1_MOSI_PIN;
213
+      spiInitialised[0] = true;
214
+    }
215
+    else if (_currentSetting->spi_d == LPC_SSP1) {
216
+      sck = BOARD_SPI2_SCK_PIN;
217
+      miso = BOARD_SPI2_MISO_PIN;
218
+      mosi = BOARD_SPI2_MOSI_PIN;
219
+      spiInitialised[1] = true;
220
+    }
221
+    PINSEL_CFG_Type PinCfg;  // data structure to hold init values
209 222
     PinCfg.Funcnum = 2;
210 223
     PinCfg.OpenDrain = 0;
211 224
     PinCfg.Pinmode = 0;
212
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_SCK_PIN);
213
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_SCK_PIN);
225
+    PinCfg.Pinnum = LPC176x::pin_bit(sck);
226
+    PinCfg.Portnum = LPC176x::pin_port(sck);
214 227
     PINSEL_ConfigPin(&PinCfg);
215
-    SET_OUTPUT(BOARD_SPI2_SCK_PIN);
228
+    SET_OUTPUT(sck);
216 229
 
217
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MISO_PIN);
218
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MISO_PIN);
230
+    PinCfg.Pinnum = LPC176x::pin_bit(miso);
231
+    PinCfg.Portnum = LPC176x::pin_port(miso);
219 232
     PINSEL_ConfigPin(&PinCfg);
220
-    SET_INPUT(BOARD_SPI2_MISO_PIN);
233
+    SET_INPUT(miso);
221 234
 
222
-    PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MOSI_PIN);
223
-    PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MOSI_PIN);
235
+    PinCfg.Pinnum = LPC176x::pin_bit(mosi);
236
+    PinCfg.Portnum = LPC176x::pin_port(mosi);
224 237
     PINSEL_ConfigPin(&PinCfg);
225
-    SET_OUTPUT(BOARD_SPI2_MOSI_PIN);
226
-  #endif
227
-
228
-  setModule(device);
229
-
230
-  /* Initialize GPDMA controller */
231
-  //TODO: call once in the constructor? or each time?
232
-  GPDMA_Init();
233
-}
238
+    SET_OUTPUT(mosi);
239
+  }
234 240
 
235
-void SPIClass::begin() {
236 241
   updateSettings();
237 242
   SSP_Cmd(_currentSetting->spi_d, ENABLE);  // start SSP running
238 243
 }
@@ -246,7 +251,7 @@ void SPIClass::beginTransaction(const SPISettings &cfg) {
246 251
 }
247 252
 
248 253
 uint8_t SPIClass::transfer(const uint16_t b) {
249
-  /* send and receive a single byte */
254
+  // Send and receive a single byte
250 255
   SSP_ReceiveData(_currentSetting->spi_d); // read any previous data
251 256
   SSP_SendData(_currentSetting->spi_d, b);
252 257
   waitSpiTxEnd(_currentSetting->spi_d);  // wait for it to finish
@@ -254,8 +259,7 @@ uint8_t SPIClass::transfer(const uint16_t b) {
254 259
 }
255 260
 
256 261
 uint16_t SPIClass::transfer16(const uint16_t data) {
257
-  return (transfer((data >> 8) & 0xFF) << 8)
258
-       | (transfer(data & 0xFF) & 0xFF);
262
+  return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF);
259 263
 }
260 264
 
261 265
 void SPIClass::end() {
@@ -294,23 +298,23 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
294 298
   // Enable dma on SPI
295 299
   SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
296 300
 
297
-  // only increase memory if minc is true
301
+  // Only increase memory if minc is true
298 302
   GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
299 303
 
300 304
   // Setup channel with given parameter
301 305
   GPDMA_Setup(&GPDMACfg);
302 306
 
303
-  // enabled dma
307
+  // Enable DMA
304 308
   GPDMA_ChannelCmd(0, ENABLE);
305 309
 
306
-  // wait data transfer
310
+  // Wait for data transfer
307 311
   while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
308 312
 
309
-  // clear err and int
313
+  // Clear err and int
310 314
   GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
311 315
   GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
312 316
 
313
-  // dma disable
317
+  // Disable DMA
314 318
   GPDMA_ChannelCmd(0, DISABLE);
315 319
 
316 320
   waitSpiTxEnd(_currentSetting->spi_d);

Loading…
Cancel
Save