Browse Source

[2.0.x] Add support for LPC1769 at 120 MHz (#9423)

Thomas Moore 6 years ago
parent
commit
e1fd9c08b3

+ 39
- 107
Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp View File

47
  * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
47
  * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
48
  */
48
  */
49
 
49
 
50
+#include "src/inc/MarlinConfig.h"
51
+
50
 #ifdef TARGET_LPC1768
52
 #ifdef TARGET_LPC1768
51
 
53
 
52
 // --------------------------------------------------------------------------
54
 // --------------------------------------------------------------------------
53
 // Includes
55
 // Includes
54
 // --------------------------------------------------------------------------
56
 // --------------------------------------------------------------------------
55
 
57
 
56
-//#include "../../../MarlinConfig.h"  //works except in U8g
57
-#include "spi_pins.h"
58
-#include "fastio.h"
59
 #include "LPC_SPI.h"
58
 #include "LPC_SPI.h"
60
 #include "../SPI.h"
59
 #include "../SPI.h"
61
 
60
 
62
 // --------------------------------------------------------------------------
61
 // --------------------------------------------------------------------------
63
-// Public Variables
64
-// --------------------------------------------------------------------------
65
-
66
-
67
-// --------------------------------------------------------------------------
68
 // Public functions
62
 // Public functions
69
 // --------------------------------------------------------------------------
63
 // --------------------------------------------------------------------------
70
 
64
 
71
 #if ENABLED(LPC_SOFTWARE_SPI)
65
 #if ENABLED(LPC_SOFTWARE_SPI)
66
+
67
+  #include "SoftwareSPI.h"
68
+
72
   // --------------------------------------------------------------------------
69
   // --------------------------------------------------------------------------
73
-  // software SPI
70
+  // Software SPI
74
   // --------------------------------------------------------------------------
71
   // --------------------------------------------------------------------------
75
 
72
 
76
-  /**
77
-   * This software SPI runs at three rates. The SD software provides an index
78
-   * (spiRate) of 0-6. The mapping is:
79
-   *     0-1 - about 5 MHz peak
80
-   *     2-3 - about 2 MHz peak
81
-   *     all others - about 250 KHz
82
-   */
83
-
84
   static uint8_t SPI_speed = 0;
73
   static uint8_t SPI_speed = 0;
85
 
74
 
86
   static uint8_t spiTransfer(uint8_t b) {
75
   static uint8_t spiTransfer(uint8_t b) {
87
-
88
-    if (!SPI_speed) {       // fastest - about 5 MHz peak
89
-      for (int bits = 0; bits < 8; bits++) {
90
-        if (b & 0x80) {
91
-          WRITE(MOSI_PIN, HIGH);
92
-          WRITE(MOSI_PIN, HIGH);  // delay to (hopefully) guarantee setup time
93
-        }
94
-        else {
95
-          WRITE(MOSI_PIN, LOW);
96
-          WRITE(MOSI_PIN, LOW);  // delay to (hopefully) guarantee setup time
97
-        }
98
-        b <<= 1;
99
-        WRITE(SCK_PIN, HIGH);
100
-        if (READ(MISO_PIN)) {
101
-          b |= 1;
102
-        }
103
-        WRITE(SCK_PIN, LOW);
104
-      }
105
-    }
106
-    else if (SPI_speed == 1) { // medium - about 1 MHz
107
-      for (int bits = 0; bits < 8; bits++) {
108
-        if (b & 0x80) {
109
-          for (uint8_t i = 0; i < 9; i++) WRITE(MOSI_PIN, HIGH);
110
-        }
111
-        else {
112
-          for (uint8_t i = 0; i < 9; i++) WRITE(MOSI_PIN, LOW);
113
-        }
114
-        b <<= 1;
115
-
116
-        for (uint8_t i = 0; i < 7; i++) WRITE(SCK_PIN, HIGH);
117
-
118
-        if (READ(MISO_PIN)) {
119
-          b |= 1;
120
-        }
121
-        WRITE(SCK_PIN, LOW);
122
-      }
123
-    }
124
-    else { // slow - about 250 KHz
125
-      for (int bits = 0; bits < 8; bits++) {
126
-        if (b & 0x80) {
127
-          WRITE(MOSI_PIN, HIGH);
128
-        }
129
-        else {
130
-          WRITE(MOSI_PIN, LOW);
131
-        }
132
-        b <<= 1;
133
-        delayMicroseconds(1U);
134
-        WRITE(SCK_PIN, HIGH);
135
-        delayMicroseconds(2U);
136
-
137
-        if (READ(MISO_PIN)) {
138
-          b |= 1;
139
-        }
140
-        WRITE(SCK_PIN, LOW);
141
-        delayMicroseconds(1U);
142
-      }
143
-    }
144
-    return b;
76
+    return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN);
145
   }
77
   }
146
 
78
 
147
   void spiBegin() {
79
   void spiBegin() {
148
-    SET_OUTPUT(SCK_PIN);
149
-    SET_INPUT(MISO_PIN);
150
-    SET_OUTPUT(MOSI_PIN);
80
+    swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN);
151
   }
81
   }
152
 
82
 
153
   void spiInit(uint8_t spiRate) {
83
   void spiInit(uint8_t spiRate) {
154
-    SPI_speed = spiRate >> 1;
155
-    WRITE(MOSI_PIN, HIGH);
156
-    WRITE(SCK_PIN, LOW);
84
+    SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN);
157
   }
85
   }
158
 
86
 
159
   uint8_t spiRec() {
87
   uint8_t spiRec() {
193
     WRITE(SS_PIN, HIGH);
121
     WRITE(SS_PIN, HIGH);
194
   }
122
   }
195
 
123
 
196
-  void SPIClass::begin() { spiBegin(); }
197
-
198
-  uint8_t SPIClass::transfer(uint8_t B) {
199
-    return spiTransfer(B);
200
-  }
201
-  uint16_t SPIClass::transfer16(uint16_t data) {
202
-    uint16_t buffer;
203
-    buffer = transfer((data>>8) & 0xFF) << 8;
204
-    buffer |= transfer(data & 0xFF) && 0xFF;
205
-    return buffer;
206
-  }
207
-
208
-  SPIClass SPI;
209
-
210
 #else
124
 #else
211
 
125
 
212
   // hardware SPI
126
   // hardware SPI
221
     PinCfg.Funcnum = 2;
135
     PinCfg.Funcnum = 2;
222
     PinCfg.OpenDrain = 0;
136
     PinCfg.OpenDrain = 0;
223
     PinCfg.Pinmode = 0;
137
     PinCfg.Pinmode = 0;
224
-  PinCfg.Pinnum = LPC1768_PIN_PIN(SCK_PIN);
225
-PinCfg.Portnum = LPC1768_PIN_PORT(SCK_PIN);
138
+    PinCfg.Pinnum = LPC1768_PIN_PIN(SCK_PIN);
139
+    PinCfg.Portnum = LPC1768_PIN_PORT(SCK_PIN);
226
     PINSEL_ConfigPin(&PinCfg);
140
     PINSEL_ConfigPin(&PinCfg);
227
     SET_OUTPUT(SCK_PIN);
141
     SET_OUTPUT(SCK_PIN);
228
 
142
 
229
-PinCfg.Pinnum = LPC1768_PIN_PIN(MISO_PIN);
230
-PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
143
+    PinCfg.Pinnum = LPC1768_PIN_PIN(MISO_PIN);
144
+    PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
231
     PINSEL_ConfigPin(&PinCfg);
145
     PINSEL_ConfigPin(&PinCfg);
232
     SET_INPUT(MISO_PIN);
146
     SET_INPUT(MISO_PIN);
233
 
147
 
237
     SET_OUTPUT(MOSI_PIN);
151
     SET_OUTPUT(MOSI_PIN);
238
   }
152
   }
239
 
153
 
240
-
241
   void spiInit(uint8_t spiRate) {
154
   void spiInit(uint8_t spiRate) {
242
 
155
 
243
-   // table to convert Marlin spiRates (0-5 plus default) into bit rates
156
+    // table to convert Marlin spiRates (0-5 plus default) into bit rates
244
     uint32_t Marlin_speed[7]; // CPSR is always 2
157
     uint32_t Marlin_speed[7]; // CPSR is always 2
245
     Marlin_speed[0] = 8333333; //(SCR:  2)  desired: 8,000,000  actual: 8,333,333  +4.2%  SPI_FULL_SPEED
158
     Marlin_speed[0] = 8333333; //(SCR:  2)  desired: 8,000,000  actual: 8,333,333  +4.2%  SPI_FULL_SPEED
246
     Marlin_speed[1] = 4166667; //(SCR:  5)  desired: 4,000,000  actual: 4,166,667  +4.2%  SPI_HALF_SPEED
159
     Marlin_speed[1] = 4166667; //(SCR:  5)  desired: 4,000,000  actual: 4,166,667  +4.2%  SPI_HALF_SPEED
250
     Marlin_speed[5] =  250000; //(SCR: 99)  desired:   250,000  actual:   250,000         SPI_SPEED_6
163
     Marlin_speed[5] =  250000; //(SCR: 99)  desired:   250,000  actual:   250,000         SPI_SPEED_6
251
     Marlin_speed[6] =  125000; //(SCR:199)  desired:   125,000  actual:   125,000         Default from HAL.h
164
     Marlin_speed[6] =  125000; //(SCR:199)  desired:   125,000  actual:   125,000         Default from HAL.h
252
 
165
 
253
-
254
-   // select 50MHz PCLK for SSP0
166
+    // divide PCLK by 2 for SSP0
255
     CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_SSP0, CLKPWR_PCLKSEL_CCLK_DIV_2);
167
     CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_SSP0, CLKPWR_PCLKSEL_CCLK_DIV_2);
256
 
168
 
257
-   // setup for SPI mode
169
+    // setup for SPI mode
258
     SSP_CFG_Type HW_SPI_init; // data structure to hold init values
170
     SSP_CFG_Type HW_SPI_init; // data structure to hold init values
259
     SSP_ConfigStructInit(&HW_SPI_init);  // set values for SPI mode
171
     SSP_ConfigStructInit(&HW_SPI_init);  // set values for SPI mode
260
     HW_SPI_init.ClockRate = Marlin_speed[MIN(spiRate, 6)]; // put in the specified bit rate
172
     HW_SPI_init.ClockRate = Marlin_speed[MIN(spiRate, 6)]; // put in the specified bit rate
285
   void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
197
   void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
286
   }
198
   }
287
 
199
 
288
-
289
-  uint8_t get_one_byte() {
290
-   // send a dummy byte so can clock in receive data
200
+  static uint8_t get_one_byte() {
201
+    // send a dummy byte so can clock in receive data
291
     SSP_SendData(LPC_SSP0,0x00FF);
202
     SSP_SendData(LPC_SSP0,0x00FF);
292
     while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
203
     while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
293
     return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
204
     return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
312
     }
223
     }
313
   }
224
   }
314
 
225
 
226
+  static uint8_t spiTransfer(uint8_t b) {
227
+    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
228
+    SSP_SendData(LPC_SSP0, b);  // send the byte
229
+    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
230
+    return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
231
+  }
232
+
315
   // Write from buffer to SPI
233
   // Write from buffer to SPI
316
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
234
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
317
   }
235
   }
324
 
242
 
325
 #endif // ENABLED(LPC_SOFTWARE_SPI)
243
 #endif // ENABLED(LPC_SOFTWARE_SPI)
326
 
244
 
245
+void SPIClass::begin() { spiBegin(); }
246
+
247
+uint8_t SPIClass::transfer(uint8_t B) {
248
+  return spiTransfer(B);
249
+}
250
+uint16_t SPIClass::transfer16(uint16_t data) {
251
+  uint16_t buffer;
252
+  buffer = transfer((data>>8) & 0xFF) << 8;
253
+  buffer |= transfer(data & 0xFF) && 0xFF;
254
+  return buffer;
255
+}
256
+
257
+SPIClass SPI;
258
+
327
 #endif // TARGET_LPC1768
259
 #endif // TARGET_LPC1768
328
 
260
 

+ 5
- 0
Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp View File

41
   PINSEL_CFG_Type PinCfg;
41
   PINSEL_CFG_Type PinCfg;
42
   UART_FIFO_CFG_Type FIFOConfig;
42
   UART_FIFO_CFG_Type FIFOConfig;
43
 
43
 
44
+  if (Baudrate == baudrate) return; // No need to re-initialize
45
+
44
   if (UARTx == LPC_UART0) {
46
   if (UARTx == LPC_UART0) {
45
     // Initialize UART0 pin connect
47
     // Initialize UART0 pin connect
46
     PinCfg.Funcnum = 1;
48
     PinCfg.Funcnum = 1;
117
   #if TX_BUFFER_SIZE > 0
119
   #if TX_BUFFER_SIZE > 0
118
     TxQueueWritePos = TxQueueReadPos = 0;
120
     TxQueueWritePos = TxQueueReadPos = 0;
119
   #endif
121
   #endif
122
+
123
+  // Save the configured baudrate
124
+  Baudrate = baudrate;
120
 }
125
 }
121
 
126
 
122
 int HardwareSerial::peek() {
127
 int HardwareSerial::peek() {

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

36
 private:
36
 private:
37
   LPC_UART_TypeDef *UARTx;
37
   LPC_UART_TypeDef *UARTx;
38
 
38
 
39
+  uint32_t Baudrate;
39
   uint32_t Status;
40
   uint32_t Status;
40
   uint8_t RxBuffer[RX_BUFFER_SIZE];
41
   uint8_t RxBuffer[RX_BUFFER_SIZE];
41
   uint32_t RxQueueWritePos;
42
   uint32_t RxQueueWritePos;
49
 public:
50
 public:
50
   HardwareSerial(LPC_UART_TypeDef *UARTx)
51
   HardwareSerial(LPC_UART_TypeDef *UARTx)
51
     : UARTx(UARTx)
52
     : UARTx(UARTx)
53
+    , Baudrate(0)
52
     , RxQueueWritePos(0)
54
     , RxQueueWritePos(0)
53
     , RxQueueReadPos(0)
55
     , RxQueueReadPos(0)
54
     #if TX_BUFFER_SIZE > 0
56
     #if TX_BUFFER_SIZE > 0

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

166
   LPC_SC->PCLKSEL0 &= ~(0x3 << PCLK_PWM1);
166
   LPC_SC->PCLKSEL0 &= ~(0x3 << PCLK_PWM1);
167
   LPC_SC->PCLKSEL0 |= (LPC_PWM1_PCLKSEL0 << PCLK_PWM1);
167
   LPC_SC->PCLKSEL0 |= (LPC_PWM1_PCLKSEL0 << PCLK_PWM1);
168
 
168
 
169
+  uint32_t PR = (CLKPWR_GetPCLK(CLKPWR_PCLKSEL_PWM1) / 1000000) - 1;      // Prescalar to create 1 MHz output
170
+
169
   LPC_PWM1->MR0  = LPC_PWM1_MR0;                                          // TC resets every 19,999 + 1 cycles - sets PWM cycle(Ton+Toff) to 20 mS
171
   LPC_PWM1->MR0  = LPC_PWM1_MR0;                                          // TC resets every 19,999 + 1 cycles - sets PWM cycle(Ton+Toff) to 20 mS
170
   // MR0 must be set before TCR enables the PWM
172
   // MR0 must be set before TCR enables the PWM
171
   LPC_PWM1->TCR  = _BV(SBIT_CNTEN) | _BV(SBIT_CNTRST) | _BV(SBIT_PWMEN);  // Enable counters, reset counters, set mode to PWM
173
   LPC_PWM1->TCR  = _BV(SBIT_CNTEN) | _BV(SBIT_CNTRST) | _BV(SBIT_PWMEN);  // Enable counters, reset counters, set mode to PWM
172
   CBI(LPC_PWM1->TCR, SBIT_CNTRST);                                        // Take counters out of reset
174
   CBI(LPC_PWM1->TCR, SBIT_CNTRST);                                        // Take counters out of reset
173
-  LPC_PWM1->PR   =  LPC_PWM1_PR;
175
+  LPC_PWM1->PR   = PR;
174
   LPC_PWM1->MCR  = _BV(SBIT_PWMMR0R) | _BV(0);                            // Reset TC if it matches MR0, disable all interrupts except for MR0
176
   LPC_PWM1->MCR  = _BV(SBIT_PWMMR0R) | _BV(0);                            // Reset TC if it matches MR0, disable all interrupts except for MR0
175
   LPC_PWM1->CTCR = 0;                                                     // Disable counter mode (enable PWM mode)
177
   LPC_PWM1->CTCR = 0;                                                     // Disable counter mode (enable PWM mode)
176
   LPC_PWM1->LER  = 0x07F;                                                 // Set the latch Enable Bits to load the new Match Values for MR0 - MR6
178
   LPC_PWM1->LER  = 0x07F;                                                 // Set the latch Enable Bits to load the new Match Values for MR0 - MR6
179
   ////  interrupt controlled PWM setup
181
   ////  interrupt controlled PWM setup
180
 
182
 
181
   LPC_SC->PCONP |= 1 << 23;  // power on timer3
183
   LPC_SC->PCONP |= 1 << 23;  // power on timer3
182
-  HAL_PWM_TIMER->PR = LPC_PWM1_PR;
184
+  HAL_PWM_TIMER->PR = PR;
183
   HAL_PWM_TIMER->MCR = 0x0B;              // Interrupt on MR0 & MR1, reset on MR0
185
   HAL_PWM_TIMER->MCR = 0x0B;              // Interrupt on MR0 & MR1, reset on MR0
184
   HAL_PWM_TIMER->MR0 = LPC_PWM1_MR0;
186
   HAL_PWM_TIMER->MR0 = LPC_PWM1_MR0;
185
   HAL_PWM_TIMER->MR1 = 0;
187
   HAL_PWM_TIMER->MR1 = 0;

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

64
 #define _LPC1768_PWM_H_
64
 #define _LPC1768_PWM_H_
65
 
65
 
66
 #include "pinmapping.h"
66
 #include "pinmapping.h"
67
+#include <lpc17xx_clkpwr.h>
67
 
68
 
68
 #define LPC_PWM1_MR0 19999  // base repetition rate minus one count - 20mS
69
 #define LPC_PWM1_MR0 19999  // base repetition rate minus one count - 20mS
69
-#define LPC_PWM1_PR 24      // prescaler value - prescaler divide by 24 + 1  -  1 MHz output
70
-#define LPC_PWM1_PCLKSEL0 0x00   // select clock source for prescaler - defaults to 25MHz on power up
71
-                                 // 0: 25MHz, 1: 100MHz, 2: 50MHz, 3: 12.5MHZ to PWM1 prescaler
72
-#define MR0_MARGIN 200       // if channel value too close to MR0 the system locks up
70
+#define LPC_PWM1_PCLKSEL0 CLKPWR_PCLKSEL_CCLK_DIV_4 // select clock divider for prescaler - defaults to 4 on power up
71
+#define MR0_MARGIN 200      // if channel value too close to MR0 the system locks up
73
 
72
 
74
 void LPC1768_PWM_init(void);
73
 void LPC1768_PWM_init(void);
75
 bool LPC1768_PWM_attach_pin(pin_t pin, uint32_t min=1, uint32_t max=(LPC_PWM1_MR0 - (MR0_MARGIN)), uint8_t servo_index=0xFF);
74
 bool LPC1768_PWM_attach_pin(pin_t pin, uint32_t min=1, uint32_t max=(LPC_PWM1_MR0 - (MR0_MARGIN)), uint8_t servo_index=0xFF);

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

23
 #ifdef TARGET_LPC1768
23
 #ifdef TARGET_LPC1768
24
 #include <stdint.h>
24
 #include <stdint.h>
25
 
25
 
26
-#define MSBFIRST 0
26
+#define MSBFIRST 1
27
 #define SPI_MODE3 0
27
 #define SPI_MODE3 0
28
 
28
 
29
 class SPISettings {
29
 class SPISettings {

+ 116
- 0
Marlin/src/HAL/HAL_LPC1768/SoftwareSPI.cpp View File

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016, 2017 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
+/**
24
+ * Software SPI functions originally from Arduino Sd2Card Library
25
+ * Copyright (C) 2009 by William Greiman
26
+ */
27
+
28
+/**
29
+ *
30
+ * For TARGET_LPC1768
31
+ */
32
+
33
+#include "src/inc/MarlinConfig.h"
34
+
35
+#ifdef TARGET_LPC1768
36
+
37
+// --------------------------------------------------------------------------
38
+// Software SPI
39
+// --------------------------------------------------------------------------
40
+
41
+/**
42
+ * This software SPI runs at multiple rates. The SD software provides an index
43
+ * (spiRate) of 0-6. The mapping is:
44
+ *     0 - about 5 MHz peak (6 MHz on LPC1769)
45
+ *     1-2 - about 2 MHz peak
46
+ *     3 - about 1 MHz peak
47
+ *     4 - about 500 kHz peak
48
+ *     5 - about 250 kHz peak
49
+ *     6 - about 125 kHz peak
50
+ */
51
+
52
+uint8_t swSpiTransfer(uint8_t b, uint8_t spi_speed, pin_t sck_pin, pin_t miso_pin, pin_t mosi_pin) {
53
+  for (uint8_t i = 0; i < 8; i++) {
54
+    if (spi_speed == 0) {
55
+      if (b & 0x80)
56
+        WRITE(mosi_pin, HIGH);
57
+      else
58
+        WRITE(mosi_pin, LOW);
59
+
60
+      WRITE(sck_pin, HIGH);
61
+      
62
+      b <<= 1;
63
+
64
+      if (miso_pin >= 0)
65
+        if (READ(miso_pin)) b |= 1;
66
+
67
+      WRITE(sck_pin, LOW);
68
+    }
69
+    else {
70
+      if (b & 0x80)
71
+        for (uint8_t j = 0; j < spi_speed; j++)
72
+          WRITE(mosi_pin, HIGH);
73
+      else
74
+        for (uint8_t j = 0; j < spi_speed; j++)
75
+          WRITE(mosi_pin, LOW);
76
+
77
+      for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
78
+        WRITE(sck_pin, HIGH);
79
+      
80
+      b <<= 1;
81
+
82
+      if (miso_pin >= 0)
83
+        if (READ(miso_pin)) b |= 1;
84
+
85
+      for (uint8_t j = 0; j < spi_speed; j++)
86
+        WRITE(sck_pin, LOW);
87
+    }
88
+  }
89
+
90
+  return b;
91
+}
92
+
93
+void swSpiBegin(pin_t sck_pin, pin_t miso_pin, pin_t mosi_pin) {
94
+  SET_OUTPUT(sck_pin);
95
+  if (VALID_PIN(miso_pin))
96
+    SET_INPUT(miso_pin);
97
+  SET_OUTPUT(mosi_pin);
98
+}
99
+
100
+uint8_t swSpiInit(uint8_t spiRate, pin_t sck_pin, pin_t mosi_pin) {
101
+  uint8_t spi_speed = 0;
102
+
103
+  spiRate = MIN(spiRate, 6);
104
+
105
+  if (SystemCoreClock == 120000000)
106
+    spi_speed = 44 / POW(2, 6 - spiRate);
107
+  else
108
+    spi_speed = 38 / POW(2, 6 - spiRate);
109
+
110
+  WRITE(mosi_pin, HIGH);
111
+  WRITE(sck_pin, LOW);
112
+
113
+  return spi_speed;
114
+}
115
+
116
+#endif // TARGET_LPC1768

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

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
+#ifndef _SOFTWARE_SPI_H_
24
+#define _SOFTWARE_SPI_H_
25
+
26
+  #include "pinmapping.h"
27
+
28
+  // --------------------------------------------------------------------------
29
+  // software SPI
30
+  // --------------------------------------------------------------------------
31
+
32
+  /**
33
+   * This software SPI runs at multiple rates. The SD software provides an index
34
+   * (spiRate) of 0-6. The mapping is:
35
+   *     0 - about 5 MHz peak (6 MHz on LPC1769)
36
+   *     1-2 - about 2 MHz peak
37
+   *     3 - about 1 MHz peak
38
+   *     4 - about 500 kHz peak
39
+   *     5 - about 250 kHz peak
40
+   *     6 - about 125 kHz peak
41
+   */
42
+
43
+  void swSpiBegin(pin_t sck_pin, pin_t miso_pin, pin_t mosi_pin);
44
+
45
+  // Returns the spi_speed value to be passed to swSpiTransfer
46
+  uint8_t swSpiInit(uint8_t spiRate, pin_t sck_pin, pin_t mosi_pin);
47
+
48
+  uint8_t swSpiTransfer(uint8_t b, uint8_t spi_speed, pin_t sck_pin, pin_t miso_pin, pin_t mosi_pin);
49
+
50
+#endif // _SOFTWARE_SPI_H_

+ 15
- 1
Marlin/src/HAL/HAL_LPC1768/main.cpp View File

70
   }
70
   }
71
 }
71
 }
72
 
72
 
73
+// detect 17x[4-8] (100MHz) or 17x9 (120MHz)
74
+static bool isLPC1769() {
75
+    #define IAP_LOCATION 0x1FFF1FF1
76
+    uint32_t command[1];
77
+    uint32_t result[5];
78
+    typedef void (*IAP)(uint32_t*, uint32_t*);
79
+    IAP iap = (IAP) IAP_LOCATION;
80
+
81
+    command[0] = 54;
82
+    iap(command, result);
83
+
84
+    return ((result[1] & 0x00100000) != 0);
85
+}
86
+
73
 extern uint32_t MSC_SD_Init(uint8_t pdrv);
87
 extern uint32_t MSC_SD_Init(uint8_t pdrv);
74
 
88
 
75
 int main(void) {
89
 int main(void) {
93
     #if NUM_SERIAL > 1
107
     #if NUM_SERIAL > 1
94
       MYSERIAL1.begin(BAUDRATE);
108
       MYSERIAL1.begin(BAUDRATE);
95
     #endif
109
     #endif
96
-    SERIAL_PRINTF("\n\nLPC1768 (%dMhz) UART0 Initialised\n", SystemCoreClock / 1000000);
110
+    SERIAL_PRINTF("\n\n%s (%dMhz) UART0 Initialised\n", isLPC1769() ? "LPC1769" : "LPC1768", SystemCoreClock / 1000000);
97
     SERIAL_FLUSHTX();
111
     SERIAL_FLUSHTX();
98
   #endif
112
   #endif
99
 
113
 

+ 13
- 6
Marlin/src/HAL/HAL_LPC1768/pinmapping.h View File

143
 #define P0_26   LPC1768_PIN(PORT(0), PIN(26), INTERRUPT(1), PWM(0), ADC_CHAN(3))
143
 #define P0_26   LPC1768_PIN(PORT(0), PIN(26), INTERRUPT(1), PWM(0), ADC_CHAN(3))
144
 #define P0_27   LPC1768_PIN(PORT(0), PIN(27), INTERRUPT(1), PWM(0), ADC_NONE)
144
 #define P0_27   LPC1768_PIN(PORT(0), PIN(27), INTERRUPT(1), PWM(0), ADC_NONE)
145
 #define P0_28   LPC1768_PIN(PORT(0), PIN(28), INTERRUPT(1), PWM(0), ADC_NONE)
145
 #define P0_28   LPC1768_PIN(PORT(0), PIN(28), INTERRUPT(1), PWM(0), ADC_NONE)
146
-#define P0_29   LPC1768_PIN(PORT(0), PIN(29), INTERRUPT(1), PWM(0), ADC_NONE)
147
-#define P0_30   LPC1768_PIN(PORT(0), PIN(30), INTERRUPT(1), PWM(0), ADC_NONE)
146
+#if SERIAL_PORT != -1 && SERIAL_PORT_2 != -1
147
+  #define P0_29 LPC1768_PIN(PORT(0), PIN(29), INTERRUPT(1), PWM(0), ADC_NONE)
148
+  #define P0_30 LPC1768_PIN(PORT(0), PIN(30), INTERRUPT(1), PWM(0), ADC_NONE)
149
+#endif
148
 #define P1_00   LPC1768_PIN(PORT(1), PIN( 0), INTERRUPT(0), PWM(0), ADC_NONE)
150
 #define P1_00   LPC1768_PIN(PORT(1), PIN( 0), INTERRUPT(0), PWM(0), ADC_NONE)
149
 #define P1_01   LPC1768_PIN(PORT(1), PIN( 1), INTERRUPT(0), PWM(0), ADC_NONE)
151
 #define P1_01   LPC1768_PIN(PORT(1), PIN( 1), INTERRUPT(0), PWM(0), ADC_NONE)
150
 #define P1_04   LPC1768_PIN(PORT(1), PIN( 4), INTERRUPT(0), PWM(0), ADC_NONE)
152
 #define P1_04   LPC1768_PIN(PORT(1), PIN( 4), INTERRUPT(0), PWM(0), ADC_NONE)
216
     P_NC,
218
     P_NC,
217
   #endif
219
   #endif
218
            P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23,
220
            P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23,
219
-    P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P_NC,
221
+    P0_24, P0_25, P0_26, P0_27, P0_28,
222
+  #if SERIAL_PORT != -1 && SERIAL_PORT_2 != -1
223
+                                       P0_29, P0_30,
224
+  #else
225
+                                       P_NC,  P_NC,
226
+  #endif
227
+                                                   P_NC,
220
 
228
 
221
   P1_00, P1_01, P_NC,  P_NC,  P1_04, P_NC,  P_NC,  P_NC,
229
   P1_00, P1_01, P_NC,  P_NC,  P1_04, P_NC,  P_NC,  P_NC,
222
   P1_08, P1_09, P1_10, P_NC,  P_NC,  P_NC,  P1_14, P1_15,
230
   P1_08, P1_09, P1_10, P_NC,  P_NC,  P_NC,  P1_14, P1_15,
248
   #endif
256
   #endif
249
 };
257
 };
250
 
258
 
251
-#if SERIAL_PORT != 0
259
+#if SERIAL_PORT != 0 && SERIAL_PORT_2 != 0
252
   #define NUM_ANALOG_INPUTS 8
260
   #define NUM_ANALOG_INPUTS 8
253
 #else
261
 #else
254
   #define NUM_ANALOG_INPUTS 6
262
   #define NUM_ANALOG_INPUTS 6
255
 #endif
263
 #endif
256
 
264
 
257
 // P0.6 thru P0.9 are for the onboard SD card
265
 // P0.6 thru P0.9 are for the onboard SD card
258
-// P0.29 and P0.30 are for the USB port
259
-#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09, P0_29, P0_30
266
+#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09
260
 
267
 
261
 // Get the digital pin for an analog index
268
 // Get the digital pin for an analog index
262
 pin_t analogInputToDigitalPin(const int8_t p);
269
 pin_t analogInputToDigitalPin(const int8_t p);

+ 8
- 4
Marlin/src/HAL/HAL_LPC1768/spi_pins.h View File

23
 #ifndef SPI_PINS_LPC1768_H
23
 #ifndef SPI_PINS_LPC1768_H
24
 #define SPI_PINS_LPC1768_H
24
 #define SPI_PINS_LPC1768_H
25
 
25
 
26
-#define LPC_SOFTWARE_SPI  // Re-ARM board needs a software SPI because using the
27
-                          // standard LCD adapter results in the LCD and the
28
-                          // SD card sharing a single SPI when the RepRap Full
29
-                          // Graphic Smart Controller is selected
26
+#include "src/core/macros.h"
27
+
28
+#if ENABLED(SDSUPPORT) && ENABLED(DOGLCD) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
29
+  #define LPC_SOFTWARE_SPI  // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
30
+                            // needed due to the speed and mode requred for communicating with each device being different.
31
+                            // This requirement can be removed if the SPI access to these devices is updated to use
32
+                            // spiBeginTransaction.
33
+#endif
30
 
34
 
31
 /** onboard SD card */
35
 /** onboard SD card */
32
 //#define SCK_PIN           P0_07
36
 //#define SCK_PIN           P0_07

+ 17
- 58
Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp View File

58
 #ifdef TARGET_LPC1768
58
 #ifdef TARGET_LPC1768
59
 
59
 
60
   #include <U8glib.h>
60
   #include <U8glib.h>
61
+  #include "SoftwareSPI.h"
61
 
62
 
62
-  #include <lpc17xx_pinsel.h>
63
-
64
-  #define LPC_PORT_OFFSET         (0x0020)
65
-  #define LPC_PIN(pin)            (1UL << pin)
66
-  #define LPC_GPIO(port)          ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port))
67
-
68
-
69
-  uint8_t SCK_pin_ST7920_HAL, SCK_port_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL, MOSI_port_ST7920_HAL;
70
-
71
-
72
-  #define SPI_SPEED 4  //20: 200KHz 5:750KHz 4:1MHz 3:1.5MHz 2:3-4MHz
73
-
74
-  static void spiSend_sw(uint8_t val)
75
-  {
76
-    for (uint8_t i = 0; i < 8; i++) {
77
-
78
-      if (val & 0x80)
79
-        for (uint8_t j = 0; j < SPI_SPEED; j++) {
80
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
81
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
82
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
83
-        }
84
-      else
85
-        for (uint8_t j = 0; j < SPI_SPEED; j++) {
86
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
87
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
88
-          LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL);
89
-        }
90
-
91
-      for (uint8_t j = 0; j < SPI_SPEED; j++) {
92
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL);
93
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL);
94
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL);
95
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL);
96
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL);
97
-      }
98
-
99
-      for (uint8_t j = 0; j < SPI_SPEED; j++) {
100
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOCLR = LPC_PIN(SCK_pin_ST7920_HAL);
101
-        LPC_GPIO(SCK_port_ST7920_HAL)->FIOCLR = LPC_PIN(SCK_pin_ST7920_HAL);
102
-      }
103
-      val = val << 1;
104
-    }
105
-  }
63
+  #define SPI_SPEED 3  // About 1 MHz
106
 
64
 
65
+  static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
66
+  static uint8_t SPI_speed = 0;
107
   static uint8_t rs_last_state = 255;
67
   static uint8_t rs_last_state = 255;
108
 
68
 
109
   static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val)
69
   static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val)
115
 
75
 
116
       if ( rs == 0 )
76
       if ( rs == 0 )
117
         /* command */
77
         /* command */
118
-        spiSend_sw(0x0f8);
78
+        swSpiTransfer(0x0f8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
119
       else
79
       else
120
          /* data */
80
          /* data */
121
-        spiSend_sw(0x0fa);
81
+         swSpiTransfer(0x0fa, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
122
 
82
 
123
       for( i = 0; i < 4; i++ )   // give the controller some time to process the data
83
       for( i = 0; i < 4; i++ )   // give the controller some time to process the data
124
         u8g_10MicroDelay();      // 2 is bad, 3 is OK, 4 is safe
84
         u8g_10MicroDelay();      // 2 is bad, 3 is OK, 4 is safe
125
     }
85
     }
126
 
86
 
127
-    spiSend_sw(val & 0x0f0);
128
-    spiSend_sw(val << 4);
87
+    swSpiTransfer(val & 0x0f0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
88
+    swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
129
   }
89
   }
130
 
90
 
131
-
132
   uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
91
   uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
133
   {
92
   {
134
     switch(msg)
93
     switch(msg)
135
     {
94
     {
136
       case U8G_COM_MSG_INIT:
95
       case U8G_COM_MSG_INIT:
137
-        #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111))
138
-        #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111))
139
-        SCK_pin_ST7920_HAL = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SCK]);
140
-        SCK_port_ST7920_HAL = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SCK]);
141
-        MOSI_pin_ST7920_HAL_HAL = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_MOSI]);
142
-        MOSI_port_ST7920_HAL = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_MOSI]);
96
+        SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK];
97
+        MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI];
143
 
98
 
144
-        u8g_SetPILevel(u8g, U8G_PI_CS, 0);
145
         u8g_SetPIOutput(u8g, U8G_PI_CS);
99
         u8g_SetPIOutput(u8g, U8G_PI_CS);
146
-        u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
147
         u8g_SetPIOutput(u8g, U8G_PI_SCK);
100
         u8g_SetPIOutput(u8g, U8G_PI_SCK);
148
-        u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
149
         u8g_SetPIOutput(u8g, U8G_PI_MOSI);
101
         u8g_SetPIOutput(u8g, U8G_PI_MOSI);
150
         u8g_Delay(5);
102
         u8g_Delay(5);
103
+
104
+        SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
105
+
106
+        u8g_SetPILevel(u8g, U8G_PI_CS, 0);
107
+        u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
108
+        u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
109
+
151
         u8g->pin_list[U8G_PI_A0_STATE] = 0;       /* inital RS state: command mode */
110
         u8g->pin_list[U8G_PI_A0_STATE] = 0;       /* inital RS state: command mode */
152
         break;
111
         break;
153
 
112
 

+ 15
- 66
Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_sw_spi.cpp View File

55
 
55
 
56
 */
56
 */
57
 
57
 
58
-
59
-
60
 #if defined (TARGET_LPC1768)
58
 #if defined (TARGET_LPC1768)
61
 
59
 
62
-
63
 #include <U8glib.h>
60
 #include <U8glib.h>
61
+#include "SoftwareSPI.h"
64
 
62
 
65
-#include <lpc17xx_pinsel.h>
66
-
67
-#define LPC_PORT_OFFSET         (0x0020)
68
-#define LPC_PIN(pin)            (1UL << pin)
69
-#define LPC_GPIO(port)          ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port))
63
+#define SPI_SPEED 2  // About 2 MHz
70
 
64
 
71
-void delayMicroseconds(uint32_t us);
72
-void pinMode(int16_t pin, uint8_t mode);
73
-void digitalWrite(int16_t pin, uint8_t pin_status);
74
-
75
-
76
-uint8_t SCK_pin, SCK_port, MOSI_pin, MOSI_port;
77
-
78
-#define SPI_SPEED 2  //20: 200KHz 5:750KHz 2:3-4MHz
65
+static uint8_t SPI_speed = 0;
79
 
66
 
80
 static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val)
67
 static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val)
81
 {
68
 {
82
-  for (uint8_t i = 0; i < 8; i++) {
83
-
84
-    if (val & 0x80)
85
-      for (uint8_t j = 0; j < SPI_SPEED; j++) {
86
-        LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin);
87
-        LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin);
88
-        LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin);
89
-      }
90
-    else
91
-      for (uint8_t j = 0; j < SPI_SPEED; j++) {
92
-        LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin);
93
-        LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin);
94
-        LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin);
95
-      }
96
-
97
-    for (uint8_t j = 0; j < SPI_SPEED; j++) {
98
-      LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin);
99
-      LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin);
100
-      LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin);
101
-      LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin);
102
-      LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin);
103
-    }
104
-
105
-    for (uint8_t j = 0; j < SPI_SPEED; j++) {
106
-      LPC_GPIO(SCK_port)->FIOCLR = LPC_PIN(SCK_pin);
107
-      LPC_GPIO(SCK_port)->FIOCLR = LPC_PIN(SCK_pin);
108
-    }
109
-    val = val << 1;
110
-  }
69
+  swSpiTransfer(val, SPI_speed, clockPin, -1, dataPin);
111
 }
70
 }
112
 
71
 
113
-
114
 uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
72
 uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
115
 {
73
 {
116
-
117
-
118
   switch(msg)
74
   switch(msg)
119
   {
75
   {
120
     case U8G_COM_MSG_INIT:
76
     case U8G_COM_MSG_INIT:
121
-      #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111))
122
-      #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111))
123
-      SCK_pin = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SCK]);
124
-      SCK_port = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SCK]);
125
-      MOSI_pin = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_MOSI]);
126
-      MOSI_port = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_MOSI]);
127
-      // As defined by Arduino INPUT(0x0), OUPUT(0x1), INPUT_PULLUP(0x2)
128
-      #define OUPUT 0x1
129
-      pinMode(u8g->pin_list[U8G_PI_SCK], OUPUT);
130
-      pinMode(u8g->pin_list[U8G_PI_MOSI], OUPUT);
131
-      pinMode(u8g->pin_list[U8G_PI_CS], OUPUT);
132
-      pinMode(u8g->pin_list[U8G_PI_A0], OUPUT);
133
-      if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET])  pinMode(u8g->pin_list[U8G_PI_RESET], OUPUT);
134
-      digitalWrite(u8g->pin_list[U8G_PI_SCK], 0);
135
-      digitalWrite(u8g->pin_list[U8G_PI_MOSI], 0);
77
+      u8g_SetPIOutput(u8g, U8G_PI_SCK);
78
+      u8g_SetPIOutput(u8g, U8G_PI_MOSI);
79
+      u8g_SetPIOutput(u8g, U8G_PI_CS);
80
+      u8g_SetPIOutput(u8g, U8G_PI_A0);
81
+      if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
82
+      SPI_speed = swSpiInit(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
83
+      u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
84
+      u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
136
       break;
85
       break;
137
 
86
 
138
     case U8G_COM_MSG_STOP:
87
     case U8G_COM_MSG_STOP:
139
       break;
88
       break;
140
 
89
 
141
     case U8G_COM_MSG_RESET:
90
     case U8G_COM_MSG_RESET:
142
-      digitalWrite(u8g->pin_list[U8G_PI_RESET], arg_val);
91
+      if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
143
       break;
92
       break;
144
 
93
 
145
     case U8G_COM_MSG_CHIP_SELECT:
94
     case U8G_COM_MSG_CHIP_SELECT:
146
-      digitalWrite(u8g->pin_list[U8G_PI_CS], !arg_val);
95
+      u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val);
147
       break;
96
       break;
148
 
97
 
149
     case U8G_COM_MSG_WRITE_BYTE:
98
     case U8G_COM_MSG_WRITE_BYTE:
170
       break;
119
       break;
171
 
120
 
172
     case U8G_COM_MSG_ADDRESS:                     /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
121
     case U8G_COM_MSG_ADDRESS:                     /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
173
-      digitalWrite(u8g->pin_list[U8G_PI_A0], arg_val);
122
+      u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
174
       break;
123
       break;
175
   }
124
   }
176
   return 1;
125
   return 1;

+ 20
- 4
Marlin/src/feature/tmc_util.cpp View File

436
       tmc_status(stepperE0, TMC_E0, i, planner.axis_steps_per_mm[E_AXIS]);
436
       tmc_status(stepperE0, TMC_E0, i, planner.axis_steps_per_mm[E_AXIS]);
437
     #endif
437
     #endif
438
     #if E1_IS_TRINAMIC
438
     #if E1_IS_TRINAMIC
439
-      tmc_status(stepperE1, TMC_E1, i, planner.axis_steps_per_mm[E_AXIS+1]);
439
+      tmc_status(stepperE1, TMC_E1, i, planner.axis_steps_per_mm[E_AXIS
440
+        #if ENABLED(DISTINCT_E_FACTORS)
441
+          + 1
442
+        #endif
443
+      ]);
440
     #endif
444
     #endif
441
     #if E2_IS_TRINAMIC
445
     #if E2_IS_TRINAMIC
442
-      tmc_status(stepperE2, TMC_E2, i, planner.axis_steps_per_mm[E_AXIS+2]);
446
+      tmc_status(stepperE2, TMC_E2, i, planner.axis_steps_per_mm[E_AXIS
447
+        #if ENABLED(DISTINCT_E_FACTORS)
448
+          + 2
449
+        #endif
450
+      ]);
443
     #endif
451
     #endif
444
     #if E3_IS_TRINAMIC
452
     #if E3_IS_TRINAMIC
445
-      tmc_status(stepperE3, TMC_E3, i, planner.axis_steps_per_mm[E_AXIS+3]);
453
+      tmc_status(stepperE3, TMC_E3, i, planner.axis_steps_per_mm[E_AXIS
454
+        #if ENABLED(DISTINCT_E_FACTORS)
455
+          + 3
456
+        #endif
457
+      ]);
446
     #endif
458
     #endif
447
     #if E4_IS_TRINAMIC
459
     #if E4_IS_TRINAMIC
448
-      tmc_status(stepperE4, TMC_E4, i, planner.axis_steps_per_mm[E_AXIS+4]);
460
+      tmc_status(stepperE4, TMC_E4, i, planner.axis_steps_per_mm[E_AXIS
461
+        #if ENABLED(DISTINCT_E_FACTORS)
462
+          + 4
463
+        #endif
464
+      ]);
449
     #endif
465
     #endif
450
 
466
 
451
     SERIAL_EOL();
467
     SERIAL_EOL();

+ 5
- 5
Marlin/src/lcd/dogm/HAL_LCD_class_defines.h View File

29
 {
29
 {
30
   public:
30
   public:
31
     U8GLIB_64128N_2X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE)
31
     U8GLIB_64128N_2X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE)
32
-      : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_sw_spi, sck, mosi, cs, a0, reset)
32
+      : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset)
33
       { }
33
       { }
34
     U8GLIB_64128N_2X_HAL(pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE)
34
     U8GLIB_64128N_2X_HAL(pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE)
35
-      : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_hw_spi, cs, a0, reset)
35
+      : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_hw_spi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset)
36
       { }
36
       { }
37
 };
37
 };
38
 
38
 
43
 {
43
 {
44
   public:
44
   public:
45
     U8GLIB_ST7920_128X64_4X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE)
45
     U8GLIB_ST7920_128X64_4X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE)
46
-      : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_sw_spi, sck, mosi, cs, U8G_PIN_NONE, reset)    // a0 = U8G_PIN_NONE
46
+      : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset)    // a0 = U8G_PIN_NONE
47
       { }
47
       { }
48
     U8GLIB_ST7920_128X64_4X_HAL(pin_t cs, pin_t reset = U8G_PIN_NONE)
48
     U8GLIB_ST7920_128X64_4X_HAL(pin_t cs, pin_t reset = U8G_PIN_NONE)
49
-      : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_hw_spi, cs, U8G_PIN_NONE, reset)   // a0 = U8G_PIN_NONE
49
+      : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_hw_spi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset)   // a0 = U8G_PIN_NONE
50
       { }
50
       { }
51
 };
51
 };
52
 
52
 
57
 {
57
 {
58
   public:
58
   public:
59
     U8GLIB_ST7920_128X64_RRD(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE)
59
     U8GLIB_ST7920_128X64_RRD(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE)
60
-      : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi, sck, mosi, cs, U8G_PIN_NONE, reset)   // a0 = U8G_PIN_NONE
60
+      : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset)   // a0 = U8G_PIN_NONE
61
       { }
61
       { }
62
 };
62
 };
63
 
63
 

+ 11
- 5
Marlin/src/lcd/ultralcd_impl_DOGM.h View File

160
 
160
 
161
 // LCD selection
161
 // LCD selection
162
 #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
162
 #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
163
-  #ifdef CPU_32_BIT
164
-    U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI
165
-  #else
163
+  #ifdef DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN)
166
     U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card)
164
     U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card)
165
+  #else
166
+    U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI
167
   #endif
167
   #endif
168
 
168
 
169
 #elif ENABLED(U8GLIB_ST7920)
169
 #elif ENABLED(U8GLIB_ST7920)
170
   // RepRap Discount Full Graphics Smart Controller
170
   // RepRap Discount Full Graphics Smart Controller
171
-    //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter)
171
+  #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN)
172
+    U8GLIB_ST7920_128X64_4X_HAL u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter)
173
+  #else
172
     //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI
174
     //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI
173
     U8GLIB_ST7920_128X64_RRD u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT
175
     U8GLIB_ST7920_128X64_RRD u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT
174
                                                                            // AVR version ignores these pin settings
176
                                                                            // AVR version ignores these pin settings
175
                                                                            // HAL version uses these pin settings
177
                                                                            // HAL version uses these pin settings
178
+  #endif
176
 
179
 
177
 #elif ENABLED(CARTESIO_UI)
180
 #elif ENABLED(CARTESIO_UI)
178
   // The CartesioUI display
181
   // The CartesioUI display
186
 
189
 
187
 #elif ENABLED(U8GLIB_ST7565_64128N)
190
 #elif ENABLED(U8GLIB_ST7565_64128N)
188
   // The MaKrPanel, Mini Viki, and Viki 2.0, ST7565 controller
191
   // The MaKrPanel, Mini Viki, and Viki 2.0, ST7565 controller
189
-    //U8GLIB_64128N_2X_HAL u8g(DOGLCD_CS, DOGLCD_A0);  // using HW-SPI
192
+  #if DISABLED(SDSUPPORT) && (DOGLCD_SCK == SCK_PIN) && (DOGLCD_MOSI == MOSI_PIN)
193
+    U8GLIB_64128N_2X_HAL u8g(DOGLCD_CS, DOGLCD_A0);  // using HW-SPI
194
+  #else
190
     U8GLIB_64128N_2X_HAL u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0);  // using SW-SPI
195
     U8GLIB_64128N_2X_HAL u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0);  // using SW-SPI
196
+  #endif
191
 
197
 
192
 #elif ENABLED(MKS_12864OLED_SSD1306)
198
 #elif ENABLED(MKS_12864OLED_SSD1306)
193
   // MKS 128x64 (SSD1306) OLED I2C LCD
199
   // MKS 128x64 (SSD1306) OLED I2C LCD

+ 40
- 8
Marlin/src/module/stepper_indirection.cpp View File

235
       _TMC2130_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
235
       _TMC2130_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
236
     #endif
236
     #endif
237
     #if ENABLED(E1_IS_TMC2130)
237
     #if ENABLED(E1_IS_TMC2130)
238
-      { constexpr int extruder = 1; _TMC2130_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); }
238
+      _TMC2130_INIT(E1, planner.axis_steps_per_mm[E_AXIS
239
+        #if ENABLED(DISTINCT_E_FACTORS)
240
+          + 1
241
+        #endif
242
+      ]);
239
     #endif
243
     #endif
240
     #if ENABLED(E2_IS_TMC2130)
244
     #if ENABLED(E2_IS_TMC2130)
241
-      { constexpr int extruder = 2; _TMC2130_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); }
245
+      _TMC2130_INIT(E2, planner.axis_steps_per_mm[E_AXIS
246
+        #if ENABLED(DISTINCT_E_FACTORS)
247
+          + 2
248
+        #endif
249
+      ]);
242
     #endif
250
     #endif
243
     #if ENABLED(E3_IS_TMC2130)
251
     #if ENABLED(E3_IS_TMC2130)
244
-      { constexpr int extruder = 3; _TMC2130_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); }
252
+      _TMC2130_INIT(E3, planner.axis_steps_per_mm[E_AXIS
253
+        #if ENABLED(DISTINCT_E_FACTORS)
254
+          + 3
255
+        #endif
256
+      ]);
245
     #endif
257
     #endif
246
     #if ENABLED(E4_IS_TMC2130)
258
     #if ENABLED(E4_IS_TMC2130)
247
-      { constexpr int extruder = 4; _TMC2130_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); }
259
+      _TMC2130_INIT(E4, planner.axis_steps_per_mm[E_AXIS
260
+        #if ENABLED(DISTINCT_E_FACTORS)
261
+          + 4
262
+        #endif
263
+      ]);
248
     #endif
264
     #endif
249
 
265
 
250
   }
266
   }
440
       _TMC2208_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
456
       _TMC2208_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
441
     #endif
457
     #endif
442
     #if ENABLED(E1_IS_TMC2208)
458
     #if ENABLED(E1_IS_TMC2208)
443
-      { constexpr int extruder = 1; _TMC2208_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); }
459
+      _TMC2208_INIT(E1, planner.axis_steps_per_mm[E_AXIS
460
+        #if ENABLED(DISTINCT_E_FACTORS)
461
+          + 1
462
+        #endif
463
+      ]);
444
     #endif
464
     #endif
445
     #if ENABLED(E2_IS_TMC2208)
465
     #if ENABLED(E2_IS_TMC2208)
446
-      { constexpr int extruder = 2; _TMC2208_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); }
466
+      _TMC2208_INIT(E2, planner.axis_steps_per_mm[E_AXIS
467
+        #if ENABLED(DISTINCT_E_FACTORS)
468
+          + 2
469
+        #endif
470
+      ]);
447
     #endif
471
     #endif
448
     #if ENABLED(E3_IS_TMC2208)
472
     #if ENABLED(E3_IS_TMC2208)
449
-      { constexpr int extruder = 3; _TMC2208_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); }
473
+      _TMC2208_INIT(E3, planner.axis_steps_per_mm[E_AXIS
474
+        #if ENABLED(DISTINCT_E_FACTORS)
475
+          + 3
476
+        #endif
477
+      ]);
450
     #endif
478
     #endif
451
     #if ENABLED(E4_IS_TMC2208)
479
     #if ENABLED(E4_IS_TMC2208)
452
-      { constexpr int extruder = 4; _TMC2208_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); }
480
+      _TMC2208_INIT(E4, planner.axis_steps_per_mm[E_AXIS
481
+        #if ENABLED(DISTINCT_E_FACTORS)
482
+          + 4
483
+        #endif
484
+      ]);
453
     #endif
485
     #endif
454
   }
486
   }
455
 #endif // HAVE_TMC2208
487
 #endif // HAVE_TMC2208

+ 22
- 4
frameworks/CMSIS/LPC1768/Re-ARM/system_LPC17xx.c View File

496
         break;
496
         break;
497
     }
497
     }
498
   }
498
   }
499
+}
500
+
501
+// detect 17x[4-8] (100MHz) or 17x9 (120MHz)
502
+static int can_120MHz() {
503
+  #define IAP_LOCATION 0x1FFF1FF1
504
+  uint32_t command[1];
505
+  uint32_t result[5];
506
+  typedef void (*IAP)(uint32_t*, uint32_t*);
507
+  IAP iap = (IAP) IAP_LOCATION;
499
 
508
 
509
+  command[0] = 54;
510
+  iap(command, result);
511
+
512
+  return result[1] & 0x00100000;
500
 }
513
 }
501
 
514
 
502
 /**
515
 /**
508
  * @brief  Setup the microcontroller system.
521
  * @brief  Setup the microcontroller system.
509
  *         Initialize the System.
522
  *         Initialize the System.
510
  */
523
  */
511
-
512
 void SystemInit (void)
524
 void SystemInit (void)
513
 {
525
 {
514
 #if (CLOCK_SETUP)                       /* Clock Setup                        */
526
 #if (CLOCK_SETUP)                       /* Clock Setup                        */
546
 
558
 
547
   LPC_SC->CCLKCFG   = 0x00000002;       /* Setup CPU Clock Divider            */
559
   LPC_SC->CCLKCFG   = 0x00000002;       /* Setup CPU Clock Divider            */
548
 
560
 
549
-  LPC_SC->PLL0CFG   = 0x00010018;     // 100MHz
550
-  LPC_SC->PLL0FEED  = 0xAA;
551
-  LPC_SC->PLL0FEED  = 0x55;
561
+  if(can_120MHz()) {
562
+    LPC_SC->PLL0CFG   = 0x0000000E;     /* configure PLL0                     */
563
+    LPC_SC->PLL0FEED  = 0xAA;
564
+    LPC_SC->PLL0FEED  = 0x55;
565
+  } else {
566
+    LPC_SC->PLL0CFG   = 0x00010018;     // 100MHz
567
+    LPC_SC->PLL0FEED  = 0xAA;
568
+    LPC_SC->PLL0FEED  = 0x55;
569
+  }
552
 
570
 
553
   LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                        */
571
   LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                        */
554
   LPC_SC->PLL0FEED  = 0xAA;
572
   LPC_SC->PLL0FEED  = 0xAA;

+ 44
- 16
frameworks/CMSIS/LPC1768/lib/chanfs/mmc_ssp.c View File

11
 /
11
 /
12
 /-------------------------------------------------------------------------*/
12
 /-------------------------------------------------------------------------*/
13
 
13
 
14
+#include "lpc17xx_ssp.h"
15
+#include "lpc17xx_clkpwr.h"
16
+#include "LPC176x.h"
17
+
14
 #define SSP_CH	1	/* SSP channel to use (0:SSP0, 1:SSP1) */
18
 #define SSP_CH	1	/* SSP channel to use (0:SSP0, 1:SSP1) */
15
 
19
 
16
-#define	CCLK		100000000UL	/* cclk frequency [Hz] */
17
-#define PCLK_SSP	50000000UL	/* PCLK frequency to be supplied for SSP [Hz] */
18
 #define SCLK_FAST	25000000UL	/* SCLK frequency under normal operation [Hz] */
20
 #define SCLK_FAST	25000000UL	/* SCLK frequency under normal operation [Hz] */
19
 #define	SCLK_SLOW	400000UL	/* SCLK frequency under initialization [Hz] */
21
 #define	SCLK_SLOW	400000UL	/* SCLK frequency under initialization [Hz] */
20
 
22
 
55
 		}
57
 		}
56
 #endif
58
 #endif
57
 
59
 
58
-#if PCLK_SSP * 1 == CCLK
59
-#define PCLKDIV_SSP	PCLKDIV_1
60
-#elif PCLK_SSP * 2 == CCLK
61
 #define PCLKDIV_SSP	PCLKDIV_2
60
 #define PCLKDIV_SSP	PCLKDIV_2
62
-#elif PCLK_SSP * 4 == CCLK
63
-#define PCLKDIV_SSP	PCLKDIV_4
64
-#elif PCLK_SSP * 8 == CCLK
65
-#define PCLKDIV_SSP	PCLKDIV_8
66
-#else
67
-#error Invalid CCLK:PCLK_SSP combination.
68
-#endif
69
 
61
 
62
+static void set_spi_clock(uint32_t target_clock)
63
+{
64
+  uint32_t prescale, cr0_div, cmp_clk, ssp_clk;
65
+
66
+  /* The SSP clock is derived from the (main system oscillator / 2),
67
+      so compute the best divider from that clock */
68
+  #if SSP_CH == 0
69
+    ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0);
70
+  #elif SSP_CH == 1
71
+    ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1);
72
+  #endif
73
+
74
+	/* Find closest divider to get at or under the target frequency.
75
+	   Use smallest prescale possible and rely on the divider to get
76
+	   the closest target frequency */
77
+	cr0_div = 0;
78
+	cmp_clk = 0xFFFFFFFF;
79
+	prescale = 2;
80
+	while (cmp_clk > target_clock)
81
+	{
82
+		cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
83
+		if (cmp_clk > target_clock)
84
+		{
85
+			cr0_div++;
86
+			if (cr0_div > 0xFF)
87
+			{
88
+				cr0_div = 0;
89
+				prescale += 2;
90
+			}
91
+		}
92
+	}
93
+
94
+  /* Write computed prescaler and divider back to register */
95
+  SSPxCR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
96
+  SSPxCR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
97
+  SSPxCPSR = prescale & SSP_CPSR_BITMASK;
98
+}
70
 
99
 
71
-#define FCLK_FAST() { SSPxCR0 = (SSPxCR0 & 0x00FF) | ((PCLK_SSP / 2 / SCLK_FAST) - 1) << 8; }
72
-#define FCLK_SLOW() { SSPxCR0 = (SSPxCR0 & 0x00FF) | ((PCLK_SSP / 2 / SCLK_SLOW) - 1) << 8; }
100
+
101
+#define FCLK_FAST() set_spi_clock(SCLK_FAST)
102
+#define FCLK_SLOW() set_spi_clock(SCLK_SLOW)
73
 
103
 
74
 
104
 
75
 
105
 
79
 
109
 
80
 ---------------------------------------------------------------------------*/
110
 ---------------------------------------------------------------------------*/
81
 
111
 
82
-#include "LPC176x.h"
83
 #include "diskio.h"
112
 #include "diskio.h"
84
 
113
 
85
 
114
 
276
 {
305
 {
277
 	__set_PCONP(PCSSPx, 1);	/* Enable SSP module */
306
 	__set_PCONP(PCSSPx, 1);	/* Enable SSP module */
278
 	__set_PCLKSEL(PCLKSSPx, PCLKDIV_SSP);	/* Select PCLK frequency for SSP */
307
 	__set_PCLKSEL(PCLKSSPx, PCLKDIV_SSP);	/* Select PCLK frequency for SSP */
279
-	SSPxCPSR = 2;			/* CPSDVSR=2 */
280
 	SSPxCR0 = 0x0007;		/* Set mode: SPI mode 0, 8-bit */
308
 	SSPxCR0 = 0x0007;		/* Set mode: SPI mode 0, 8-bit */
281
 	SSPxCR1 = 0x2;			/* Enable SSP with Master */
309
 	SSPxCR1 = 0x2;			/* Enable SSP with Master */
282
 	ATTACH_SSP();			/* Attach SSP module to I/O pads */
310
 	ATTACH_SSP();			/* Attach SSP module to I/O pads */

Loading…
Cancel
Save