LPC: Finish DMA transfer, use HW SPI class (#19191)
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							8393c6a63d
						
					
				
				
					commit
					42619a3a81
				
			| @@ -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) { | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user