From 42619a3a81fe8201640a9e636494dcef05a3e6b2 Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Thu, 10 Sep 2020 02:41:26 -0300 Subject: [PATCH] LPC: Finish DMA transfer, use HW SPI class (#19191) --- Marlin/src/HAL/LPC1768/HAL_SPI.cpp | 109 ++++++-------------- Marlin/src/HAL/LPC1768/inc/SanityCheck.h | 2 +- Marlin/src/HAL/LPC1768/include/SPI.h | 22 +++- Marlin/src/HAL/LPC1768/tft/xpt2046.cpp | 1 - Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h | 17 ++- platformio.ini | 1 + 6 files changed, 61 insertions(+), 91 deletions(-) diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp index 00b4310d1d..3c64ea812f 100644 --- a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp +++ b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp @@ -100,72 +100,25 @@ #else - // decide which HW SPI device to use - #ifndef LPC_HW_SPI_DEV - #if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09) - #define LPC_HW_SPI_DEV 1 - #else - #if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18) - #define LPC_HW_SPI_DEV 0 - #else - #error "Invalid pins selected for hardware SPI" - #endif - #endif - #endif - #if LPC_HW_SPI_DEV == 0 - #define LPC_SSPn LPC_SSP0 - #else - #define LPC_SSPn LPC_SSP1 - #endif - void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0 - PINSEL_CFG_Type PinCfg; // data structure to hold init values - PinCfg.Funcnum = 2; - PinCfg.OpenDrain = 0; - PinCfg.Pinmode = 0; - PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN); - PinCfg.Portnum = LPC176x::pin_port(SCK_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(SCK_PIN); - - PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN); - PinCfg.Portnum = LPC176x::pin_port(MISO_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_INPUT(MISO_PIN); - - PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN); - PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(MOSI_PIN); - // divide PCLK by 2 for SSP0 - CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2); - spiInit(0); - SSP_Cmd(LPC_SSPn, ENABLE); // start SSP running + spiInit(SPI_SPEED); } void spiInit(uint8_t spiRate) { - // table to convert Marlin spiRates (0-5 plus default) into bit rates - uint32_t Marlin_speed[7]; // CPSR is always 2 - Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED - Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED - Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED - Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED - Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 - Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 - Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h - // setup for SPI mode - SSP_CFG_Type HW_SPI_init; // data structure to hold init values - SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode - HW_SPI_init.ClockRate = Marlin_speed[_MIN(spiRate, 6)]; // put in the specified bit rate - HW_SPI_init.Mode |= SSP_CR1_SSP_EN; - SSP_Init(LPC_SSPn, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers + #if MISO_PIN == BOARD_SPI1_MISO_PIN + SPI.setModule(1); + #elif MISO_PIN == BOARD_SPI2_MISO_PIN + SPI.setModule(2); + #endif + SPI.setDataSize(DATA_SIZE_8BIT); + SPI.setDataMode(SPI_MODE0); + + SPI.setClock(SPISettings::spiRate2Clock(spiRate)); + SPI.begin(); } static uint8_t doio(uint8_t b) { - /* send and receive a single byte */ - SSP_SendData(LPC_SSPn, b & 0x00FF); - while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY)); // wait for it to finish - return SSP_ReceiveData(LPC_SSPn) & 0x00FF; + return SPI.transfer(b & 0x00FF) & 0x00FF; } void spiSend(uint8_t b) { doio(b); } @@ -224,6 +177,9 @@ SPIClass::SPIClass(uint8_t device) { PINSEL_CFG_Type PinCfg; // data structure to hold init values #if BOARD_NR_SPI >= 1 _settings[0].spi_d = LPC_SSP0; + _settings[0].dataMode = SPI_MODE0; + _settings[0].dataSize = DATA_SIZE_8BIT; + _settings[0].clock = SPI_CLOCK_MAX; // _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); PinCfg.Funcnum = 2; PinCfg.OpenDrain = 0; @@ -246,6 +202,9 @@ SPIClass::SPIClass(uint8_t device) { #if BOARD_NR_SPI >= 2 _settings[1].spi_d = LPC_SSP1; + _settings[1].dataMode = SPI_MODE0; + _settings[1].dataSize = DATA_SIZE_8BIT; + _settings[1].clock = SPI_CLOCK_MAX; // _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); PinCfg.Funcnum = 2; PinCfg.OpenDrain = 0; @@ -320,7 +279,7 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) { // Destination memory - Not used GPDMACfg.DstMemAddr = 0; // Transfer size - GPDMACfg.TransferSize = (minc ? length : 1); + GPDMACfg.TransferSize = length; // Transfer width GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE; // Transfer type @@ -335,26 +294,24 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) { // Enable dma on SPI SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE); - // if minc=false, I'm repeating the same byte 'length' times, as I could not find yet how do GPDMA without memory increment - do { - // Setup channel with given parameter - GPDMA_Setup(&GPDMACfg); + // only increase memory if minc is true + GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0); - // enabled dma - GPDMA_ChannelCmd(0, ENABLE); + // Setup channel with given parameter + GPDMA_Setup(&GPDMACfg); - // wait data transfer - while (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) { } + // enabled dma + GPDMA_ChannelCmd(0, ENABLE); - // clear err and int - GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); - GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0); + // wait data transfer + while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { } - // dma disable - GPDMA_ChannelCmd(0, DISABLE); + // clear err and int + GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); + GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0); - --length; - } while (!minc && length > 0); + // dma disable + GPDMA_ChannelCmd(0, DISABLE); waitSpiTxEnd(_currentSetting->spi_d); @@ -382,7 +339,7 @@ void SPIClass::setBitOrder(uint8_t bitOrder) { } void SPIClass::setDataMode(uint8_t dataMode) { - _currentSetting->dataSize = dataMode; + _currentSetting->dataMode = dataMode; } void SPIClass::setDataSize(uint32_t ds) { diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h index 0a4e59c6c4..caec347bf5 100644 --- a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h +++ b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h @@ -24,7 +24,7 @@ #if PIO_PLATFORM_VERSION < 1001 #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." #endif -#if PIO_FRAMEWORK_VERSION < 2002 +#if PIO_FRAMEWORK_VERSION < 2005 #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries." #endif diff --git a/Marlin/src/HAL/LPC1768/include/SPI.h b/Marlin/src/HAL/LPC1768/include/SPI.h index e2645b9290..9da2a32556 100644 --- a/Marlin/src/HAL/LPC1768/include/SPI.h +++ b/Marlin/src/HAL/LPC1768/include/SPI.h @@ -61,7 +61,9 @@ class SPISettings { public: - SPISettings(uint32_t speed, int, int) : spi_speed(speed) {}; + SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) { + init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT); + } SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { if (__builtin_constant_p(inClock)) init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); @@ -72,7 +74,19 @@ public: init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); } - uint32_t spiRate() const { return spi_speed; } + //uint32_t spiRate() const { return spi_speed; } + + static inline uint32_t spiRate2Clock(uint32_t spiRate) { + uint32_t Marlin_speed[7]; // CPSR is always 2 + Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED + Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED + Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED + Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED + Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 + Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 + Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h + return Marlin_speed[spiRate > 6 ? 6 : spiRate]; + } private: void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { @@ -85,7 +99,7 @@ private: dataSize = inDataSize; } - uint32_t spi_speed; + //uint32_t spi_speed; uint32_t clock; uint32_t dataSize; //uint32_t clockDivider; @@ -122,7 +136,7 @@ public: void end(); void beginTransaction(const SPISettings&); - void endTransaction() {}; + void endTransaction() {} // Transfer using 1 "Data Size" uint8_t transfer(uint16_t data); diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp index c72e5f0eac..5f96630043 100644 --- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp @@ -72,7 +72,6 @@ bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { if (!isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - SERIAL_ECHOLNPAIR("X: ", *x, ", Y: ", *y); return isTouched(); } diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h index b32f99c68d..49c4dffa04 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h @@ -275,9 +275,6 @@ #define LCD_BACKLIGHT_PIN -1 #elif HAS_SPI_TFT // Config for Classic UI (emulated DOGM) and Color UI - #define SS_PIN -1 - //#define ONBOARD_SD_CS_PIN -1 - #define TFT_CS_PIN P1_22 #define TFT_A0_PIN P1_23 #define TFT_DC_PIN P1_23 @@ -285,7 +282,6 @@ #define TFT_BACKLIGHT_PIN P1_18 #define TFT_RESET_PIN P1_19 - #define LPC_HW_SPI_DEV 0 #define LCD_USE_DMA_SPI #define TOUCH_INT_PIN P1_21 @@ -297,15 +293,18 @@ #define GRAPHICAL_TFT_UPSCALE 3 #endif - // SPI 1 - #define SCK_PIN P0_15 - #define MISO_PIN P0_17 - #define MOSI_PIN P0_18 - // Disable any LCD related PINs config #define LCD_PINS_ENABLE -1 #define LCD_PINS_RS -1 + // Emulated DOGM have xpt calibration values independent of display resolution + #if ENABLED(SPI_GRAPHICAL_TFT) + #define XPT2046_X_CALIBRATION -11245 + #define XPT2046_Y_CALIBRATION 8629 + #define XPT2046_X_OFFSET 685 + #define XPT2046_Y_OFFSET -285 + #endif + #else #define BTN_ENC P0_28 // (58) open-drain diff --git a/platformio.ini b/platformio.ini index 4a2abf5830..0c301a4044 100644 --- a/platformio.ini +++ b/platformio.ini @@ -623,6 +623,7 @@ debug_tool = jlink # [common_LPC] platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.3.zip +platform_packages = framework-arduino-lpc176x@^0.2.5 board = nxp_lpc1768 lib_ldf_mode = off lib_compat_mode = strict