mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 11:26:12 +08:00
More Kinetis logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3881 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -50,8 +50,8 @@
|
|||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Definitions
|
* Definitions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
/* IRQ numbers **********************************************************************/
|
||||||
/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to
|
/* The IRQ numbers corresponds directly to vector numbers and hence map directly to
|
||||||
* bits in the NVIC. This does, however, waste several words of memory in the IRQ
|
* bits in the NVIC. This does, however, waste several words of memory in the IRQ
|
||||||
* to handle mapping tables.
|
* to handle mapping tables.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -115,10 +115,12 @@
|
|||||||
* Private Variables
|
* Private Variables
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
static uint8_t g_sizemap[8] = {1, 4, 8, 16, 32, 64, 128, 0};
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -296,10 +298,11 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
|
|||||||
uint32_t clock, unsigned int parity,
|
uint32_t clock, unsigned int parity,
|
||||||
unsigned int nbits)
|
unsigned int nbits)
|
||||||
{
|
{
|
||||||
uint32_t sbr;
|
uint32_t sbr;
|
||||||
uint32_t brfa;
|
uint32_t brfa;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
uint8_t regval;
|
uint8_t regval;
|
||||||
|
unsigned int depth;
|
||||||
|
|
||||||
/* Disable the transmitter and receiver throughout the reconfiguration */
|
/* Disable the transmitter and receiver throughout the reconfiguration */
|
||||||
|
|
||||||
@@ -384,10 +387,32 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
|
|||||||
regval |= ((uint8_t)brfa << UART_C4_BRFA_SHIFT) & UART_C4_BRFA_MASK;
|
regval |= ((uint8_t)brfa << UART_C4_BRFA_SHIFT) & UART_C4_BRFA_MASK;
|
||||||
putreg8(regval, uart_base+KINETIS_UART_C4_OFFSET);
|
putreg8(regval, uart_base+KINETIS_UART_C4_OFFSET);
|
||||||
|
|
||||||
|
/* Set the FIFO watermarks */
|
||||||
|
|
||||||
|
regval = getreg8(uart_base+KINETIS_UART_PFIFO_OFFSET);
|
||||||
|
|
||||||
|
depth = g_sizemap[(regval & UART_PFIFO_RXFIFOSIZE_MASK) >> UART_PFIFO_RXFIFOSIZE_SHIFT];
|
||||||
|
if (depth > 1)
|
||||||
|
{
|
||||||
|
depth = (3 * depth) >> 2;
|
||||||
|
}
|
||||||
|
putreg8(depth , uart_base+KINETIS_UART5_RWFIFO);
|
||||||
|
|
||||||
|
depth = g_sizemap[(regval & UART_PFIFO_TXFIFOSIZE_MASK) >> UART_PFIFO_TXFIFOSIZE_SHIFT];
|
||||||
|
if (depth > 3)
|
||||||
|
{
|
||||||
|
depth = (depth >> 2);
|
||||||
|
}
|
||||||
|
putreg8(depth, uart_base+KINETIS_UART5_TWFIFO);
|
||||||
|
|
||||||
|
/* Enable RX and TX FIFOs */
|
||||||
|
|
||||||
|
putreg8(UART_PFIFO_RXFE | UART_PFIFO_TXFE, uart_base+KINETIS_UART_PFIFO_OFFSET);
|
||||||
|
|
||||||
/* Now we can re-enable the transmitter and receiver */
|
/* Now we can re-enable the transmitter and receiver */
|
||||||
|
|
||||||
regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET);
|
regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET);
|
||||||
regval |= (UART_C2_RE|UART_C2_TE);
|
regval |= (UART_C2_RE | UART_C2_TE);
|
||||||
putreg8(regval, uart_base+KINETIS_UART_C2_OFFSET);
|
putreg8(regval, uart_base+KINETIS_UART_C2_OFFSET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,8 +40,13 @@
|
|||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
|
#include "kinetis_port.h"
|
||||||
|
|
||||||
#ifdef CONFIG_GPIO_IRQ
|
#ifdef CONFIG_GPIO_IRQ
|
||||||
|
|
||||||
@@ -49,9 +54,15 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/* Configuration ************************************************************/
|
/* Configuration ************************************************************/
|
||||||
|
/* The Kinetis port interrupt logic is very flexible and will program interrupts on
|
||||||
|
* most all pin events. In order to keep the memory usage to a minimum, the NuttX
|
||||||
|
* port supports enabling interrupts on a per-port basis.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdndef CONFIG_KINESIS_NGPIOIRQS
|
#if defined (CONFIG_KINETIS_PORTAINTS) || defined (CONFIG_KINETIS_PORTBINTS) || \
|
||||||
# define CONFIG_KINESIS_NGPIOIRQS 8
|
defined (CONFIG_KINETIS_PORTCINTS) || defined (CONFIG_KINETIS_PORTDINTS) || \
|
||||||
|
defined (CONFIG_KINETIS_PORTEINTS)
|
||||||
|
# undef HAVE_PORTINTS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -61,48 +72,197 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
/* Per pin port interrupt vectors. NOTE: Not all pins in each port
|
||||||
|
* correspond to externally available GPIOs. However, I believe that the
|
||||||
|
* Kinesis will support interrupts even if the pin is not available as
|
||||||
|
* a GPIO. Hence, we need to support all 32 pins for each port. To keep the
|
||||||
|
* memory usage at a minimum, the logic may be configure per port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_KINETIS_PORTAINTS
|
||||||
|
static xcpt_t g_portaisrs[32];
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTBINTS
|
||||||
|
static xcpt_t g_portbisrs[32];
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTCINTS
|
||||||
|
static xcpt_t g_portcisrs[32];
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTDINTS
|
||||||
|
static xcpt_t g_portdisrs[32];
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTEINTS
|
||||||
|
static xcpt_t g_porteisrs[32];
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: kinetis_portinterrupt
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Common port interrupt handling.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_PORTINTS
|
||||||
|
static int kinetis_portainterrupt(int irq, FAR void *context,
|
||||||
|
uintptr_t addr, xcpt_t **xcpt)
|
||||||
|
{
|
||||||
|
uint32_t isfr = getreg32(addr);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Examine each pin in the port */
|
||||||
|
|
||||||
|
for (i = 0; i < 32 && isfr != 0; i++)
|
||||||
|
{
|
||||||
|
/* A bit set in the ISR means that an interrupt is pending for this
|
||||||
|
* pin. If the pin is programmed for level sensitive inputs, then
|
||||||
|
* the interrupt handling logic MUST disable the interrupt (or cause
|
||||||
|
* the level to change) to prevent infinite interrupts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t bit = (1 << i);
|
||||||
|
if ((isfr & bit )) != 0)
|
||||||
|
{
|
||||||
|
/* I think that bits may be set in the ISFR for DMA activities
|
||||||
|
* well. So, no error is declared if there is no registered
|
||||||
|
* interrupt handler for the pin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (xcpt[i])
|
||||||
|
{
|
||||||
|
/* There is a registered interrupt handler... invoke it */
|
||||||
|
|
||||||
|
(void)xcpt[i](irq, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Writing a one to the ISFR register will clear the pending
|
||||||
|
* interrupt. If pin is configured to generate a DMA request
|
||||||
|
* then the ISFR bit will be cleared automatically at the
|
||||||
|
* completion of the requested DMA transfer. If configured for
|
||||||
|
* a level sensitive interrupt and the pin remains asserted and
|
||||||
|
* the bit will set again immediately after it is cleared.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isfr &= ~bit;
|
||||||
|
putreg32(bit, addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: kinetis_portXinterrupt
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Handle interrupts arriving on individual ports
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_KINETIS_PORTAINTS
|
||||||
|
static int kinetis_portainterrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
return kinetis_portinterrupt(irq, context, KINETIS_PORTA_ISFR, g_portaisrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTBINTS
|
||||||
|
static int kinetis_portbinterrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
return kinetis_portinterrupt(irq, context, KINETIS_PORTB_ISFR, g_portbisrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTCINTS
|
||||||
|
static int kinetis_portcinterrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
return kinetis_portinterrupt(irq, context, KINETIS_PORTC_ISFR, g_portcisrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTDINTS
|
||||||
|
static int kinetis_portdinterrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
return kinetis_portinterrupt(irq, context, KINETIS_PORTD_ISFR, g_portdisrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTEINTS
|
||||||
|
static int kinetis_porteinterrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
return kinetis_portinterrupt(irq, context, KINETIS_PORTE_ISFR, g_porteisrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: kinetis_pinirqinitialize
|
* Name: kinetis_pinirqinitialize
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize logic to support a second level of interrupt decoding for GPIO pins.
|
* Initialize logic to support a second level of interrupt decoding for
|
||||||
|
* GPIO pins.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void kinetis_pinirqinitialize(void)
|
void kinetis_pinirqinitialize(void)
|
||||||
{
|
{
|
||||||
# warning "Missing logic"
|
#ifdef CONFIG_KINETIS_PORTAINTS
|
||||||
|
(void)irq_attach(KINETIS_IRQ_PORTA, kinetis_portainterrupt);
|
||||||
|
putreg32(0xffffffff, KINETIS_PORTA_ISFR);
|
||||||
|
up_enable_irq(KINETIS_IRQ_PORTA);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTBINTS
|
||||||
|
(void)irq_attach(KINETIS_IRQ_PORTB, kinetis_portbinterrupt);
|
||||||
|
putreg32(0xffffffff, KINETIS_PORTB_ISFR);
|
||||||
|
up_enable_irq(KINETIS_IRQ_PORTB);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTCINTS
|
||||||
|
(void)irq_attach(KINETIS_IRQ_PORTC, kinetis_portcinterrupt);
|
||||||
|
putreg32(0xffffffff, KINETIS_PORTC_ISFR);
|
||||||
|
up_enable_irq(KINETIS_IRQ_PORTC);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTDINTS
|
||||||
|
(void)irq_attach(KINETIS_IRQ_PORTD, kinetis_portdinterrupt);
|
||||||
|
putreg32(0xffffffff, KINETIS_PORTD_ISFR);
|
||||||
|
up_enable_irq(KINETIS_IRQ_PORTD);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTEINTS
|
||||||
|
(void)irq_attach(KINETIS_IRQ_PORTE, kinetis_porteinterrupt);
|
||||||
|
putreg32(0xffffffff, KINETIS_PORTE_ISFR);
|
||||||
|
up_enable_irq(KINETIS_IRQ_PORTE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: kinetis_pinirqconfig
|
* Name: kinetis_pinirqconfig
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Sets/clears PIN and interrupt triggers. On return PIN interrupts are always
|
* Sets/clears PIN and interrupt triggers. On return PIN interrupts are
|
||||||
* disabled.
|
* always disabled.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* - pinset: Pin configuration
|
* - pinset: Pin configuration
|
||||||
* - pinisr: Pin interrupt service routine
|
* - pinisr: Pin interrupt service routine
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* The previous value of the interrupt handler function pointer. This value may,
|
* The previous value of the interrupt handler function pointer. This
|
||||||
* for example, be used to restore the previous handler when multiple handlers are
|
* value may, for example, be used to restore the previous handler whe
|
||||||
* used.
|
* multiple handlers are used.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
xcpt_t kinetis_pinirqconfig(uint32_t pinset, xcpt_t pinisr)
|
xcpt_t kinetis_pinirqconfig(uint32_t pinset, xcpt_t pinisr)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_PORTINTS
|
||||||
|
xcpt_t **table;
|
||||||
|
xcpt_t oldisr;
|
||||||
|
irqstate_t flags;
|
||||||
|
unsigned int port;
|
||||||
|
unsigned int pin;
|
||||||
|
|
||||||
/* It only makes sense to call this function for input pins that are configured
|
/* It only makes sense to call this function for input pins that are configured
|
||||||
* as interrupts.
|
* as interrupts.
|
||||||
@@ -111,8 +271,54 @@ xcpt_t kinetis_pinirqconfig(uint32_t pinset, xcpt_t pinisr)
|
|||||||
DEBUGASSERT((pinset & _PIN_INTDMA_MASK) == _PIN_INTERRUPT);
|
DEBUGASSERT((pinset & _PIN_INTDMA_MASK) == _PIN_INTERRUPT);
|
||||||
DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT);
|
DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT);
|
||||||
|
|
||||||
# warning "Missing logic"
|
/* Get the port number and pin number */
|
||||||
return NULL;
|
|
||||||
|
port = (cfgset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT;
|
||||||
|
pin = (cfgset & _PIN_MASK) >> _PIN_SHIFT;
|
||||||
|
|
||||||
|
/* Get the table associated with this port */
|
||||||
|
|
||||||
|
DEBUGASSERT(port < KINETIS_NPORTS);
|
||||||
|
flags = irqsave();
|
||||||
|
switch (port)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KINETIS_PORTAINTS
|
||||||
|
case KINETIS_PORTA :
|
||||||
|
table = g_portaisrs;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTBINTS
|
||||||
|
case KINETIS_PORTB :
|
||||||
|
table = g_portbisrs;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTCINTS
|
||||||
|
case KINETIS_PORTC :
|
||||||
|
table = g_portcisrs;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTDINTS
|
||||||
|
case KINETIS_PORTD :
|
||||||
|
table = g_portdisrs;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_KINETIS_PORTEINTS
|
||||||
|
case KINETIS_PORTE :
|
||||||
|
table = g_porteisrs;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the old PIN ISR and set the new PIN ISR */
|
||||||
|
|
||||||
|
oldisr = table[pin];
|
||||||
|
table[pin] = pinisr;
|
||||||
|
|
||||||
|
/* And return the old PIN isr address */
|
||||||
|
|
||||||
|
return oldisr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@@ -125,6 +331,7 @@ xcpt_t kinetis_pinirqconfig(uint32_t pinset, xcpt_t pinisr)
|
|||||||
|
|
||||||
void kinetis_pinirqenable(uint32_t pinset)
|
void kinetis_pinirqenable(uint32_t pinset)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_PORTINTS
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
@@ -173,6 +380,7 @@ void kinetis_pinirqenable(uint32_t pinset)
|
|||||||
|
|
||||||
putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin));
|
putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@@ -185,6 +393,7 @@ void kinetis_pinirqenable(uint32_t pinset)
|
|||||||
|
|
||||||
void kinetis_pinirqdisable(uint32_t pinset)
|
void kinetis_pinirqdisable(uint32_t pinset)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_PORTINTS
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
@@ -206,6 +415,6 @@ void kinetis_pinirqdisable(uint32_t pinset)
|
|||||||
regval &= ~PORT_PCR_IRQC_MASK;
|
regval &= ~PORT_PCR_IRQC_MASK;
|
||||||
putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin));
|
putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_GPIO_IRQ */
|
#endif /* CONFIG_GPIO_IRQ */
|
||||||
|
|||||||
@@ -223,20 +223,6 @@
|
|||||||
# define UART5_ASSIGNED 1
|
# define UART5_ASSIGNED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* These values describe the set of enabled interrupts */
|
|
||||||
|
|
||||||
#define IE_RX (1 << 0)
|
|
||||||
#define IE_TX (1 << 1)
|
|
||||||
|
|
||||||
#define RX_ENABLED(im) (((im) & IE_RX) != 0)
|
|
||||||
#define TX_ENABLED(im) (((im) & IE_TX) != 0)
|
|
||||||
|
|
||||||
#define ENABLE_RX(im) do { (im) |= IE_RX; } while (0)
|
|
||||||
#define ENABLE_TX(im) do { (im) |= IE_TX; } while (0)
|
|
||||||
|
|
||||||
#define DISABLE_RX(im) do { (im) &= ~IE_RX; } while (0)
|
|
||||||
#define DISABLE_TX(im) do { (im) &= ~IE_TX; } while (0)
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -550,18 +536,38 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value
|
|||||||
putreg8(value, priv->uartbase + offset);
|
putreg8(value, priv->uartbase + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_setuartint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void up_setuartint(struct up_dev_s *priv)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
uint8_t regval;
|
||||||
|
|
||||||
|
/* Re-enable/re-disable interrupts corresponding to the state of bits in ie */
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
regval = up_serialin(priv, KINETIS_UART_C2_OFFSET);
|
||||||
|
regval &= ~UART_C2_ALLINTS;
|
||||||
|
regval |= priv->ie;
|
||||||
|
up_serialout(priv, KINETIS_UART_C2_OFFSET, regval);
|
||||||
|
irqrestore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_restoreuartint
|
* Name: up_restoreuartint
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void up_restoreuartint(struct up_dev_s *priv, uint8_t im)
|
static void up_restoreuartint(struct up_dev_s *priv, uint8_t ie)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
/* Re-enable/re-disable interrupts corresponding to the state of bits in im */
|
/* Re-enable/re-disable interrupts corresponding to the state of bits in ie */
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
#warning "Missing logic"
|
priv->ie = ie & UART_C2_ALLINTS;
|
||||||
|
up_setuartint(priv);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,15 +575,16 @@ static void up_restoreuartint(struct up_dev_s *priv, uint8_t im)
|
|||||||
* Name: up_disableuartint
|
* Name: up_disableuartint
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void up_disableuartint(struct up_dev_s *priv, uint8_t *im)
|
static void up_disableuartint(struct up_dev_s *priv, uint8_t *ie)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
if (im)
|
if (ie)
|
||||||
{
|
{
|
||||||
*im = priv->im;
|
*ie = priv->ie;
|
||||||
}
|
}
|
||||||
|
|
||||||
up_restoreint(priv, 0);
|
up_restoreint(priv, 0);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
@@ -602,6 +609,10 @@ static int up_setup(struct uart_dev_s *dev)
|
|||||||
priv->bits);
|
priv->bits);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Make sure that all interrupts are disabled */
|
||||||
|
|
||||||
|
up_restoreuartint(priv, 0);
|
||||||
|
|
||||||
/* Set up the interrupt priority */
|
/* Set up the interrupt priority */
|
||||||
|
|
||||||
up_prioritize_irq(priv->irqs, priv->irqprio);
|
up_prioritize_irq(priv->irqs, priv->irqprio);
|
||||||
@@ -626,7 +637,7 @@ static void up_shutdown(struct uart_dev_s *dev)
|
|||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
|
||||||
up_disableuartint(priv, NULL);
|
up_restoreint(priv, 0);
|
||||||
|
|
||||||
/* Reset hardware and disable Rx and Tx */
|
/* Reset hardware and disable Rx and Tx */
|
||||||
|
|
||||||
@@ -653,7 +664,9 @@ static int up_attach(struct uart_dev_s *dev)
|
|||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Attach the IRQ(s) */
|
/* Attach and enable the IRQ(s). The interrupts are (probably) still
|
||||||
|
* disabled in the C2 register.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = irq_attach(priv->irqs, up_interrupts);
|
ret = irq_attach(priv->irqs, up_interrupts);
|
||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_DEBUG
|
||||||
@@ -663,6 +676,14 @@ static int up_attach(struct uart_dev_s *dev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_DEBUG
|
||||||
|
up_enable_irq(priv->irqe);
|
||||||
|
#endif
|
||||||
|
up_enable_irq(priv->irqs);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,7 +703,11 @@ static void up_detach(struct uart_dev_s *dev)
|
|||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
|
||||||
up_disableuartint(priv, NULL);
|
up_restoreint(priv, 0);
|
||||||
|
#ifdef CONFIG_DEBUG
|
||||||
|
up_disable_irq(priv->irqe);
|
||||||
|
#endif
|
||||||
|
up_disable_irq(priv->irqs);
|
||||||
|
|
||||||
/* Detach from the interrupt(s) */
|
/* Detach from the interrupt(s) */
|
||||||
|
|
||||||
@@ -783,6 +808,8 @@ static int up_interrupts(int irq, void *context)
|
|||||||
struct uart_dev_s *dev = NULL;
|
struct uart_dev_s *dev = NULL;
|
||||||
struct up_dev_s *priv;
|
struct up_dev_s *priv;
|
||||||
int passes;
|
int passes;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int count;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
|
||||||
#ifdef CONFIG_KINETIS_UART0
|
#ifdef CONFIG_KINETIS_UART0
|
||||||
@@ -852,7 +879,8 @@ static int up_interrupts(int irq, void *context)
|
|||||||
|
|
||||||
/* Handle incoming, receive bytes */
|
/* Handle incoming, receive bytes */
|
||||||
|
|
||||||
#warning "Missing logic"
|
count = up_serialin(priv, KINETIS_UART_RCFIFO_OFFSET);
|
||||||
|
if (count > 0)
|
||||||
{
|
{
|
||||||
/* Process incoming bytes */
|
/* Process incoming bytes */
|
||||||
|
|
||||||
@@ -861,7 +889,9 @@ static int up_interrupts(int irq, void *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle outgoing, transmit bytes */
|
/* Handle outgoing, transmit bytes */
|
||||||
#warning "Missing logic"
|
|
||||||
|
count = up_serialin(priv, KINETIS_UART_TCFIFO_OFFSET);
|
||||||
|
#warning "Missing logic"
|
||||||
{
|
{
|
||||||
/* Process outgoing bytes */
|
/* Process outgoing bytes */
|
||||||
|
|
||||||
@@ -951,10 +981,10 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
|
|||||||
{
|
{
|
||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint8_t im;
|
uint8_t ie;
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
im = priv->im;
|
ie = priv->ie;
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
/* Receive an interrupt when their is anything in the Rx data register (or an Rx
|
/* Receive an interrupt when their is anything in the Rx data register (or an Rx
|
||||||
@@ -962,23 +992,22 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||||
#ifdef CONFIG_DEBUG
|
priv->ie |= UART_C2_RIE;
|
||||||
up_enable_irq(priv->irqe);
|
up_setuartint(priv);
|
||||||
#endif
|
|
||||||
up_enable_irq(priv->irqs);
|
|
||||||
ENABLE_RX(im);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#warning "Revisit: How are errors enabled? What is the IDLE receive interrupt. I think I need it"
|
||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_DEBUG
|
||||||
up_disable_irq(priv->irqe);
|
priv->ie |= UART_C2_RIE;
|
||||||
|
#else
|
||||||
|
priv->ie |= UART_C2_RIE;
|
||||||
#endif
|
#endif
|
||||||
up_disable_irq(priv->irqs);
|
up_setuartint(priv);
|
||||||
DISABLE_RX(im);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->im = im;
|
priv->ie = ie;
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,10 +1022,12 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
|
|||||||
static bool up_rxavailable(struct uart_dev_s *dev)
|
static bool up_rxavailable(struct uart_dev_s *dev)
|
||||||
{
|
{
|
||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
/* Return true if the receive data register is full */
|
/* Return true if there are any bytes in the RX FIFO */
|
||||||
|
|
||||||
return (up_serialin(priv, KINETIS_UART_S1_OFFSET) & UART_S1_RDRF) != 0;
|
count = up_serialin(priv, KINETIS_UART_RCFIFO_OFFSET);
|
||||||
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1025,16 +1056,15 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|||||||
{
|
{
|
||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint8_t im;
|
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
im = priv->im;
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
/* Enable the TX interrupt */
|
/* Enable the TX interrupt */
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||||
ENABLE_TX(im);
|
priv->ie |= UART_C2_TIE;
|
||||||
|
up_setuartint(priv);
|
||||||
|
|
||||||
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
||||||
* interrupts disabled (note this may recurse).
|
* interrupts disabled (note this may recurse).
|
||||||
@@ -1047,10 +1077,10 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|||||||
{
|
{
|
||||||
/* Disable the TX interrupt */
|
/* Disable the TX interrupt */
|
||||||
|
|
||||||
DISABLE_TX(im);
|
priv->ie &= ~UART_C2_TIE;
|
||||||
|
up_setuartint(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->im = im;
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,21 +1143,21 @@ void up_earlyserialinit(void)
|
|||||||
* pic32mx_consoleinit()
|
* pic32mx_consoleinit()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
up_disableuartint(TTYS0_DEV.priv, NULL);
|
up_restoreint(TTYS0_DEV.priv, 0);
|
||||||
#ifdef TTYS1_DEV
|
#ifdef TTYS1_DEV
|
||||||
up_disableuartint(TTYS1_DEV.priv, NULL);
|
up_restoreint(TTYS1_DEV.priv, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS2_DEV
|
#ifdef TTYS2_DEV
|
||||||
up_disableuartint(TTYS2_DEV.priv, NULL);
|
up_restoreint(TTYS2_DEV.priv, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS3_DEV
|
#ifdef TTYS3_DEV
|
||||||
up_disableuartint(TTYS3_DEV.priv, NULL);
|
up_restoreint(TTYS3_DEV.priv, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS4_DEV
|
#ifdef TTYS4_DEV
|
||||||
up_disableuartint(TTYS4_DEV.priv, NULL);
|
up_restoreint(TTYS4_DEV.priv, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS5_DEV
|
#ifdef TTYS5_DEV
|
||||||
up_disableuartint(TTYS5_DEV.priv, NULL);
|
up_restoreint(TTYS5_DEV.priv, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration whichever one is the console */
|
/* Configuration whichever one is the console */
|
||||||
|
|||||||
@@ -320,6 +320,7 @@
|
|||||||
#define UART_C2_RIE (1 << 5) /* Bit 5: Receiver Full Interrupt or DMA Transfer Enable */
|
#define UART_C2_RIE (1 << 5) /* Bit 5: Receiver Full Interrupt or DMA Transfer Enable */
|
||||||
#define UART_C2_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */
|
#define UART_C2_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */
|
||||||
#define UART_C2_TIE (1 << 7) /* Bit 7: Transmitter Interrupt or DMA Transfer Enable */
|
#define UART_C2_TIE (1 << 7) /* Bit 7: Transmitter Interrupt or DMA Transfer Enable */
|
||||||
|
#define UART_C2_ALLINTS (0xf0)
|
||||||
|
|
||||||
/* UART Status Register 1 */
|
/* UART Status Register 1 */
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ struct up_dev_s
|
|||||||
uint8_t irqrx; /* RX IRQ associated with this UART (for enable) */
|
uint8_t irqrx; /* RX IRQ associated with this UART (for enable) */
|
||||||
uint8_t irqtx; /* TX IRQ associated with this UART (for enable) */
|
uint8_t irqtx; /* TX IRQ associated with this UART (for enable) */
|
||||||
uint8_t irqprio; /* Interrupt priority */
|
uint8_t irqprio; /* Interrupt priority */
|
||||||
uint8_t ie; /* Interrupts enabled */
|
|
||||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||||
uint8_t bits; /* Number of bits (5, 6, 7 or 8) */
|
uint8_t bits; /* Number of bits (5, 6, 7 or 8) */
|
||||||
bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
|
bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
|
||||||
|
|||||||
Reference in New Issue
Block a user