From 90cfe8e23bd6d93a1bb6414aa907bd36f88dac14 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 24 Dec 2015 12:35:22 -0600 Subject: [PATCH] TMS570: Initalize SCI interrupt handling logic --- arch/arm/src/tms570/chip/tms570_sci.h | 34 ++++++--- arch/arm/src/tms570/tms570_lowputc.c | 2 +- arch/arm/src/tms570/tms570_serial.c | 99 +++++++++++++++++---------- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/arch/arm/src/tms570/chip/tms570_sci.h b/arch/arm/src/tms570/chip/tms570_sci.h index a021c6020f..29dceda853 100644 --- a/arch/arm/src/tms570/chip/tms570_sci.h +++ b/arch/arm/src/tms570/chip/tms570_sci.h @@ -244,9 +244,9 @@ #define SCI_INT_PE (1 << 24) /* Bit 24: Parity error interrupt */ #define SCI_INT_OE (1 << 25) /* Bit 25: Overrun error interrupt */ #define SCI_INT_FE (1 << 26) /* Bit 26: Framing error interrupt */ -#define SCI_INT_NRE (1 << 27) /* Bit 27: No respose error interrupt */ -#define SCI_INT_ISFE (1 << 28) /* Bit 28: Inconsistene synch field error interrupt */ -#define SCI_INT_CE (1 << 29) /* Bit 29: checksum error interrupt */ +#define SCI_INT_NRE (1 << 27) /* Bit 27: No response error interrupt */ +#define SCI_INT_ISFE (1 << 28) /* Bit 28: Inconsistent synch field error interrupt */ +#define SCI_INT_CE (1 << 29) /* Bit 29: Checksum error interrupt */ #define SCI_INT_PBE (1 << 30) /* Bit 30: Physical bus error interrupt */ #define SCI_INT_BE (1 << 31) /* Bit 31: Bit error interrupt */ @@ -272,16 +272,32 @@ #define SCI_FLR_PE (1 << 24) /* Bit 24: Parity error flag */ #define SCI_FLR_OE (1 << 25) /* Bit 25: Overrun error flag */ #define SCI_FLR_FE (1 << 26) /* Bit 26: Framing error flag */ -#define SCI_FLR_NRE (1 << 27) /* Bit 27: No respose error flag */ -#define SCI_FLR_ISFE (1 << 28) /* Bit 28: Inconsistene synch field error flag */ +#define SCI_FLR_NRE (1 << 27) /* Bit 27: No response error flag */ +#define SCI_FLR_ISFE (1 << 28) /* Bit 28: Inconsistent synch field error flag */ #define SCI_FLR_CE (1 << 29) /* Bit 29: checksum error flag */ #define SCI_FLR_PBE (1 << 30) /* Bit 30: Physical bus error flag */ #define SCI_FLR_BE (1 << 31) /* Bit 31: Bit error flag */ -/* SCI Interrupt Vector Offset 0 */ -#define SCI_INTVECT0_ -/* SCI Interrupt Vector Offset 1 */ -#define SCI_INTVECT1_ +/* SCI Interrupt Vector Offset 0/1 */ + +#define SCI_INTVECT_MASK (0x1f) /* Bits 0-4: Interrupt vector offset */ +# define SCI_INTVECT_NONE (0) /* No interrupt */ +# define SCI_INTVECT_WAKEUP (1) /* Wake-up interrupt */ +# define SCI_INTVECT_ISFE (2) /* Inconsistent synch field error interrupt */ +# define SCI_INTVECT_PE (3) /* Parity error interrupt */ +# define SCI_INTVECT_ID (4) /* Identification interrupt */ +# define SCI_INTVECT_PBE (5) /* Physical bus error interrupt */ +# define SCI_INTVECT_FE (6) /* Framing error interrupt */ +# define SCI_INTVECT_BRKDT (7) /* Break detect interrupt */ +# define SCI_INTVECT_CE (8) /* Checksum error interrupt */ +# define SCI_INTVECT_OE (9) /* Overrun error interrupt */ +# define SCI_INTVECT_BE (10) /* Bit error interrupt */ +# define SCI_INTVECT_RX (11) /* Receive interrupt */ +# define SCI_INTVECT_TX (12) /* Tranmit interrupt */ +# define SCI_INTVECT_NRE (13) /* No response error interrupt */ +# define SCI_INTVECT_TOAWUS (14) /* Timeout after wakeup signal interrupt */ +# define SCI_INTVECT_TOA3WUS (15) /* Timeout after 2 Wakeup signls interrupt */ +# define SCI_INTVECT_TIMEOUT (16) /* Timeout interrupt */ /* SCI Format Control Register */ diff --git a/arch/arm/src/tms570/tms570_lowputc.c b/arch/arm/src/tms570/tms570_lowputc.c index 5186a7ce0b..3eab5654c1 100644 --- a/arch/arm/src/tms570/tms570_lowputc.c +++ b/arch/arm/src/tms570/tms570_lowputc.c @@ -295,7 +295,7 @@ int tms570_sci_configure(uint32_t base, FAR const struct sci_config_s *config) return -ERANGE; } - /* Disable all interrupts */ + /* Disable all interrupts and map them all to INT0 */ putreg32(SCI_INT_ALL, base + TMS570_SCI_CLEARINT_OFFSET); putreg32(SCI_INT_ALL, base + TMS570_SCI_CLEARINTLVL_OFFSET); diff --git a/arch/arm/src/tms570/tms570_serial.c b/arch/arm/src/tms570/tms570_serial.c index 890c2324b9..b4e9d1bb1f 100644 --- a/arch/arm/src/tms570/tms570_serial.c +++ b/arch/arm/src/tms570/tms570_serial.c @@ -279,7 +279,8 @@ static inline uint32_t tms570_serialin(struct tms570_dev_s *priv, int offset) * Name: tms570_serialout ****************************************************************************/ -static inline void tms570_serialout(struct tms570_dev_s *priv, int offset, uint32_t value) +static inline void tms570_serialout(struct tms570_dev_s *priv, int offset, + uint32_t value) { putreg32(value, priv->scibase + offset); } @@ -288,7 +289,8 @@ static inline void tms570_serialout(struct tms570_dev_s *priv, int offset, uint3 * Name: tms570_restoresciint ****************************************************************************/ -static inline void tms570_restoresciint(struct tms570_dev_s *priv, uint32_t imr) +static inline void tms570_restoresciint(struct tms570_dev_s *priv, + uint32_t imr) { /* Restore the previous interrupt state (assuming all interrupts disabled) */ @@ -431,51 +433,78 @@ static void tms570_detach(struct sci_dev_s *dev) static int tms570_interrupt(struct sci_dev_s *dev) { struct tms570_dev_s *priv; - uint32_t pending; - uint32_t imr; - int passes; - bool handled; + uint32_t intvec; - DEBUGASSERT(dev && dev->priv); + DEBUGASSERT(dev != NULL && dev->priv != NULL); priv = (struct tms570_dev_s *)dev->priv; - /* Loop until there are no characters to be transferred or, until we have - * been looping for a long time. - */ + /* Loop until there are no further pending interrupts */ - handled = true; - for (passes = 0; passes < 256 && handled; passes++) + for (; ; ) { - handled = false; - - /* Get the SCI status (we are only interested in the unmasked interrupts). */ - - priv->sr = tms570_serialin(priv, TMS570_SCI_SR_OFFSET); - imr = tms570_serialin(priv, TMS570_SCI_IMR_OFFSET); - pending = priv->sr & imr; - - /* Handle an incoming, receive byte. RXRDY: At least one complete character - * has been received and US_RHR has not yet been read. + /* Get the next pending interrupt. For most interrupts, reading the + * INVECT0 register clears the corresonding INTFLAG. */ - if ((pending & SCI_INT_RXRDY) != 0) + intvec = tms570_serialin(priv, TMS570_SCI_INTVECT0_OFFSET) & SCI_INTVECT_MASK; + + /* Handle the pending interrupt */ + + switch (intvec) { - /* Received data ready... process incoming bytes */ + case SCI_INTVECT_NONE: /* No interrupt */ + return; - sci_recvchars(dev); - handled = true; - } + case SCI_INTVECT_WAKEUP: /* Wake-up interrupt */ + /* SCI sets the WAKEUP flag if bus activity on the RX line + * either prevents power-down mode from being entered, or RX + * line activity causes an exit from power-down mode. If + * enabled wakeup interrupt is triggered once WAKEUP flag is + * set. + */ - /* Handle outgoing, transmit bytes. TXRDY: There is no character in the - * US_THR. - */ +#warning Missing Logic + break; - if ((pending & SCI_INT_TXRDY) != 0) - { - /* Transmit data register empty ... process outgoing bytes */ + /* SCI Errors */ - sci_xmitchars(dev); - handled = true; + case SCI_INTVECT_PE: /* Parity error interrupt */ + case SCI_INTVECT_FE: /* Framing error interrupt */ + case SCI_INTVECT_BRKDT: /* Break detect interrupt */ + case SCI_INTVECT_OE: /* Overrun error interrupt */ + case SCI_INTVECT_BE: /* Bit error interrupt */ +#warning Missing Logic + break; + + case SCI_INTVECT_RX: /* Receive interrupt */ + { + /* Receive data ready... process incoming bytes */ + + uart_recvchars(dev); + } + break; + + case SCI_INTVECT_TX: /* Tranmit interrupt */ + { + /* Transmit data register available ... process outgoing bytes */ + + uart_xmitchars(dev); + } + break; + + /* LIN mode only. These should never occur in SCI mode */ + + case SCI_INTVECT_ISFE: /* Inconsistent synch field error interrupt */ + case SCI_INTVECT_ID: /* Identification interrupt */ + case SCI_INTVECT_PBE: /* Physical bus error interrupt */ + case SCI_INTVECT_CE: /* Checksum error interrupt */ + case SCI_INTVECT_NRE: /* No response error interrupt */ + case SCI_INTVECT_TOAWUS: /* Timeout after wakeup signal interrupt */ + case SCI_INTVECT_TOA3WUS: /* Timeout after 2 Wakeup signls interrupt */ + case SCI_INTVECT_TIMEOUT: /* Timeout interrupt */ + + default: + PANIC(); } }