diff --git a/arch/arm/include/lpc43xx/chip.h b/arch/arm/include/lpc43xx/chip.h index e8ce651f663..dec8ecb762f 100644 --- a/arch/arm/include/lpc43xx/chip.h +++ b/arch/arm/include/lpc43xx/chip.h @@ -46,7 +46,7 @@ * Pre-processor Definitions ************************************************************************************/ -/* Per the data sheet: LPC4350/30/20/10 Rev. 3.2 — 4 June 2012 */ +/* Per the data sheet: LPC4350/30/20/10 Rev. 3.2 — 4 June 2012 */ /* Get customizations for each supported chip. * * SRAM Resources @@ -74,7 +74,7 @@ * manager. This gives some symmetry to all of the members of the family. */ -/* Per the user manual: UM10503, Rev. 1.2 — 8 June 2012 */ +/* Per the user manual: UM10503, Rev. 1.2 — 8 June 2012 */ /* Get customizations for each supported chip. * * SRAM Resources diff --git a/arch/arm/src/lpc43xx/Make.defs b/arch/arm/src/lpc43xx/Make.defs index d6990c82449..3b3f8b1948f 100644 --- a/arch/arm/src/lpc43xx/Make.defs +++ b/arch/arm/src/lpc43xx/Make.defs @@ -96,6 +96,8 @@ CHIP_CSRCS += lpc43_start.c lpc43_uart.c ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += lpc43_timerisr.c +else +CHIP_CSRCS += lpc43_tickless_rit.c endif ifeq ($(CONFIG_BUILD_PROTECTED),y) @@ -131,10 +133,10 @@ CHIP_CSRCS += lpc43_spifi.c endif ifeq ($(CONFIG_LPC43_SSP0),y) -CHIP_CSRCS += lpc43_ssp.c +CHIP_CSRCS += lpc43_ssp.c lpc43_spi.c else ifeq ($(CONFIG_LPC43_SSP1),y) -CHIP_CSRCS += lpc43_ssp.c +CHIP_CSRCS += lpc43_ssp.c lpc43_spi.c endif endif diff --git a/arch/arm/src/lpc43xx/chip/lpc43_rit.h b/arch/arm/src/lpc43xx/chip/lpc43_rit.h index 90c911e4ddb..71671cd3ab0 100644 --- a/arch/arm/src/lpc43xx/chip/lpc43_rit.h +++ b/arch/arm/src/lpc43xx/chip/lpc43_rit.h @@ -42,7 +42,6 @@ ************************************************************************************/ #include -#include "chip/lpc4310203050_memorymap.h" /************************************************************************************ * Pre-processor Definitions diff --git a/arch/arm/src/lpc43xx/chip/lpc43_timer.h b/arch/arm/src/lpc43xx/chip/lpc43_timer.h index 7627b135db4..109b8c8b7fa 100644 --- a/arch/arm/src/lpc43xx/chip/lpc43_timer.h +++ b/arch/arm/src/lpc43xx/chip/lpc43_timer.h @@ -68,77 +68,77 @@ /* Register addresses ***************************************************************/ -#define LPC43_TMR0_IR (LPC43_TMR0_BASE+LPC43_TMR_IR_OFFSET) -#define LPC43_TMR0_TCR (LPC43_TMR0_BASE+LPC43_TMR_TCR_OFFSET) -#define LPC43_TMR0_TC (LPC43_TMR0_BASE+LPC43_TMR_TC_OFFSET) -#define LPC43_TMR0_PR (LPC43_TMR0_BASE+LPC43_TMR_PR_OFFSET) -#define LPC43_TMR0_PC (LPC43_TMR0_BASE+LPC43_TMR_PC_OFFSET) -#define LPC43_TMR0_MCR (LPC43_TMR0_BASE+LPC43_TMR_MCR_OFFSET) -#define LPC43_TMR0_MR0 (LPC43_TMR0_BASE+LPC43_TMR_MR0_OFFSET) -#define LPC43_TMR0_MR1 (LPC43_TMR0_BASE+LPC43_TMR_MR1_OFFSET) -#define LPC43_TMR0_MR2 (LPC43_TMR0_BASE+LPC43_TMR_MR2_OFFSET) -#define LPC43_TMR0_MR3 (LPC43_TMR0_BASE+LPC43_TMR_MR3_OFFSET) -#define LPC43_TMR0_CCR (LPC43_TMR0_BASE+LPC43_TMR_CCR_OFFSET) -#define LPC43_TMR0_CR0 (LPC43_TMR0_BASE+LPC43_TMR_CR0_OFFSET) -#define LPC43_TMR0_CR1 (LPC43_TMR0_BASE+LPC43_TMR_CR1_OFFSET) -#define LPC43_TMR0_CR2 (LPC43_TMR0_BASE+LPC43_TMR_CR2_OFFSET) -#define LPC43_TMR0_CR3 (LPC43_TMR0_BASE+LPC43_TMR_CR3_OFFSET) -#define LPC43_TMR0_EMR (LPC43_TMR0_BASE+LPC43_TMR_EMR_OFFSET) -#define LPC43_TMR0_CTCR (LPC43_TMR0_BASE+LPC43_TMR_CTCR_OFFSET) +#define LPC43_TMR0_IR (LPC43_TIMER0_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR0_TCR (LPC43_TIMER0_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR0_TC (LPC43_TIMER0_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR0_PR (LPC43_TIMER0_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR0_PC (LPC43_TIMER0_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR0_MCR (LPC43_TIMER0_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR0_MR0 (LPC43_TIMER0_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR0_MR1 (LPC43_TIMER0_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR0_MR2 (LPC43_TIMER0_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR0_MR3 (LPC43_TIMER0_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR0_CCR (LPC43_TIMER0_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR0_CR0 (LPC43_TIMER0_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR0_CR1 (LPC43_TIMER0_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR0_CR2 (LPC43_TIMER0_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR0_CR3 (LPC43_TIMER0_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR0_EMR (LPC43_TIMER0_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR0_CTCR (LPC43_TIMER0_BASE+LPC43_TMR_CTCR_OFFSET) -#define LPC43_TMR1_IR (LPC43_TMR1_BASE+LPC43_TMR_IR_OFFSET) -#define LPC43_TMR1_TCR (LPC43_TMR1_BASE+LPC43_TMR_TCR_OFFSET) -#define LPC43_TMR1_TC (LPC43_TMR1_BASE+LPC43_TMR_TC_OFFSET) -#define LPC43_TMR1_PR (LPC43_TMR1_BASE+LPC43_TMR_PR_OFFSET) -#define LPC43_TMR1_PC (LPC43_TMR1_BASE+LPC43_TMR_PC_OFFSET) -#define LPC43_TMR1_MCR (LPC43_TMR1_BASE+LPC43_TMR_MCR_OFFSET) -#define LPC43_TMR1_MR0 (LPC43_TMR1_BASE+LPC43_TMR_MR0_OFFSET) -#define LPC43_TMR1_MR1 (LPC43_TMR1_BASE+LPC43_TMR_MR1_OFFSET) -#define LPC43_TMR1_MR2 (LPC43_TMR1_BASE+LPC43_TMR_MR2_OFFSET) -#define LPC43_TMR1_MR3 (LPC43_TMR1_BASE+LPC43_TMR_MR3_OFFSET) -#define LPC43_TMR1_CCR (LPC43_TMR1_BASE+LPC43_TMR_CCR_OFFSET) -#define LPC43_TMR1_CR0 (LPC43_TMR1_BASE+LPC43_TMR_CR0_OFFSET) -#define LPC43_TMR1_CR1 (LPC43_TMR1_BASE+LPC43_TMR_CR1_OFFSET) -#define LPC43_TMR1_CR2 (LPC43_TMR1_BASE+LPC43_TMR_CR2_OFFSET) -#define LPC43_TMR1_CR3 (LPC43_TMR1_BASE+LPC43_TMR_CR3_OFFSET) -#define LPC43_TMR1_EMR (LPC43_TMR1_BASE+LPC43_TMR_EMR_OFFSET) -#define LPC43_TMR1_CTCR (LPC43_TMR1_BASE+LPC43_TMR_CTCR_OFFSET) +#define LPC43_TMR1_IR (LPC43_TIMER1_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR1_TCR (LPC43_TIMER1_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR1_TC (LPC43_TIMER1_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR1_PR (LPC43_TIMER1_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR1_PC (LPC43_TIMER1_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR1_MCR (LPC43_TIMER1_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR1_MR0 (LPC43_TIMER1_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR1_MR1 (LPC43_TIMER1_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR1_MR2 (LPC43_TIMER1_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR1_MR3 (LPC43_TIMER1_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR1_CCR (LPC43_TIMER1_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR1_CR0 (LPC43_TIMER1_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR1_CR1 (LPC43_TIMER1_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR1_CR2 (LPC43_TIMER1_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR1_CR3 (LPC43_TIMER1_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR1_EMR (LPC43_TIMER1_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR1_CTCR (LPC43_TIMER1_BASE+LPC43_TMR_CTCR_OFFSET) -#define LPC43_TMR2_IR (LPC43_TMR2_BASE+LPC43_TMR_IR_OFFSET) -#define LPC43_TMR2_TCR (LPC43_TMR2_BASE+LPC43_TMR_TCR_OFFSET) -#define LPC43_TMR2_TC (LPC43_TMR2_BASE+LPC43_TMR_TC_OFFSET) -#define LPC43_TMR2_PR (LPC43_TMR2_BASE+LPC43_TMR_PR_OFFSET) -#define LPC43_TMR2_PC (LPC43_TMR2_BASE+LPC43_TMR_PC_OFFSET) -#define LPC43_TMR2_MCR (LPC43_TMR2_BASE+LPC43_TMR_MCR_OFFSET) -#define LPC43_TMR2_MR0 (LPC43_TMR2_BASE+LPC43_TMR_MR0_OFFSET) -#define LPC43_TMR2_MR1 (LPC43_TMR2_BASE+LPC43_TMR_MR1_OFFSET) -#define LPC43_TMR2_MR2 (LPC43_TMR2_BASE+LPC43_TMR_MR2_OFFSET) -#define LPC43_TMR2_MR3 (LPC43_TMR2_BASE+LPC43_TMR_MR3_OFFSET) -#define LPC43_TMR2_CCR (LPC43_TMR2_BASE+LPC43_TMR_CCR_OFFSET) -#define LPC43_TMR2_CR0 (LPC43_TMR2_BASE+LPC43_TMR_CR0_OFFSET) -#define LPC43_TMR2_CR1 (LPC43_TMR2_BASE+LPC43_TMR_CR1_OFFSET) -#define LPC43_TMR2_CR2 (LPC43_TMR2_BASE+LPC43_TMR_CR2_OFFSET) -#define LPC43_TMR2_CR3 (LPC43_TMR2_BASE+LPC43_TMR_CR3_OFFSET) -#define LPC43_TMR2_EMR (LPC43_TMR2_BASE+LPC43_TMR_EMR_OFFSET) -#define LPC43_TMR2_CTCR (LPC43_TMR2_BASE+LPC43_TMR_CTCR_OFFSET) +#define LPC43_TMR2_IR (LPC43_TIMER2_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR2_TCR (LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR2_TC (LPC43_TIMER2_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR2_PR (LPC43_TIMER2_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR2_PC (LPC43_TIMER2_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR2_MCR (LPC43_TIMER2_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR2_MR0 (LPC43_TIMER2_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR2_MR1 (LPC43_TIMER2_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR2_MR2 (LPC43_TIMER2_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR2_MR3 (LPC43_TIMER2_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR2_CCR (LPC43_TIMER2_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR2_CR0 (LPC43_TIMER2_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR2_CR1 (LPC43_TIMER2_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR2_CR2 (LPC43_TIMER2_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR2_CR3 (LPC43_TIMER2_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR2_EMR (LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR2_CTCR (LPC43_TIMER2_BASE+LPC43_TMR_CTCR_OFFSET) -#define LPC43_TMR3_IR (LPC43_TMR3_BASE+LPC43_TMR_IR_OFFSET) -#define LPC43_TMR3_TCR (LPC43_TMR3_BASE+LPC43_TMR_TCR_OFFSET) -#define LPC43_TMR3_TC (LPC43_TMR3_BASE+LPC43_TMR_TC_OFFSET) -#define LPC43_TMR3_PR (LPC43_TMR3_BASE+LPC43_TMR_PR_OFFSET) -#define LPC43_TMR3_PC (LPC43_TMR3_BASE+LPC43_TMR_PC_OFFSET) -#define LPC43_TMR3_MCR (LPC43_TMR3_BASE+LPC43_TMR_MCR_OFFSET) -#define LPC43_TMR3_MR0 (LPC43_TMR3_BASE+LPC43_TMR_MR0_OFFSET) -#define LPC43_TMR3_MR1 (LPC43_TMR3_BASE+LPC43_TMR_MR1_OFFSET) -#define LPC43_TMR3_MR2 (LPC43_TMR3_BASE+LPC43_TMR_MR2_OFFSET) -#define LPC43_TMR3_MR3 (LPC43_TMR3_BASE+LPC43_TMR_MR3_OFFSET) -#define LPC43_TMR3_CCR (LPC43_TMR3_BASE+LPC43_TMR_CCR_OFFSET) -#define LPC43_TMR3_CR0 (LPC43_TMR3_BASE+LPC43_TMR_CR0_OFFSET) -#define LPC43_TMR3_CR1 (LPC43_TMR3_BASE+LPC43_TMR_CR1_OFFSET) -#define LPC43_TMR3_CR2 (LPC43_TMR3_BASE+LPC43_TMR_CR2_OFFSET) -#define LPC43_TMR3_CR3 (LPC43_TMR3_BASE+LPC43_TMR_CR3_OFFSET) -#define LPC43_TMR3_EMR (LPC43_TMR3_BASE+LPC43_TMR_EMR_OFFSET) -#define LPC43_TMR3_CTCR (LPC43_TMR3_BASE+LPC43_TMR_CTCR_OFFSET) +#define LPC43_TMR3_IR (LPC43_TIMER3_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR3_TCR (LPC43_TIMER3_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR3_TC (LPC43_TIMER3_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR3_PR (LPC43_TIMER3_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR3_PC (LPC43_TIMER3_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR3_MCR (LPC43_TIMER3_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR3_MR0 (LPC43_TIMER3_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR3_MR1 (LPC43_TIMER3_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR3_MR2 (LPC43_TIMER3_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR3_MR3 (LPC43_TIMER3_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR3_CCR (LPC43_TIMER3_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR3_CR0 (LPC43_TIMER3_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR3_CR1 (LPC43_TIMER3_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR3_CR2 (LPC43_TIMER3_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR3_CR3 (LPC43_TIMER3_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR3_EMR (LPC43_TIMER3_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR3_CTCR (LPC43_TIMER3_BASE+LPC43_TMR_CTCR_OFFSET) /* Register bit definitions *********************************************************/ /* Registers holding 32-bit numeric values (no bit field definitions): diff --git a/arch/arm/src/lpc43xx/lpc43_cgu.c b/arch/arm/src/lpc43xx/lpc43_cgu.c index a50f5e93fa7..6b13ee4fd73 100644 --- a/arch/arm/src/lpc43xx/lpc43_cgu.c +++ b/arch/arm/src/lpc43xx/lpc43_cgu.c @@ -461,7 +461,7 @@ void lpc43_pll0usbenable(void) * operation and will make the lock signal high once it has regained * lock on the input clock * - * Wait for PLL1 to report that it is locked. + * Wait for PLL0 to report that it is locked. */ while ((getreg32(LPC43_PLL0USB_STAT) & PLL0USB_STAT_LOCK) == 0); diff --git a/arch/arm/src/lpc43xx/lpc43_i2c.c b/arch/arm/src/lpc43xx/lpc43_i2c.c index 8a188df978c..8dd3175e704 100644 --- a/arch/arm/src/lpc43xx/lpc43_i2c.c +++ b/arch/arm/src/lpc43xx/lpc43_i2c.c @@ -206,8 +206,7 @@ static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits) DEBUGASSERT(dev != NULL); DEBUGASSERT(nbits == 7); - priv->msg.addr = addr << 1; - priv->msg.flags = 0 ; + priv->msg.addr = addr; return OK; } @@ -231,7 +230,7 @@ static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, priv->wrcnt = 0; priv->rdcnt = 0; - priv->msg.addr &= ~0x01; + priv->msg.flags = 0; priv->msg.buffer = (uint8_t *)buffer; priv->msg.length = buflen; @@ -264,7 +263,7 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen) priv->wrcnt = 0; priv->rdcnt = 0; - priv->msg.addr |= 0x01; + priv->msg.flags = I2C_M_READ; priv->msg.buffer = buffer; priv->msg.length = buflen; @@ -364,7 +363,7 @@ static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, i priv->msgs = msgs; priv->nmsg = count; - ret = count - i2c_start(priv); + ret = i2c_start(priv); return ret; } @@ -428,7 +427,7 @@ static int i2c_interrupt(int irq, FAR void *context) case 0x08: /* A START condition has been transmitted. */ case 0x10: /* A Repeated START condition has been transmitted. */ - putreg32(msg->addr, priv->base + LPC43_I2C_DAT_OFFSET); /* set address */ + putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ)?I2C_READADDR8(msg->addr):I2C_WRITEADDR8(msg->addr), priv->base + LPC43_I2C_DAT_OFFSET); /* set address */ putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear start bit */ break; diff --git a/arch/arm/src/lpc43xx/lpc43_spi.c b/arch/arm/src/lpc43xx/lpc43_spi.c index f1ae4bbf4f2..e56367e4ef1 100644 --- a/arch/arm/src/lpc43xx/lpc43_spi.c +++ b/arch/arm/src/lpc43xx/lpc43_spi.c @@ -56,6 +56,7 @@ #include "chip.h" #include "lpc43_pinconfig.h" #include "lpc43_spi.h" +#include "lpc43_ssp.h" #ifdef CONFIG_LPC43_SPI @@ -583,3 +584,39 @@ FAR struct spi_dev_s *lpc43_spiinitialize(int port) #endif /* CONFIG_LPC43_SPI */ +/**************************************************************************** + * Name: up_spiinitialize + * + * Description: + * Initialize the selected SPI port + * 0 - SPI + * 1 - SSP0 + * 2 - SSP1 + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *up_spiinitialize(int port) +{ + if (port) { +#if ( defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) ) + return lpc43_sspinitialize(port-1); +#else + return NULL; +#endif + } else { +#if defined(CONFIG_LPC43_SPI) + return lpc43_spiinitialize(port); +#else + return NULL; +#endif + } +} + + + diff --git a/arch/arm/src/lpc43xx/lpc43_ssp.c b/arch/arm/src/lpc43xx/lpc43_ssp.c index 8fbc2ad7923..fe97cbc760f 100644 --- a/arch/arm/src/lpc43xx/lpc43_ssp.c +++ b/arch/arm/src/lpc43xx/lpc43_ssp.c @@ -162,8 +162,12 @@ static const struct spi_ops_s g_spi0ops = .cmddata = lpc43_ssp0cmddata, /* Provided externally */ #endif .send = ssp_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = ssp_exchange, +#else .sndblock = ssp_sndblock, .recvblock = ssp_recvblock, +#endif #ifdef CONFIG_SPI_CALLBACK .registercallback = lpc43_ssp0register, /* Provided externally */ #else @@ -197,8 +201,12 @@ static const struct spi_ops_s g_spi1ops = .cmddata = lpc43_ssp1cmddata, /* Provided externally */ #endif .send = ssp_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = ssp_exchange, +#else .sndblock = ssp_sndblock, .recvblock = ssp_recvblock, +#endif #ifdef CONFIG_SPI_CALLBACK .registercallback = lpc43_ssp1register, /* Provided externally */ #else @@ -526,6 +534,76 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd) return (uint16_t)regval; } +static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) { + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + union + { + FAR uint8_t *p8; + FAR uint16_t *p16; + FAR const void *pv; + } tx; + union + { + FAR uint8_t *p8; + FAR uint16_t *p16; + FAR const void *pv; + } rx; + uint32_t data; + uint32_t datadummy = (priv->nbits > 8)?0xffff:0xff; + uint32_t rxpending = 0; + + /* While there is remaining to be sent (and no synchronization error has occurred) */ + + sspdbg("nwords: %d\n", nwords); + + tx.pv = txbuffer; + rx.pv = rxbuffer; + + while (nwords || rxpending) + { + /* Write data to the data register while (1) the TX FIFO is + * not full, (2) we have not exceeded the depth of the TX FIFO, + * and (3) there are more bytes to be sent. + */ + + spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); + while ((ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF) && + (rxpending < LPC43_SSP_FIFOSZ) && nwords) + { + if (txbuffer && priv->nbits > 8) + { + data = (uint32_t)*tx.p16++; + } + else + { + data = (uint32_t)*tx.p8++; + } + + ssp_putreg(priv, LPC43_SSP_DR_OFFSET, txbuffer?data:datadummy); + nwords--; + rxpending++; + } + + /* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */ + + spivdbg("RX: rxpending: %d\n", rxpending); + while (ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE) + { + data = ssp_getreg(priv, LPC43_SSP_DR_OFFSET); + if (rxbuffer && priv->nbits > 8) + { + *rx.p16++ = (uint16_t)data; + } + else + { + *rx.p8++ = (uint8_t)data; + } + rxpending--; + } + } +} + /**************************************************************************** * Name: ssp_sndblock * @@ -547,72 +625,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd) static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) { - FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; - union - { - FAR const uint8_t *p8; - FAR const uint16_t *p16; - FAR const void *pv; - } u; - uint32_t data; - uint32_t sr; - - /* Loop while thre are bytes remaining to be sent */ - - sspdbg("nwords: %d\n", nwords); - u.pv = buffer; - while (nwords > 0) - { - /* While the TX FIFO is not full and there are bytes left to send */ - - while ((ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF) && nwords) - { - /* Fetch the data to send */ - - if (priv->nbits > 8) - { - data = (uint32_t)*u.p16++; - } - else - { - data = (uint32_t)*u.p8++; - } - - /* Send the data */ - - ssp_putreg(priv, LPC43_SSP_DR_OFFSET, data); - nwords--; - } - } - - /* Then discard all card responses until the RX & TX FIFOs are emptied. */ - - sspdbg("discarding\n"); - do - { - /* Is there anything in the RX fifo? */ - - sr = ssp_getreg(priv, LPC43_SSP_SR_OFFSET); - if ((sr & SSP_SR_RNE) != 0) - { - /* Yes.. Read and discard */ - - (void)ssp_getreg(priv, LPC43_SSP_DR_OFFSET); - } - - /* There is a race condition where TFE may go true just before - * RNE goes true and this loop terminates prematurely. The nasty little - * delay in the following solves that (it could probably be tuned - * to improve performance). - */ - - else if ((sr & SSP_SR_TFE) != 0) - { - up_udelay(100); - sr = ssp_getreg(priv, LPC43_SSP_SR_OFFSET); - } - } - while ((sr & SSP_SR_RNE) != 0 || (sr & SSP_SR_TFE) == 0); + return ssp_exchange(dev, buffer, NULL, nwords); } /**************************************************************************** @@ -636,54 +649,7 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) { - FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; - union - { - FAR uint8_t *p8; - FAR uint16_t *p16; - FAR void *pv; - } u; - uint32_t data; - uint32_t rxpending = 0; - - /* While there is remaining to be sent (and no synchronization error has occurred) */ - - sspdbg("nwords: %d\n", nwords); - u.pv = buffer; - while (nwords || rxpending) - { - /* Fill the transmit FIFO with 0xffff... - * Write 0xff to the data register while (1) the TX FIFO is - * not full, (2) we have not exceeded the depth of the TX FIFO, - * and (3) there are more bytes to be sent. - */ - - spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); - while ((ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF) && - (rxpending < LPC43_SSP_FIFOSZ) && nwords) - { - ssp_putreg(priv, LPC43_SSP_DR_OFFSET, 0xffff); - nwords--; - rxpending++; - } - - /* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */ - - spivdbg("RX: rxpending: %d\n", rxpending); - while (ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE) - { - data = (uint8_t)ssp_getreg(priv, LPC43_SSP_DR_OFFSET); - if (priv->nbits > 8) - { - *u.p16++ = (uint16_t)data; - } - else - { - *u.p8++ = (uint8_t)data; - } - rxpending--; - } - } + return ssp_exchange(dev, NULL, buffer, nwords); } /**************************************************************************** diff --git a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c new file mode 100644 index 00000000000..531755cfe4d --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c @@ -0,0 +1,773 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_rit.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * + * only controlled resets to 0 are performed, no direct set to counter + * working counter region is from 0 to TO_END + * all public functions are synchronized with disabled irqs + * + ****************************************************************************/ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/lpc43_rit.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef min +# define min(a,b) (a < b ? a : b) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t TO_RESET = UINT32_MAX / 2; +static uint32_t TO_RESET_NEXT = UINT32_MAX / 2 + UINT32_MAX / 4; +static uint32_t TO_END = UINT32_MAX / 2 + UINT32_MAX / 4 + UINT32_MAX / 8; /* any alarm should no last more than UINT32_MAX/8 */ +static struct timespec MAX_TS; + +static uint32_t COMMON_DEV; +static uint32_t MIN_TICKS; +static uint32_t MIN_NSEC; + +static uint32_t RESET_TICKS = 1000; /* ticks to add to force a reset */ + +static struct timespec base_ts; /* time base */ +static uint32_t base_rest; /* rest of ticks that is < MIN_TICKS*/ + +static struct timespec alarm_time_ts; /* alarmTime to set on next interrupt, used if not already armed */ + +static bool alarm_time_set = false; /* true if alarm_time set and need to be processed */ +static bool call = false; /* true if callback should be called on next interrupt */ +static bool forced_int = false; /* true if interrupt was forced with mask, no reset */ +static bool armed = false; /* true if alarm is armed for next match */ +static uint32_t synch = 0; /* synch all calls, recursion is possible */ +static irqstate_t g_flags; + +static uint32_t ctrl_cache; +static uint32_t mask_cache; +static uint32_t compare_cache; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* some timer HW functions */ + + static inline void lpc43_tl_set_counter (uint32_t value) +{ + putreg32(value, LPC43_RIT_COUNTER); +} + + static inline uint32_t lpc43_tl_get_counter (void) +{ + return getreg32(LPC43_RIT_COUNTER); +} + + static inline void lpc43_tl_set_compare (uint32_t value) +{ + if ( value != compare_cache) + { + compare_cache = value; + putreg32(value, LPC43_RIT_COMPVAL); + } +} + +static inline uint32_t lpc43_tl_get_compare (void) +{ + return compare_cache; +} + + static inline void lpc43_tl_set_mask (uint32_t value) +{ + if ( value != mask_cache) + { + mask_cache = value; + putreg32(value, LPC43_RIT_MASK); + } +} + +static inline uint32_t lpc43_tl_get_mask (void) +{ + return mask_cache; +} + +static inline bool lpc43_tl_get_ctrl_bit (uint32_t bit) +{ + return ((ctrl_cache & bit)?true:false); +} + + static inline void lpc43_tl_set_ctrl_bit (uint32_t bit, bool value) +{ + + if ( lpc43_tl_get_ctrl_bit(bit) != value ) { + + if (value) + { + ctrl_cache |= bit; + } + else + { + ctrl_cache &= ~bit; + } + + putreg32(ctrl_cache, LPC43_RIT_CTRL); + } +} + +static inline void lpc43_tl_set_reset_on_match (bool value) +{ + lpc43_tl_set_ctrl_bit (RIT_CTRL_ENCLR, value); +} + +static inline bool lpc43_tl_get_reset_on_match (void) +{ + return lpc43_tl_get_ctrl_bit (RIT_CTRL_ENCLR); +} + +static inline void lpc43_tl_set_enable (bool value) +{ + lpc43_tl_set_ctrl_bit (RIT_CTRL_EN, value); +} + +static inline bool lpc43_tl_get_enable (void) +{ + return lpc43_tl_get_ctrl_bit (RIT_CTRL_EN); +} + + static inline void lpc43_tl_clear_interrupt (void) +{ + putreg32(ctrl_cache | RIT_CTRL_INT, LPC43_RIT_CTRL); +} + + static inline bool lpc43_tl_get_interrupt (void) +{ + return (( getreg32(LPC43_RIT_CTRL) & RIT_CTRL_INT )?true:false); +} + +/* converters */ +static uint32_t commonDev(uint32_t a, uint32_t b) +{ + while(b !=0) + { + int h = a%b; + a = b; + b = h; + } + + return a; +} + + static void lpc43_tl_add(FAR const struct timespec *ts1, + FAR const struct timespec *ts2, + FAR struct timespec *ts3) +{ + time_t sec = ts1->tv_sec + ts2->tv_sec; + long nsec = ts1->tv_nsec + ts2->tv_nsec; + + if (nsec >= NSEC_PER_SEC) + { + nsec -= NSEC_PER_SEC; + sec++; + } + + ts3->tv_sec = sec; + ts3->tv_nsec = nsec; +} + + static void lpc43_tl_sub(FAR const struct timespec *ts1, + FAR const struct timespec *ts2, + FAR struct timespec *ts3) +{ + time_t sec; + long nsec; + + if (ts1->tv_sec < ts2->tv_sec) + { + sec = 0; + nsec = 0; + } + else if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec <= ts2->tv_nsec) + { + sec = 0; + nsec = 0; + } + else + { + sec = ts1->tv_sec - ts2->tv_sec; + if (ts1->tv_nsec < ts2->tv_nsec) + { + nsec = (ts1->tv_nsec + NSEC_PER_SEC) - ts2->tv_nsec; + sec--; + } + else + { + nsec = ts1->tv_nsec - ts2->tv_nsec; + } + } + + ts3->tv_sec = sec; + ts3->tv_nsec = nsec; +} + +static inline uint32_t lpc43_tl_ts2tick ( FAR const struct timespec *ts) + { + return ( ts->tv_sec*LPC43_CCLK + ( ts->tv_nsec/MIN_NSEC*MIN_TICKS ) ); + } + + static uint32_t lpc43_tl_tick2ts (uint32_t ticks, FAR struct timespec *ts, bool with_rest) + { + + uint32_t ticks_whole; + uint32_t ticks_rest = 0; + + if (with_rest) + { + uint32_t ticks_mult = ticks/MIN_TICKS; + ticks_whole = ticks_mult*MIN_TICKS; + ticks_rest = ticks - ticks_whole; + + } + else + { + ticks_whole = ticks; + } + + ts->tv_sec = ticks_whole/LPC43_CCLK; + ts->tv_nsec = ((ticks_whole%LPC43_CCLK)/MIN_TICKS)*MIN_NSEC; + + return ticks_rest; + } + +/* logic functions */ + +static inline void lpc43_tl_sync_up (void) { + irqstate_t flags; + flags = irqsave (); + + if ( synch == 0 ) + { + g_flags = flags; + + } + synch++; +} + +static inline void lpc43_tl_sync_down (void) { + synch--; + if ( synch == 0 ) + { + irqrestore (g_flags); + } +} + +/* assuming safe timer state, force interrupt, no reset possible */ + +static inline void lpc43_tl_force_int (void) +{ + forced_int = true; + lpc43_tl_set_reset_on_match (false); + lpc43_tl_set_mask (UINT32_MAX); + lpc43_tl_set_compare(UINT32_MAX); +} + +/* init all vars, forced_int should not be cleared */ + +static inline void lpc43_tl_init_timer_vars (void) +{ + alarm_time_set = false; + call = false; + armed = false; + +} + +/* calc RESET_TICKS and set compare to TO_RESET */ + +static void lpc43_tl_calibrate_init (void) +{ + uint32_t counter = lpc43_tl_get_counter (); + + uint32_t counter_after = lpc43_tl_get_counter (); + counter_after = TO_RESET + counter; + counter_after = counter_after - counter; + + /*shift to toReset*/ + + lpc43_tl_set_compare (counter_after); + + counter_after = lpc43_tl_get_counter (); + + RESET_TICKS = (counter_after - counter) * 2; + +} + +/* process current and set timer in default safe state */ + +static void lpc43_tl_save_timer (bool from_isr) +{ + if (forced_int) /* special case of forced interrupt by mask*/ + { + forced_int = false; + lpc43_tl_set_compare (UINT32_MAX); + lpc43_tl_set_mask (0); + lpc43_tl_clear_interrupt (); + } + else + { + + /*process reset if any*/ + + uint32_t match = lpc43_tl_get_compare (); + + /*move to end, no resets during processing*/ + + lpc43_tl_set_compare (UINT32_MAX); + lpc43_tl_set_mask (0); + + if (from_isr || lpc43_tl_get_interrupt ()) + { + if (lpc43_tl_get_reset_on_match ()) /*was reset ?*/ + { + struct timespec match_ts; + base_rest = lpc43_tl_tick2ts(match + base_rest, &match_ts,true); + lpc43_tl_add(&base_ts, &match_ts,&base_ts); + } + lpc43_tl_clear_interrupt (); + } + } +} + +/* assuming safe timer state, true if set, false - time is in the past */ + +static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set) +{ + if (compare_to_set < TO_RESET) + { + lpc43_tl_set_reset_on_match (false); + } + else + { + lpc43_tl_set_reset_on_match (true); + } + + lpc43_tl_set_compare (compare_to_set); + + //check if ok + bool reset = lpc43_tl_get_interrupt (); + uint32_t counter = lpc43_tl_get_counter (); + bool reset_after = lpc43_tl_get_interrupt (); + + if (reset != reset_after) + { + //was a reset get new counter + counter = lpc43_tl_get_counter (); + } + + if (reset_after || (!reset_after && compare_to_set > counter)) + { + return true; + } + else + { + lpc43_tl_set_compare (UINT32_MAX); + + return false; + } + +} + +/* assuming safe timer state, set_safe_compare in loop */ + +static void lpc43_tl_looped_forced_set_compare (void) +{ + uint32_t i = 1; + bool result = lpc43_tl_set_safe_compare ( + lpc43_tl_get_counter () + RESET_TICKS); /* like in calibrateInit */ + while (!result) + { + i++; + result = lpc43_tl_set_safe_compare ( + lpc43_tl_get_counter () + RESET_TICKS * i); + }; +} + +/* assuming safe timer state, true if set, false - time is in the past */ + +static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm) +{ + + uint32_t calcTime; + + if (curr < TO_RESET_NEXT) + { + calcTime = min(TO_RESET_NEXT, to_set); + } + else + { + if (curr < TO_END) + { + calcTime = min(curr + RESET_TICKS, to_set); + } + else + { + lpc43_tl_looped_forced_set_compare (); + return true; + } + } + + bool set = lpc43_tl_set_safe_compare (calcTime); + + if (arm && set && (calcTime == to_set)) + { + armed = true; + } + + return set; +} + +/* assuming safe timer state, try to set compare for normal operation */ + +static void lpc43_tl_set_default_compare (uint32_t curr) +{ + bool result = lpc43_tl_set_calc_arm (curr, UINT32_MAX, + false); + if (!result) + { + result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, + false); + if (!result) + { + lpc43_tl_looped_forced_set_compare (); + } + } + +} + +/* calculates ticks to set from alarm_time_ts and base_ts/base_rest, UINT32_MAX if overflow */ +static inline uint32_t lpc43_tl_calc_to_set (void) +{ + struct timespec diff_ts; + struct timespec ovf_ts; + + lpc43_tl_sub(&alarm_time_ts,&base_ts,&diff_ts); + + lpc43_tl_sub(&diff_ts,&MAX_TS,&ovf_ts); + if ( ovf_ts.tv_sec == 0 && ovf_ts.tv_nsec == 0 ) /* check overflow */ + { + return ( lpc43_tl_ts2tick(&diff_ts) - base_rest ); + } + else + { + return UINT32_MAX; + } + +} + +/* assuming safe timer state, used by isr: sets default compare , calls alarm */ +static inline void lpc43_tl_alarm (uint32_t curr) +{ + lpc43_tl_init_timer_vars (); + lpc43_tl_set_default_compare (curr); + + +#ifdef CONFIG_SCHED_TICKLESS_ALARM + struct timespec ts; + up_timer_gettime(&ts); + sched_alarm_expiration (&ts); +#else + sched_timer_expiration(); +#endif +} + +/* interrupt handler */ + +static int lpc43_tl_isr (int irq, FAR void *context) + { + lpc43_tl_sync_up(); + + lpc43_tl_save_timer(true); + + uint32_t curr = lpc43_tl_get_counter (); + if (call) + { + lpc43_tl_alarm(curr); + } + else + { + if (armed) + { + lpc43_tl_alarm(curr); /* armed - call alarm */ + } + else + { + if (alarm_time_set) /* need to set alarm time */ + { + uint32_t toSet = lpc43_tl_calc_to_set(); + + if (toSet > curr) + { + if (toSet > TO_END) + { + lpc43_tl_set_default_compare (curr); + } + else + { + bool set = lpc43_tl_set_calc_arm (curr, toSet, true); + if (!set) + { + lpc43_tl_alarm(curr); + } + } + } + else + { + lpc43_tl_alarm(curr); + } + } + else + { + lpc43_tl_set_default_compare (curr); + } + } + } + + lpc43_tl_sync_down(); + + return OK; + } + + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_timer_initialize (void) +{ + irqstate_t flags; + flags = irqsave (); + + ctrl_cache = getreg32(LPC43_RIT_CTRL); + ctrl_cache &= ~RIT_CTRL_INT; /* set interrupt to 0*/ + mask_cache = getreg32(LPC43_RIT_MASK); + compare_cache = getreg32(LPC43_RIT_COMPVAL); + + COMMON_DEV = commonDev(NSEC_PER_SEC,LPC43_CCLK); + MIN_TICKS = LPC43_CCLK/COMMON_DEV; + MIN_NSEC = NSEC_PER_SEC/COMMON_DEV; + + base_ts.tv_sec = 0; + base_ts.tv_nsec = 0; + base_rest = 0; + + lpc43_tl_tick2ts(TO_END,&MAX_TS,false); + + lpc43_tl_set_enable (false); + + lpc43_tl_set_compare (UINT32_MAX); + lpc43_tl_set_counter (0); + lpc43_tl_set_mask (0); + + lpc43_tl_set_reset_on_match (false); + lpc43_tl_clear_interrupt (); + + irq_attach (LPC43M4_IRQ_RITIMER, lpc43_tl_isr); + up_enable_irq (LPC43M4_IRQ_RITIMER); + + lpc43_tl_init_timer_vars (); + + lpc43_tl_set_enable (true); + + lpc43_tl_calibrate_init (); + + irqrestore (flags); + +} + + +/* no reg changes, only processing */ +int up_timer_gettime (FAR struct timespec *ts) + { + lpc43_tl_sync_up(); + + /* order of calls is important, reset can come during processing */ + + bool reset = lpc43_tl_get_interrupt (); + uint32_t count = lpc43_tl_get_counter (); + + /* not processed reset can exist */ + if (lpc43_tl_get_reset_on_match ()) + { + bool resetAfter = lpc43_tl_get_interrupt (); + + if (reset != resetAfter) /* was a reset during processing? get new counter */ + { + count = lpc43_tl_get_counter (); + } + + if (resetAfter) + { + count += lpc43_tl_get_compare (); /* count should be smaller then UINT32_MAX-TO_END -> no overflow */ + } + } + + struct timespec count_ts; + + + lpc43_tl_tick2ts(count + base_rest,&count_ts,false ); + + lpc43_tl_add(&base_ts,&count_ts,ts); + + lpc43_tl_sync_down(); + + return OK; + } + + +int up_alarm_cancel (FAR struct timespec *ts) + { + lpc43_tl_sync_up(); + + /*no reg changes, only variables logic*/ + + if ( ts != NULL ) { + up_timer_gettime (ts); + } + + /* let default setup will be done in interrupt handler or up_alarm_start */ + lpc43_tl_init_timer_vars (); + + lpc43_tl_sync_down(); + return OK; + } + +int up_alarm_start (FAR const struct timespec *ts) + { + lpc43_tl_sync_up(); + + lpc43_tl_save_timer (false); + + lpc43_tl_init_timer_vars (); + + alarm_time_set = true; + alarm_time_ts.tv_sec = ts->tv_sec; + alarm_time_ts.tv_nsec = ts->tv_nsec; + + uint32_t toSet = lpc43_tl_calc_to_set(); + + uint32_t curr = lpc43_tl_get_counter (); + + if (toSet > curr) + { + if (toSet > TO_END) /* future set */ + { + lpc43_tl_set_default_compare (curr); + } + else + { + bool set = lpc43_tl_set_calc_arm (curr, toSet, true); + if (!set) /* signal call, force interrupt handler */ + { + call = true; + lpc43_tl_force_int (); + } + + } + } + else /* signal call, force interrupt handler */ + { + call = true; + lpc43_tl_force_int (); + } + + lpc43_tl_sync_down(); + + return OK; + } + +#ifndef CONFIG_SCHED_TICKLESS_ALARM + +int up_timer_cancel(FAR struct timespec *ts) + { + lpc43_tl_sync_up(); + + if (ts != NULL) + { + struct timespec abs_ts; + up_timer_gettime(&abs_ts); + lpc43_tl_sub( &alarm_time_ts,&abs_ts,ts ); + } + + lpc43_tl_init_timer_vars (); + + lpc43_tl_sync_down(); + return OK; + } + +int up_timer_start(FAR const struct timespec *ts) + { + + lpc43_tl_sync_up(); + + struct timespec abs_ts; + up_timer_gettime(&abs_ts); + lpc43_tl_add(&abs_ts,ts,&abs_ts); + + up_alarm_start(&abs_ts); + + lpc43_tl_sync_down(); + return OK; + } + +# endif /* CONFIG_SCHED_TICKLESS_ALARM */ + +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/lpc43xx/lpc43_usb0dev.c b/arch/arm/src/lpc43xx/lpc43_usb0dev.c index 849f90626ea..4af4e887919 100644 --- a/arch/arm/src/lpc43xx/lpc43_usb0dev.c +++ b/arch/arm/src/lpc43xx/lpc43_usb0dev.c @@ -1079,9 +1079,8 @@ static void lpc43_usbreset(struct lpc43_usbdev_s *priv) { int epphy; - /* Disable all endpoints */ + /* Disable all endpoints. Control endpoint 0 is always enabled */ - lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL0); lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL1); lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL2); lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL3); @@ -2584,12 +2583,9 @@ void up_usbinitialize(void) struct lpc43_usbdev_s *priv = &g_usbdev; int i; uint32_t regval; + irqstate_t flags; - usbtrace(TRACE_DEVINIT, 0); - - /* Disable USB interrupts */ - - lpc43_putreg(0, LPC43_USBDEV_USBINTR); + flags = irqsave(); /* Initialize the device state structure */ @@ -2647,10 +2643,15 @@ void up_usbinitialize(void) } } + /* Enable PLL0 clock */ + + lpc43_pll0usbconfig(); + lpc43_pll0usbenable(); + /* Clock */ regval = getreg32(LPC43_BASE_USB0_CLK); - regval &= ~BASE_USB0_CLK_CLKSEL_MASK; + regval &= ~(BASE_USB0_CLK_CLKSEL_MASK | BASE_USB0_CLK_PD) ; regval |= (BASE_USB0_CLKSEL_PLL0USB | BASE_USB0_CLK_AUTOBLOCK); putreg32(regval, LPC43_BASE_USB0_CLK); @@ -2660,20 +2661,11 @@ void up_usbinitialize(void) regval |= CCU_CLK_CFG_RUN; putreg32(regval, LPC43_CCU1_M4_USB0_CFG); - /* Enable PLL0 clock */ + //lpc43_putreg(RGU_CTRL0_USB0_RST, LPC43_RGU_CTRL0); /* Reset USB block */ - lpc43_pll0usbconfig(); - lpc43_pll0usbenable(); + lpc43_pullup(&priv->usbdev, false); /* disconnect device */ - /* Reset USB block */ - - regval = lpc43_getreg(LPC43_RGU_CTRL0); - regval |= RGU_CTRL0_USB0_RST; - lpc43_putreg(regval, LPC43_RGU_CTRL0); - - /* Reset the controller */ - - lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); + lpc43_setbits (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); /* Reset the controller */ while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST) ; @@ -2683,33 +2675,25 @@ void up_usbinitialize(void) regval &= ~CREG0_USB0PHY; putreg32(regval, LPC43_CREG0); - /* Attach USB controller interrupt handler */ - - if (irq_attach(LPC43M4_IRQ_USB0, lpc43_usbinterrupt) != 0) - { - usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_IRQREGISTRATION), - (uint16_t)LPC43M4_IRQ_USB0); - goto errout; - } - + lpc43_putreg(0, LPC43_USBDEV_USBINTR); /* Disable USB interrupts */ /* Program the controller to be the USB device controller */ lpc43_putreg (USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM | USBDEV_USBMODE_CM_DEVICE, LPC43_USBDEV_USBMODE); - /* Disconnect device */ + /* Attach USB controller interrupt handler */ - lpc43_pullup(&priv->usbdev, false); + irq_attach(LPC43M4_IRQ_USB0, lpc43_usbinterrupt); + up_enable_irq(LPC43M4_IRQ_USB0); + + irqrestore(flags); /* Reset/Re-initialize the USB hardware */ lpc43_usbreset(priv); return; - -errout: - up_usbuninitialize(); } /**************************************************************************** @@ -2742,7 +2726,7 @@ void up_usbuninitialize(void) /* Reset the controller */ - lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); + lpc43_setbits (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST) ; @@ -2850,3 +2834,4 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver) g_usbdev.driver = NULL; return OK; } +