From 93be53ea683d11cc454d8f3aa6c11f9c842e2ac2 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 2 Apr 2013 16:36:19 +0000 Subject: SSP driver fixes for the LPC178x; Fixes for Open1788 touchscreen driver git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5812 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/armv6-m/Toolchain.defs | 2 +- nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h | 11 +++++ nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c | 1 - nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c | 69 ++++++++++++++++++++++------- 4 files changed, 65 insertions(+), 18 deletions(-) (limited to 'nuttx/arch/arm') diff --git a/nuttx/arch/arm/src/armv6-m/Toolchain.defs b/nuttx/arch/arm/src/armv6-m/Toolchain.defs index 7fc4bf9cd..22427d188 100644 --- a/nuttx/arch/arm/src/armv6-m/Toolchain.defs +++ b/nuttx/arch/arm/src/armv6-m/Toolchain.defs @@ -160,6 +160,6 @@ endif ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),GNU_EABI) CROSSDEV ?= arm-none-eabi- ARCROSSDEV ?= arm-none-eabi- - MAXOPTIMIZATION = -O3 + MAXOPTIMIZATION = -Os ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -march=armv6-m -mfloat-abi=soft endif diff --git a/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h b/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h index e97a670a8..dd791327f 100644 --- a/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h +++ b/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h @@ -89,6 +89,17 @@ #define LPC17_SSP1_ICR (LPC17_SSP1_BASE+LPC17_SSP_ICR_OFFSET) #define LPC17_SSP1_DMACR (LPC17_SSP1_BASE+LPC17_SSP_DMACR_OFFSET) +#define LPC17_SSP2_CR0 (LPC17_SSP2_BASE+LPC17_SSP_CR0_OFFSET) +#define LPC17_SSP2_CR1 (LPC17_SSP2_BASE+LPC17_SSP_CR1_OFFSET) +#define LPC17_SSP2_DR (LPC17_SSP2_BASE+LPC17_SSP_DR_OFFSET) +#define LPC17_SSP2_SR (LPC17_SSP2_BASE+LPC17_SSP_SR_OFFSET) +#define LPC17_SSP2_CPSR (LPC17_SSP2_BASE+LPC17_SSP_CPSR_OFFSET) +#define LPC17_SSP2_IMSC (LPC17_SSP2_BASE+LPC17_SSP_IMSC_OFFSET) +#define LPC17_SSP2_RIS (LPC17_SSP2_BASE+LPC17_SSP_RIS_OFFSET) +#define LPC17_SSP2_MIS (LPC17_SSP2_BASE+LPC17_SSP_MIS_OFFSET) +#define LPC17_SSP2_ICR (LPC17_SSP2_BASE+LPC17_SSP_ICR_OFFSET) +#define LPC17_SSP2_DMACR (LPC17_SSP2_BASE+LPC17_SSP_DMACR_OFFSET) + /* Register bit definitions *********************************************************/ /* Control Register 0 */ diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c index 05c3caa20..43b2fc891 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c @@ -52,7 +52,6 @@ #include "chip.h" #include "lpc17_gpio.h" - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c index 3c9a51904..11f8da38b 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c @@ -92,6 +92,7 @@ #endif /* SSP Clocking *************************************************************/ + #if defined(LPC176x) /* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock (SSP_CLOCK). * SSP_CLOCK may be further divided by 2-254 to get the SSP clock. If we @@ -106,17 +107,16 @@ # if LPC17_CCLK > 100000000 # error "CCLK <= 100,000,000 assumed" -# endif +# endif # define SSP_PCLKSET_DIV SYSCON_PCLKSEL_CCLK # define SSP_CLOCK LPC17_CCLK +#elif defined(LPC178x) /* All peripherals are clocked by the same peripheral clock in the LPC178x * family. */ -#elif defined(LPC178x) - # define SSP_CLOCK BOARD_PCLK_FREQUENCY #endif @@ -397,10 +397,12 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock) static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) { FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; - uint32_t divisor; + uint32_t cpsdvsr; + uint32_t scr; + uint32_t regval; uint32_t actual; - /* Check if the requested frequence is the same as the frequency selection */ + /* Check if the requested frequency is the same as the frequency selection */ DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2); #ifndef CONFIG_SPI_OWNBUS @@ -412,30 +414,65 @@ static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) } #endif - /* frequency = SSP_CLOCK / divisor, or divisor = SSP_CLOCK / frequency */ + /* The SSP bit frequency is given by: + * + * frequency = SSP_CLOCK / (CPSDVSR * (SCR+1)). + * + * Let's try for a solution with the smallest value of SCR. NOTES: + * (1) In the calculations below, the value of the variable 'scr' is + * (SCR+1) in the above equation. (2) On slower LPC17xx parts, SCR + * will probably always be zero. + */ - divisor = SSP_CLOCK / frequency; + for (scr = 1; scr <= 256; scr++) + { + /* CPSDVSR = SSP_CLOCK / (SCR + 1) / frequency */ + + cpsdvsr = SSP_CLOCK / (scr * frequency); - /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + /* Break out on the first solution we find with the smallest value + * of SCR and with CPSDVSR within the maximum range or 254. + */ - if (divisor < 2) + if (cpsdvsr < 255) + { + break; + } + } + + DEBUGASSERT(scr <= 256 && cpsdvsr <= 255); + + /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + + if (cpsdvsr < 2) { - divisor = 2; + /* Clip to the minimum value. */ + + cpsdvsr = 2; } - else if (divisor > 254) + else if (cpsdvsr > 254) { - divisor = 254; + /* This should never happen */ + + cpsdvsr = 254; } - divisor = (divisor + 1) & ~1; + /* Force even */ - /* Save the new divisor value */ + cpsdvsr = (cpsdvsr + 1) & ~1; + + /* Save the new CPSDVSR and SCR values */ - ssp_putreg(priv, LPC17_SSP_CPSR_OFFSET, divisor); + ssp_putreg(priv, LPC17_SSP_CPSR_OFFSET, cpsdvsr); + + regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_SCR_MASK; + regval |= ((scr - 1) << SSP_CR0_SCR_SHIFT); + ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, regval); /* Calculate the new actual */ - actual = SSP_CLOCK / divisor; + actual = SSP_CLOCK / (cpsdvsr * scr); /* Save the frequency setting */ -- cgit v1.2.3