Skip to content

Commit 3f09f99

Browse files
rhapsodyvvgadreau
authored andcommitted
LPC: Finish DMA transfer, use HW SPI class (MarlinFirmware#19191)
1 parent e55344b commit 3f09f99

File tree

6 files changed

+61
-91
lines changed

6 files changed

+61
-91
lines changed

Marlin/src/HAL/LPC1768/HAL_SPI.cpp

+33-76
Original file line numberDiff line numberDiff line change
@@ -100,72 +100,25 @@
100100

101101
#else
102102

103-
// decide which HW SPI device to use
104-
#ifndef LPC_HW_SPI_DEV
105-
#if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
106-
#define LPC_HW_SPI_DEV 1
107-
#else
108-
#if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18)
109-
#define LPC_HW_SPI_DEV 0
110-
#else
111-
#error "Invalid pins selected for hardware SPI"
112-
#endif
113-
#endif
114-
#endif
115-
#if LPC_HW_SPI_DEV == 0
116-
#define LPC_SSPn LPC_SSP0
117-
#else
118-
#define LPC_SSPn LPC_SSP1
119-
#endif
120-
121103
void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
122-
PINSEL_CFG_Type PinCfg; // data structure to hold init values
123-
PinCfg.Funcnum = 2;
124-
PinCfg.OpenDrain = 0;
125-
PinCfg.Pinmode = 0;
126-
PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN);
127-
PinCfg.Portnum = LPC176x::pin_port(SCK_PIN);
128-
PINSEL_ConfigPin(&PinCfg);
129-
SET_OUTPUT(SCK_PIN);
130-
131-
PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN);
132-
PinCfg.Portnum = LPC176x::pin_port(MISO_PIN);
133-
PINSEL_ConfigPin(&PinCfg);
134-
SET_INPUT(MISO_PIN);
135-
136-
PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN);
137-
PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN);
138-
PINSEL_ConfigPin(&PinCfg);
139-
SET_OUTPUT(MOSI_PIN);
140-
// divide PCLK by 2 for SSP0
141-
CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
142-
spiInit(0);
143-
SSP_Cmd(LPC_SSPn, ENABLE); // start SSP running
104+
spiInit(SPI_SPEED);
144105
}
145106

146107
void spiInit(uint8_t spiRate) {
147-
// table to convert Marlin spiRates (0-5 plus default) into bit rates
148-
uint32_t Marlin_speed[7]; // CPSR is always 2
149-
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
150-
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
151-
Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
152-
Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
153-
Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
154-
Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
155-
Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
156-
// setup for SPI mode
157-
SSP_CFG_Type HW_SPI_init; // data structure to hold init values
158-
SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode
159-
HW_SPI_init.ClockRate = Marlin_speed[_MIN(spiRate, 6)]; // put in the specified bit rate
160-
HW_SPI_init.Mode |= SSP_CR1_SSP_EN;
161-
SSP_Init(LPC_SSPn, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
108+
#if MISO_PIN == BOARD_SPI1_MISO_PIN
109+
SPI.setModule(1);
110+
#elif MISO_PIN == BOARD_SPI2_MISO_PIN
111+
SPI.setModule(2);
112+
#endif
113+
SPI.setDataSize(DATA_SIZE_8BIT);
114+
SPI.setDataMode(SPI_MODE0);
115+
116+
SPI.setClock(SPISettings::spiRate2Clock(spiRate));
117+
SPI.begin();
162118
}
163119

164120
static uint8_t doio(uint8_t b) {
165-
/* send and receive a single byte */
166-
SSP_SendData(LPC_SSPn, b & 0x00FF);
167-
while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY)); // wait for it to finish
168-
return SSP_ReceiveData(LPC_SSPn) & 0x00FF;
121+
return SPI.transfer(b & 0x00FF) & 0x00FF;
169122
}
170123

171124
void spiSend(uint8_t b) { doio(b); }
@@ -224,6 +177,9 @@ SPIClass::SPIClass(uint8_t device) {
224177
PINSEL_CFG_Type PinCfg; // data structure to hold init values
225178
#if BOARD_NR_SPI >= 1
226179
_settings[0].spi_d = LPC_SSP0;
180+
_settings[0].dataMode = SPI_MODE0;
181+
_settings[0].dataSize = DATA_SIZE_8BIT;
182+
_settings[0].clock = SPI_CLOCK_MAX;
227183
// _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
228184
PinCfg.Funcnum = 2;
229185
PinCfg.OpenDrain = 0;
@@ -246,6 +202,9 @@ SPIClass::SPIClass(uint8_t device) {
246202

247203
#if BOARD_NR_SPI >= 2
248204
_settings[1].spi_d = LPC_SSP1;
205+
_settings[1].dataMode = SPI_MODE0;
206+
_settings[1].dataSize = DATA_SIZE_8BIT;
207+
_settings[1].clock = SPI_CLOCK_MAX;
249208
// _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
250209
PinCfg.Funcnum = 2;
251210
PinCfg.OpenDrain = 0;
@@ -320,7 +279,7 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
320279
// Destination memory - Not used
321280
GPDMACfg.DstMemAddr = 0;
322281
// Transfer size
323-
GPDMACfg.TransferSize = (minc ? length : 1);
282+
GPDMACfg.TransferSize = length;
324283
// Transfer width
325284
GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
326285
// Transfer type
@@ -335,26 +294,24 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
335294
// Enable dma on SPI
336295
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
337296

338-
// if minc=false, I'm repeating the same byte 'length' times, as I could not find yet how do GPDMA without memory increment
339-
do {
340-
// Setup channel with given parameter
341-
GPDMA_Setup(&GPDMACfg);
297+
// only increase memory if minc is true
298+
GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
342299

343-
// enabled dma
344-
GPDMA_ChannelCmd(0, ENABLE);
300+
// Setup channel with given parameter
301+
GPDMA_Setup(&GPDMACfg);
345302

346-
// wait data transfer
347-
while (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) { }
303+
// enabled dma
304+
GPDMA_ChannelCmd(0, ENABLE);
348305

349-
// clear err and int
350-
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
351-
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
306+
// wait data transfer
307+
while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
352308

353-
// dma disable
354-
GPDMA_ChannelCmd(0, DISABLE);
309+
// clear err and int
310+
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
311+
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
355312

356-
--length;
357-
} while (!minc && length > 0);
313+
// dma disable
314+
GPDMA_ChannelCmd(0, DISABLE);
358315

359316
waitSpiTxEnd(_currentSetting->spi_d);
360317

@@ -382,7 +339,7 @@ void SPIClass::setBitOrder(uint8_t bitOrder) {
382339
}
383340

384341
void SPIClass::setDataMode(uint8_t dataMode) {
385-
_currentSetting->dataSize = dataMode;
342+
_currentSetting->dataMode = dataMode;
386343
}
387344

388345
void SPIClass::setDataSize(uint32_t ds) {

Marlin/src/HAL/LPC1768/inc/SanityCheck.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#if PIO_PLATFORM_VERSION < 1001
2525
#error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically."
2626
#endif
27-
#if PIO_FRAMEWORK_VERSION < 2002
27+
#if PIO_FRAMEWORK_VERSION < 2005
2828
#error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
2929
#endif
3030

Marlin/src/HAL/LPC1768/include/SPI.h

+18-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161

6262
class SPISettings {
6363
public:
64-
SPISettings(uint32_t speed, int, int) : spi_speed(speed) {};
64+
SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) {
65+
init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT);
66+
}
6567
SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
6668
if (__builtin_constant_p(inClock))
6769
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
@@ -72,7 +74,19 @@ class SPISettings {
7274
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
7375
}
7476

75-
uint32_t spiRate() const { return spi_speed; }
77+
//uint32_t spiRate() const { return spi_speed; }
78+
79+
static inline uint32_t spiRate2Clock(uint32_t spiRate) {
80+
uint32_t Marlin_speed[7]; // CPSR is always 2
81+
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
82+
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
83+
Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
84+
Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
85+
Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
86+
Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
87+
Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
88+
return Marlin_speed[spiRate > 6 ? 6 : spiRate];
89+
}
7690

7791
private:
7892
void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
@@ -85,7 +99,7 @@ class SPISettings {
8599
dataSize = inDataSize;
86100
}
87101

88-
uint32_t spi_speed;
102+
//uint32_t spi_speed;
89103
uint32_t clock;
90104
uint32_t dataSize;
91105
//uint32_t clockDivider;
@@ -122,7 +136,7 @@ class SPIClass {
122136
void end();
123137

124138
void beginTransaction(const SPISettings&);
125-
void endTransaction() {};
139+
void endTransaction() {}
126140

127141
// Transfer using 1 "Data Size"
128142
uint8_t transfer(uint16_t data);

Marlin/src/HAL/LPC1768/tft/xpt2046.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
7272
if (!isTouched()) return false;
7373
*x = getRawData(XPT2046_X);
7474
*y = getRawData(XPT2046_Y);
75-
SERIAL_ECHOLNPAIR("X: ", *x, ", Y: ", *y);
7675
return isTouched();
7776
}
7877

Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h

+8-9
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,13 @@
275275
#define LCD_BACKLIGHT_PIN -1
276276

277277
#elif HAS_SPI_TFT // Config for Classic UI (emulated DOGM) and Color UI
278-
#define SS_PIN -1
279-
//#define ONBOARD_SD_CS_PIN -1
280-
281278
#define TFT_CS_PIN P1_22
282279
#define TFT_A0_PIN P1_23
283280
#define TFT_DC_PIN P1_23
284281
#define TFT_MISO_PIN P0_17
285282
#define TFT_BACKLIGHT_PIN P1_18
286283
#define TFT_RESET_PIN P1_19
287284

288-
#define LPC_HW_SPI_DEV 0
289285
#define LCD_USE_DMA_SPI
290286

291287
#define TOUCH_INT_PIN P1_21
@@ -297,15 +293,18 @@
297293
#define GRAPHICAL_TFT_UPSCALE 3
298294
#endif
299295

300-
// SPI 1
301-
#define SCK_PIN P0_15
302-
#define MISO_PIN P0_17
303-
#define MOSI_PIN P0_18
304-
305296
// Disable any LCD related PINs config
306297
#define LCD_PINS_ENABLE -1
307298
#define LCD_PINS_RS -1
308299

300+
// Emulated DOGM have xpt calibration values independent of display resolution
301+
#if ENABLED(SPI_GRAPHICAL_TFT)
302+
#define XPT2046_X_CALIBRATION -11245
303+
#define XPT2046_Y_CALIBRATION 8629
304+
#define XPT2046_X_OFFSET 685
305+
#define XPT2046_Y_OFFSET -285
306+
#endif
307+
309308
#else
310309

311310
#define BTN_ENC P0_28 // (58) open-drain

platformio.ini

+1
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ debug_tool = jlink
466466
#
467467
[common_LPC]
468468
platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.3.zip
469+
platform_packages = framework-arduino-lpc176x@^0.2.5
469470
board = nxp_lpc1768
470471
lib_ldf_mode = off
471472
lib_compat_mode = strict

0 commit comments

Comments
 (0)