Add PIC32 UART support

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3634 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-05-20 22:15:16 +00:00
parent f50f5b21ef
commit 7762d295e6
10 changed files with 757 additions and 140 deletions

View File

@ -42,6 +42,7 @@
#ifndef __ASSEMBLY__
# include <stdint.h>
# include <stdbool.h>
#endif
/****************************************************************************
@ -190,7 +191,7 @@ extern void up_sigdeliver(void);
/* IRQs */
extern void up_irqinitialize(void);
extern void up_maskack_irq(int irq);
extern bool up_pending_irq(int irq);
extern void up_clrpend_irq(int irq);
/* DMA */

View File

@ -91,9 +91,11 @@ uint32_t *up_doirq(int irq, uint32_t *regs)
savestate = (uint32_t*)current_regs;
current_regs = regs;
/* Mask and acknowledge the interrupt */
/* Disable further occurences of this interrupt (until the interrupt sources
* have been clear by the driver.
*/
up_maskack_irq(irq);
up_disable_irq(irq);
/* Deliver the IRQ */

View File

@ -46,11 +46,435 @@
#include "chip.h"
#include "pic32mx-memorymap.h"
#include "pic32mx-uart.h"
#include "pic32mx-int.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Configuration *********************************************************************/
/* Interrupt Priorities *************************************************************/
#ifndef CONFIG_PIC32MX_WDTPRIO
# define CONFIG_PIC32MX_WDTPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_WDTPRIO < 4
# error "CONFIG_PIC32MX_WDTPRIO is too small"
#endif
#if CONFIG_PIC32MX_WDTPRIO > 31
# error "CONFIG_PIC32MX_WDTPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_RTCCPRIO
# define CONFIG_PIC32MX_RTCCPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_RTCCPRIO < 4
# error "CONFIG_PIC32MX_RTCCPRIO is too small"
#endif
#if CONFIG_PIC32MX_RTCCPRIO > 31
# error "CONFIG_PIC32MX_RTCCPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_T1PRIO
# define CONFIG_PIC32MX_T1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T1PRIO < 4
# error "CONFIG_PIC32MX_T1PRIO is too small"
#endif
#if CONFIG_PIC32MX_T1PRIO > 31
# error "CONFIG_PIC32MX_T1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_T2PRIO
# define CONFIG_PIC32MX_T2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T2PRIO < 4
# error "CONFIG_PIC32MX_T2PRIO is too small"
#endif
#if CONFIG_PIC32MX_T2PRIO > 31
# error "CONFIG_PIC32MX_T2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_T3PRIO
# define CONFIG_PIC32MX_T3PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T3PRIO < 4
# error "CONFIG_PIC32MX_T3PRIO is too small"
#endif
#if CONFIG_PIC32MX_T3PRIO > 31
# error "CONFIG_PIC32MX_T3PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_T4PRIO
# define CONFIG_PIC32MX_T4PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T4PRIO < 4
# error "CONFIG_PIC32MX_T4PRIO is too small"
#endif
#if CONFIG_PIC32MX_T4PRIO > 31
# error "CONFIG_PIC32MX_T4PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_T5PRIO
# define CONFIG_PIC32MX_T5PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T5PRIO < 4
# error "CONFIG_PIC32MX_T5PRIO is too small"
#endif
#if CONFIG_PIC32MX_T5PRIO > 31
# error "CONFIG_PIC32MX_T5PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IC1PRIO
# define CONFIG_PIC32MX_IC1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IC1PRIO < 4
# error "CONFIG_PIC32MX_IC1PRIO is too small"
#endif
#if CONFIG_PIC32MX_IC1PRIO > 31
# error "CONFIG_PIC32MX_IC1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IC2PRIO
# define CONFIG_PIC32MX_IC2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IC2PRIO < 4
# error "CONFIG_PIC32MX_IC2PRIO is too small"
#endif
#if CONFIG_PIC32MX_IC2PRIO > 31
# error "CONFIG_PIC32MX_IC2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IC3PRIO
# define CONFIG_PIC32MX_IC3PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IC3PRIO < 4
# error "CONFIG_PIC32MX_IC3PRIO is too small"
#endif
#if CONFIG_PIC32MX_IC3PRIO > 31
# error "CONFIG_PIC32MX_IC3PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IC4PRIO
# define CONFIG_PIC32MX_IC4PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IC4PRIO < 4
# error "CONFIG_PIC32MX_IC4PRIO is too small"
#endif
#if CONFIG_PIC32MX_IC4PRIO > 31
# error "CONFIG_PIC32MX_IC4PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IC5PRIO
# define CONFIG_PIC32MX_IC5PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IC5PRIO < 4
# error "CONFIG_PIC32MX_IC5PRIO is too small"
#endif
#if CONFIG_PIC32MX_IC5PRIO > 31
# error "CONFIG_PIC32MX_IC5PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OC1PRIO
# define CONFIG_PIC32MX_OC1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OC1PRIO < 4
# error "CONFIG_PIC32MX_OC1PRIO is too small"
#endif
#if CONFIG_PIC32MX_OC1PRIO > 31
# error "CONFIG_PIC32MX_OC1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OC2PRIO
# define CONFIG_PIC32MX_OC2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OC2PRIO < 4
# error "CONFIG_PIC32MX_OC2PRIO is too small"
#endif
#if CONFIG_PIC32MX_OC2PRIO > 31
# error "CONFIG_PIC32MX_OC2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OC3PRIO
# define CONFIG_PIC32MX_OC3PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OC3PRIO < 4
# error "CONFIG_PIC32MX_OC3PRIO is too small"
#endif
#if CONFIG_PIC32MX_OC3PRIO > 31
# error "CONFIG_PIC32MX_OC3PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OC4PRIO
# define CONFIG_PIC32MX_OC4PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OC4PRIO < 4
# error "CONFIG_PIC32MX_OC4PRIO is too small"
#endif
#if CONFIG_PIC32MX_OC4PRIO > 31
# error "CONFIG_PIC32MX_OC4PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OC5PRIO
# define CONFIG_PIC32MX_OC5PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OC5PRIO < 4
# error "CONFIG_PIC32MX_OC5PRIO is too small"
#endif
#if CONFIG_PIC32MX_OC5PRIO > 31
# error "CONFIG_PIC32MX_OC5PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_I2C1PRIO
# define CONFIG_PIC32MX_I2C1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_I2C1PRIO < 4
# error "CONFIG_PIC32MX_I2C1PRIO is too small"
#endif
#if CONFIG_PIC32MX_I2C1PRIO > 31
# error "CONFIG_PIC32MX_I2C1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_I2C2PRIO
# define CONFIG_PIC32MX_I2C2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_I2C2PRIO < 4
# error "CONFIG_PIC32MX_I2C2PRIO is too small"
#endif
#if CONFIG_PIC32MX_I2C2PRIO > 31
# error "CONFIG_PIC32MX_I2C2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_SPI1PRIO
# define CONFIG_PIC32MX_SPI1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_SPI1PRIO < 4
# error "CONFIG_PIC32MX_SPI1PRIO is too small"
#endif
#if CONFIG_PIC32MX_SPI1PRIO > 31
# error "CONFIG_PIC32MX_SPI1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_SPI2PRIO
# define CONFIG_PIC32MX_SPI2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_SPI2PRIO < 4
# error "CONFIG_PIC32MX_SPI2PRIO is too small"
#endif
#if CONFIG_PIC32MX_SPI2PRIO > 31
# error "CONFIG_PIC32MX_SPI2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_UART1PRIO
# define CONFIG_PIC32MX_UART1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_UART1PRIO < 4
# error "CONFIG_PIC32MX_UART1PRIO is too small"
#endif
#if CONFIG_PIC32MX_UART1PRIO > 31
# error "CONFIG_PIC32MX_UART1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_UART2PRIO
# define CONFIG_PIC32MX_UART2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_UART2PRIO < 4
# error "CONFIG_PIC32MX_UART2PRIO is too small"
#endif
#if CONFIG_PIC32MX_UART2PRIO > 31
# error "CONFIG_PIC32MX_UART2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_PMPPRIO
# define CONFIG_PIC32MX_PMPPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_PMPPRIO < 4
# error "CONFIG_PIC32MX_PMPPRIO is too small"
#endif
#if CONFIG_PIC32MX_PMPPRIO > 31
# error "CONFIG_PIC32MX_PMPPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_ADCPRIO
# define CONFIG_PIC32MX_ADCPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_ADCPRIO < 4
# error "CONFIG_PIC32MX_ADCPRIO is too small"
#endif
#if CONFIG_PIC32MX_ADCPRIO > 31
# error "CONFIG_PIC32MX_ADCPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_CVRPRIO
# define CONFIG_PIC32MX_CVRPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_CVRPRIO < 4
# error "CONFIG_PIC32MX_CVRPRIO is too small"
#endif
#if CONFIG_PIC32MX_CVRPRIO > 31
# error "CONFIG_PIC32MX_CVRPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_CM1PRIO
# define CONFIG_PIC32MX_CM1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_CM1PRIO < 4
# error "CONFIG_PIC32MX_CM1PRIO is too small"
#endif
#if CONFIG_PIC32MX_CM1PRIO > 31
# error "CONFIG_PIC32MX_CM1PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_CM2PRIO
# define CONFIG_PIC32MX_CM2PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_CM2PRIO < 4
# error "CONFIG_PIC32MX_CM2PRIO is too small"
#endif
#if CONFIG_PIC32MX_CM2PRIO > 31
# error "CONFIG_PIC32MX_CM2PRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_OSCPRIO
# define CONFIG_PIC32MX_OSCPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_OSCPRIO < 4
# error "CONFIG_PIC32MX_OSCPRIO is too small"
#endif
#if CONFIG_PIC32MX_OSCPRIO > 31
# error "CONFIG_PIC32MX_OSCPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_DDPPRIO
# define CONFIG_PIC32MX_DDPPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_DDPPRIO < 4
# error "CONFIG_PIC32MX_DDPPRIO is too small"
#endif
#if CONFIG_PIC32MX_DDPPRIO > 31
# error "CONFIG_PIC32MX_DDPPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_FLASHPRIO
# define CONFIG_PIC32MX_FLASHPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_FLASHPRIO < 4
# error "CONFIG_PIC32MX_FLASHPRIO is too small"
#endif
#if CONFIG_PIC32MX_FLASHPRIO > 31
# error "CONFIG_PIC32MX_FLASHPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_BMXPRIO
# define CONFIG_PIC32MX_BMXPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_BMXPRIO < 4
# error "CONFIG_PIC32MX_BMXPRIO is too small"
#endif
#if CONFIG_PIC32MX_BMXPRIO > 31
# error "CONFIG_PIC32MX_BMXPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_DMAPRIO
# define CONFIG_PIC32MX_DMAPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_DMAPRIO < 4
# error "CONFIG_PIC32MX_DMAPRIO is too small"
#endif
#if CONFIG_PIC32MX_DMAPRIO > 31
# error "CONFIG_PIC32MX_DMAPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_CHEPRIO
# define CONFIG_PIC32MX_CHEPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_CHEPRIO < 4
# error "CONFIG_PIC32MX_CHEPRIO is too small"
#endif
#if CONFIG_PIC32MX_CHEPRIO > 31
# error "CONFIG_PIC32MX_CHEPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_USBPRIO
# define CONFIG_PIC32MX_USBPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_USBPRIO < 4
# error "CONFIG_PIC32MX_USBPRIO is too small"
#endif
#if CONFIG_PIC32MX_USBPRIO > 31
# error "CONFIG_PIC32MX_USBPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTAPRIO
# define CONFIG_PIC32MX_IOPORTAPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTAPRIO < 4
# error "CONFIG_PIC32MX_IOPORTAPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTAPRIO > 31
# error "CONFIG_PIC32MX_IOPORTAPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTBPRIO
# define CONFIG_PIC32MX_IOPORTBPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTBPRIO < 4
# error "CONFIG_PIC32MX_IOPORTBPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTBPRIO > 31
# error "CONFIG_PIC32MX_IOPORTBPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTCPRIO
# define CONFIG_PIC32MX_IOPORTCPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTCPRIO < 4
# error "CONFIG_PIC32MX_IOPORTCPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTCPRIO > 31
# error "CONFIG_PIC32MX_IOPORTCPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTDPRIO
# define CONFIG_PIC32MX_IOPORTDPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTDPRIO < 4
# error "CONFIG_PIC32MX_IOPORTDPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTDPRIO > 31
# error "CONFIG_PIC32MX_IOPORTDPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTEPRIO
# define CONFIG_PIC32MX_IOPORTEPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTEPRIO < 4
# error "CONFIG_PIC32MX_IOPORTEPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTEPRIO > 31
# error "CONFIG_PIC32MX_IOPORTEPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTFPRIO
# define CONFIG_PIC32MX_IOPORTFPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTFPRIO < 4
# error "CONFIG_PIC32MX_IOPORTFPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTFPRIO > 31
# error "CONFIG_PIC32MX_IOPORTFPRIO is too large"
#endif
#ifndef CONFIG_PIC32MX_IOPORTGPRIO
# define CONFIG_PIC32MX_IOPORTGPRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_IOPORTGPRIO < 4
# error "CONFIG_PIC32MX_IOPORTGPRIO is too small"
#endif
#if CONFIG_PIC32MX_IOPORTGPRIO > 31
# error "CONFIG_PIC32MX_IOPORTGPRIO is too large"
#endif
/* UARTs *****************************************************************************/
/* Don't enable UARTs not supported by the chip. */
#if CHIP_NEUARTS < 1

View File

@ -133,9 +133,11 @@ uint32_t *pic32mx_decodeirq(uint32_t *regs)
irq = ((regval) & INT_INTSTAT_VEC_MASK) >> INT_INTSTAT_VEC_SHIFT;
/* Mask and acknowledge the interrupt */
/* Disable further interrupts from this source until the driver has
* cleared the pending interrupt sources.
*/
up_maskack_irq(irq);
up_disable_irq(irq);
/* Deliver the IRQ */

View File

@ -173,7 +173,7 @@ EXTERN void pic32mx_uartreset(uintptr_t uart_base);
******************************************************************************/
#ifdef HAVE_UART_DEVICE
EXTERN void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baud,
EXTERN void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baudrate,
unsigned int parity, unsigned int nbits,
bool stop2);
#endif

View File

@ -125,9 +125,6 @@ void up_irqinitialize(void)
current_regs = NULL;
/* Attach processor exceptions */
#warning "Missing logic"
/* Initialize logic to support a second level of interrupt decoding for
* IOPORT pins.
*/
@ -241,6 +238,64 @@ void up_enable_irq(int irq)
}
}
/****************************************************************************
* Name: up_pending_irq
*
* Description:
* Return true if the interrupt is pending and unmasked.
*
****************************************************************************/
bool up_pending_irq(int irq)
{
uint32_t ifsaddr;
uint32_t iecaddr;
uint32_t regval;
int bitno;
/* Disable the interrupt by clearing the associated bit in the IEC and then
* acknowledge the interrupt by clearing the associated bit in the IFS
* register. It is necessary to do this BEFORE lowering the interrupt
* priority level otherwise recursive interrupts would occur.
*/
DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST)
if (irq >= PIC32MX_IRQSRC0_FIRST)
{
if (irq <= PIC32MX_IRQSRC0_LAST)
{
/* Use IFS0 */
ifsaddr = PIC32MX_INT_IFS0;
iecaddr = PIC32MX_INT_IEC0;
bitno -= PIC32MX_IRQSRC0_FIRST;
}
else if (irq <= PIC32MX_IRQSRC1_LAST)
{
/* Use IFS1 */
ifsaddr = PIC32MX_INT_IFS1;
iecaddr = PIC32MX_INT_IEC1;
bitno -= PIC32MX_IRQSRC1_FIRST;
}
else
{
/* Value out of range.. just ignore */
return false;
}
/* Get the set of unmasked, pending interrupts. Return true if the
* interrupt is pending and unmask.
*/
regval = getreg32(ifsaddr) & getreg32(iecaddr);
return (regval & (1 << bitno)) != 0;
}
return false;
}
/****************************************************************************
* Name: up_clrpend_irq
*
@ -290,62 +345,6 @@ void up_clrpend_irq(int irq)
}
}
/****************************************************************************
* Name: up_maskack_irq
*
* Description:
* Mask the IRQ and acknowledge it. This could be done by calling
* up_disable_irq followed by up_clrpend_irq, but since these function is
* called from interrupt handling logic it is probably worth the improved
* performance by doing doing both here.
*
****************************************************************************/
void up_maskack_irq(int irq)
{
uint32_t iecaddr;
uint32_t ifsaddr;
int bitno;
/* Disable the interrupt by clearing the associated bit in the IEC and then
* acknowledge the interrupt by clearing the associated bit in the IFS
* register. It is necessary to do this BEFORE lowering the interrupt
* priority level otherwise recursive interrupts would occur.
*/
DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST)
if (irq >= PIC32MX_IRQSRC0_FIRST)
{
if (irq <= PIC32MX_IRQSRC0_LAST)
{
/* Use IEC0 and IFS0*/
iecaddr = PIC32MX_INT_IEC0CLR;
ifsaddr = PIC32MX_INT_IFS0CLR;
bitno -= PIC32MX_IRQSRC0_FIRST;
}
else if (irq <= PIC32MX_IRQSRC1_LAST)
{
/* Use IEC1 and IFS1 */
iecaddr = PIC32MX_INT_IEC1CLR;
ifsaddr = PIC32MX_INT_IFS1CLR;
bitno -= PIC32MX_IRQSRC1_FIRST;
}
else
{
/* Value out of range.. just ignore */
return;
}
/* Disable then acknowledge interrupt */
putreg32((1 << bitno), iecaddr);
putreg32((1 << bitno), ifsaddr);
}
}
/****************************************************************************
* Name: up_prioritize_irq
*

View File

@ -58,17 +58,17 @@
/* Select UART parameters for the selected console */
#if defined(CONFIG_UART1_SERIAL_CONSOLE)
# define AVR32_CONSOLE_BASE PIC32MX_UART1_K1BASE
# define AVR32_CONSOLE_BAUD CONFIG_UART1_BAUD
# define AVR32_CONSOLE_BITS CONFIG_UART1_BITS
# define AVR32_CONSOLE_PARITY CONFIG_UART1_PARITY
# define AVR32_CONSOLE_2STOP CONFIG_UART1_2STOP
#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
# define AVR32_CONSOLE_BASE PIC32MX_UART2_K1BASE
# define AVR32_CONSOLE_BAUD CONFIG_UART2_BAUD
# define AVR32_CONSOLE_BITS CONFIG_UART2_BITS
# define AVR32_CONSOLE_PARITY CONFIG_UART2_PARITY
# define AVR32_CONSOLE_2STOP CONFIG_UART2_2STOP
# define PIC32MX_CONSOLE_BASE PIC32MX_UART1_K1BASE
# define PIC32MX_CONSOLE_BAUD CONFIG_UART1_BAUD
# define PIC32MX_CONSOLE_BITS CONFIG_UART1_BITS
# define PIC32MX_CONSOLE_PARITY CONFIG_UART1_PARITY
# define PIC32MX_CONSOLE_2STOP CONFIG_UART1_2STOP
#elif defined(CONFIG_UART_SERIAL_CONSOLE)
# define PIC32MX_CONSOLE_BASE PIC32MX_UART_K1BASE
# define PIC32MX_CONSOLE_BAUD CONFIG_UART_BAUD
# define PIC32MX_CONSOLE_BITS CONFIG_UART_BITS
# define PIC32MX_CONSOLE_PARITY CONFIG_UART_PARITY
# define PIC32MX_CONSOLE_2STOP CONFIG_UART_2STOP
#else
# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting"
#endif
@ -94,7 +94,7 @@
******************************************************************************/
/******************************************************************************
* Name: pic32mx_uartputreg
* Name: pic32mx_putreg
*
* Description:
* Write a value to a UART register
@ -102,7 +102,7 @@
******************************************************************************/
#ifdef HAVE_UART_DEVICE
static inline void pic32mx_uartputreg(uintptr_t uart_base, unsigned int offset,
static inline void pic32mx_putreg(uintptr_t uart_base, unsigned int offset,
uint32_t value)
{
putreg32(value, uart_base + offset);
@ -110,7 +110,7 @@ static inline void pic32mx_uartputreg(uintptr_t uart_base, unsigned int offset,
#endif
/******************************************************************************
* Name: pic32mx_uartgetreg
* Name: pic32mx_getreg
*
* Description:
* Get a value from a UART register
@ -118,7 +118,7 @@ static inline void pic32mx_uartputreg(uintptr_t uart_base, unsigned int offset,
******************************************************************************/
#ifdef HAVE_UART_DEVICE
static inline uint32_t pic32mx_uartgetreg(uintptr_t uart_base,
static inline uint32_t pic32mx_getreg(uintptr_t uart_base,
unsigned int offset)
{
return getreg32(uart_base + offset);
@ -131,12 +131,49 @@ static inline uint32_t pic32mx_uartgetreg(uintptr_t uart_base,
* Description:
* Configure the UART baud rate.
*
* With BRGH=0
* BAUD = PBCLK / 16 / (BRG+1)
* BRG = PBCLK / 16 / BAUD - 1
* With BRGH=1
* BAUD = PBCLK / 4 / (BRG+1)
* BRG = PBCLK / 4 / BAUD - 1
*
*
******************************************************************************/
#ifdef HAVE_UART_DEVICE
static void pic32mx_uartsetbaud(uintptr_t uart_base, uint32_t baudrate)
{
#warning "Missing logic"
uint32_t tmp;
uint32_t brg;
unsigned int mode;
/* We want the largest value of BRG divisor possible (for the best accuracy).
* Subject to BRG <= 65536.
*/
tmp = BOARD_PERIPHERAL_CLOCK / baudrate;
/* Try BRGH=1 first. This will select the 4x divisor and will produce the
* larger BRG divisor, given all other things equal.
*/
brg = (tmp + 2) >> 2;
mode = PIC32MX_UART_MODESET_OFFSET;
if (brg > 65536)
{
/* Nope, too big.. try BRGH=1 */
brg = (tmp + 8) >> 4;
mode = PIC32MX_UART_MODECLR_OFFSET;
}
DEBUGASSERT(brg <= 65536);
/* Set the BRG divisor */
pic32mx_putreg(uart_base, mode, UART_MODE_BRGH);
pic32mx_putreg(uart_base, PIC32MX_UART_BRG_OFFSET, brg);
}
#endif
@ -148,14 +185,18 @@ static void pic32mx_uartsetbaud(uintptr_t uart_base, uint32_t baudrate)
* Name: pic32mx_uartreset
*
* Description:
* Reset a UART.
* Reset hardware and disable Rx and Tx.
*
******************************************************************************/
#ifdef HAVE_UART_DEVICE
void pic32mx_uartreset(uintptr_t uart_base)
{
#warning "Missing logic"
/* Doesn't reset the hardware... just shuts it down */
pic32mx_putreg(uart_base, PIC32MX_UART_STACLR_OFFSET,
UART_STA_UTXEN | UART_STA_URXEN);
pic32mx_putreg(uart_base, PIC32MX_UART_MODECLR_OFFSET, UART_MODE_ON);
}
#endif
@ -168,9 +209,65 @@ void pic32mx_uartreset(uintptr_t uart_base)
******************************************************************************/
#ifdef HAVE_UART_DEVICE
void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baud,
void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baudrate,
unsigned int parity, unsigned int nbits, bool stop2)
{
/* Clear mode and sta bits */
pic32mx_putreg(uart_base, PIC32MX_UART_MODECLR_OFFSET,
UART_MODE_STSEL | UART_MODE_PDSEL_MASK | UART_MODE_BRGH |
UART_MODE_RXINV | UART_MODE_WAKE | UART_MODE_LPBACK |
UART_MODE_UEN_MASK | UART_MODE_RTSMD | UART_MODE_IREN |
UART_MODE_SIDL | UART_MODE_ON);
pic32mx_putreg(uart_base, PIC32MX_UART_STACLR_OFFSET,
UART_STA_UTXINV | UART_STA_UTXISEL_MASK | UART_STA_URXISEL_RXBF);
/* Configure the FIFO interrupts */
pic32mx_putreg(uart_base, PIC32MX_UART_STASET_OFFSET,
UART_STA_UTXISEL_TXBNF | UART_STA_URXISEL_RECVD);
/* Configure word size and parity */
if (nbits == 9)
{
DEBUGASSERT(parity == 0);
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_MODE_PDSEL_9NONE);
}
else
{
DEBUGASSERT(nbits == 8);
if (parity == 1)
{
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_MODE_PDSEL_8ODD);
}
else if (parity == 2)
{
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_MODE_PDSEL_8EVEN);
}
}
/* Configure 1 or 2 stop bits */
if (stop2)
{
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_MODE_STSEL);
}
/* Set the BRG divisor */
pic32mx_uartsetbaud(uart_base, baudrate);
/* Enable the UART */
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_STA_UTXEN | UART_STA_URXEN);
pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET,
UART_MODE_ON);
}
#endif
@ -186,7 +283,11 @@ void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baud,
void pic32mx_consoleinit(void)
{
#warning "Missing logic"
#ifdef HAVE_UART_DEVICE
pic32mx_uartconfigure(PIC32MX_CONSOLE_BASE, PIC32MX_CONSOLE_BAUD,
PIC32MX_CONSOLE_PARITY, PIC32MX_CONSOLE_BITS,
PIC32MX_CONSOLE_2STOP);
#endif
}
/******************************************************************************
@ -199,6 +300,12 @@ void pic32mx_consoleinit(void)
void up_lowputc(char ch)
{
#warning "Missing logic"
/* Wait for the transmit buffer not full */
while ((pic32mx_getreg(PIC32MX_CONSOLE_BASE, PIC32MX_UART_STA_OFFSET) & UART_STA_UTXBF) != 0);
/* Then write the character to the TX data register */
pic32mx_putreg(PIC32MX_CONSOLE_BASE, PIC32MX_UART_TXREG_OFFSET, (uint32_t)ch);
}

View File

@ -66,9 +66,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Some sanity checks *******************************************************/
/* Is there at least one UART enabled and configured as a RS-232 device? */
#ifndef HAVE_UART_DEVICE
@ -123,19 +121,15 @@
/* These values describe the set of enabled interrupts */
#define IE_ERROR (1 << 0)
#define IE_RX (1 << 1)
#define IE_TX (1 << 2)
#define IE_RX (1 << 0)
#define IE_TX (1 << 1)
#define ERROR_ENABLED(im) (((im) & IE_ERROR) != 0)
#define RX_ENABLED(im) (((im) & IE_RX) != 0)
#define TX_ENABLED(im) (((im) & IE_TX) != 0)
#define ENABLE_ERROR(im) do { (im) |= IE_ERROR; } while (0)
#define ENABLE_RX(im) do { (im) |= IE_RX; } while (0)
#define ENABLE_TX(im) do { (im) |= IE_TX; } while (0)
#define DISABLE_ERROR(im) do { (im) &= ~IE_ERROR; } while (0)
#define DISABLE_RX(im) do { (im) &= ~IE_RX; } while (0)
#define DISABLE_TX(im) do { (im) &= ~IE_TX; } while (0)
@ -173,6 +167,7 @@ static bool up_rxavailable(struct uart_dev_s *dev);
static void up_send(struct uart_dev_s *dev, int ch);
static void up_txint(struct uart_dev_s *dev, bool enable);
static bool up_txready(struct uart_dev_s *dev);
static bool up_txempty(struct uart_dev_s *dev);
/****************************************************************************
* Private Variables
@ -191,7 +186,7 @@ struct uart_ops_s g_uart_ops =
.send = up_send,
.txint = up_txint,
.txready = up_txready,
.txempty = up_txready,
.txempty = up_txempty,
};
/* I/O buffers */
@ -299,18 +294,31 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t valu
static void up_restoreuartint(struct up_dev_s *priv, uint8_t im)
{
/* Re-enable interrupts as for each "1" bit in imr */
irqstate_t flags;
#warning "Missing logic"
/* Re-enable/re-disable interrupts corresponding to the state of bits in im */
flags = irqsave();
up_rxint(priv, RX_ENABLED(im));
up_txint(priv, TX_ENABLED(im));
irqrestore(flags);
}
/****************************************************************************
* Name: up_disableuartint
****************************************************************************/
static inline void up_disableuartint(struct up_dev_s *priv, uint8_t *imr)
static void up_disableuartint(struct up_dev_s *priv, uint8_t *im)
{
#warning "Missing logic"
irqstate_t flags;
flags = irqsave();
if (im)
{
*im = priv->im;
}
up_restoreint(priv, 0);
irqrestore(flags);
}
/****************************************************************************
@ -349,7 +357,11 @@ static void up_shutdown(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
/* Reset, disable interrupts, and disable Rx and Tx */
/* Disable interrupts */
up_disableuartint(priv, NULL);
/* Reset hardware and disable Rx and Tx */
uart_reset(priv->uartbase);
}
@ -391,7 +403,13 @@ static int up_attach(struct uart_dev_s *dev)
static void up_detach(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
up_serialout(priv, AVR32_UART_IDR_OFFSET, 0xffffffff);
/* Disable interrupts */
up_disableuartint(priv, NULL);
/* Dettach from the interrupt */
irq_detach(priv->irq);
}
@ -443,11 +461,34 @@ static int up_interrupt(int irq, void *context)
{
handled = false;
/* Handle incoming, receive bytes (with or without timeout) */
/* Handle error interrupts. This interrupt occurs when any of the
* following error conditions take place:
* - Parity error PERR (UxSTA bit 3) is detected
* - Framing Error FERR (UxSTA bit 2) is detected
* - Overflow condition for the receive buffer OERR (UxSTA bit 1) occurs
*/
#warning "Missing logic"
#ifdef CONFIG_DEBUG
if (up_pending_irq(priv->irqe))
{
/* Received data ready... process incoming bytes */
/* Clear the pending error interrupt */
up_clrpend_irq(priv->irqe);
lldbg("ERROR: interrrupt STA: %08x\n",
up_serialin(priv, PIC32MX_UART1_STA_OFFSET)
handled = true;
}
#endif
/* Handle incoming, receive bytes */
if (up_pending_irq(priv->irqrx))
{
/* Clear the pending RX interrupt */
up_clrpend_irq(priv->irqrx);
/* Process incoming bytes */
uart_recvchars(dev);
handled = true;
@ -455,15 +496,20 @@ static int up_interrupt(int irq, void *context)
/* Handle outgoing, transmit bytes */
#warning "Missing logic"
if (up_pending_irq(priv->irqtx))
{
/* Transmit data regiser empty ... process outgoing bytes */
/* Clear the pending RX interrupt */
up_clrpend_irq(priv->irqtx);
/* Process outgoing bytes */
uart_xmitchars(dev);
handled = true;
}
}
return OK;
return OK;
}
/****************************************************************************
@ -519,16 +565,16 @@ static int up_receive(struct uart_dev_s *dev, uint32_t *status)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
/* Get the Rx byte */
#warning "Missing logic"
/* Return status information */
if (status)
{
*status = 0; /* We are not yet tracking serial errors */
}
/* Then return the actual received byte */
return 0;
return (int)(up_serialin(priv, PIC32MX_UART_RXREG_OFFSET) & UART_RXREG_MASK;
}
/****************************************************************************
@ -542,7 +588,11 @@ static int up_receive(struct uart_dev_s *dev, uint32_t *status)
static void up_rxint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
irqstate_t flags;
uint8_t im;
flags = irqsave();
im = priv->im;
if (enable)
{
/* Receive an interrupt when their is anything in the Rx data register (or an Rx
@ -550,17 +600,23 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
*/
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
# ifdef CONFIG_UART_ERRINTS
#warning "Missing logic"
# else
#warning "Missing logic"
# endif
#ifdef CONFIG_DEBUG
up_enable_irq(priv->irqe);
#endif
up_enable_irq(priv->irqtx);
ENABLE_RX(im);
#endif
}
else
{
#warning "Missing logic"
#ifdef CONFIG_DEBUG
up_disable_irq(priv->irqe);
#endif
up_disable_irq(priv->irqtx);
DISABLE_RX(im);
}
priv->im = im;
irqrestore(flags);
}
/****************************************************************************
@ -575,6 +631,17 @@ static bool up_rxavailable(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
/* Return true is data is available in the receive data buffer */
#define UART_STA_URXDA (1 << 0) /* Bit 0: Receive buffer data available */
#define UART_STA_RIDLE (1 << 4) /* Bit 4: Receiver idle */
#define (1 << 8) /* Bit 8: */
#define (1 << 9) /* Bit 9: Transmit buffer full status */
/* Return TRUE if the Transmit shift register is empty */
return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_TRMT) != 0;
#warning "Missing logic"
return false;
}
@ -590,7 +657,7 @@ static bool up_rxavailable(struct uart_dev_s *dev)
static void up_send(struct uart_dev_s *dev, int ch)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
#warning "Missing logic"
up_serialout(priv, PIC32MX_UART_TXREG_OFFSET, (uint32_t)ch);
}
/****************************************************************************
@ -605,14 +672,17 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
irqstate_t flags;
uint8_t im;
flags = irqsave();
im = priv->im;
if (enable)
{
/* Enable the TX interrupt */
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
#warning "Missing logic"
up_enable_irq(priv->irqtx);
ENABLE_TX(im);
/* Fake a TX interrupt here by just calling uart_xmitchars() with
* interrupts disabled (note this may recurse).
@ -625,8 +695,11 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
{
/* Disable the TX interrupt */
#warning "Missing logic"
up_disable_irq(priv->irqtx);
DISABLE_TX(im);
}
priv->im = im;
irqrestore(flags);
}
@ -642,8 +715,26 @@ static bool up_txready(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
#warning "Missing logic"
return false;
/* Return TRUE if the Transmit buffer register is not full */
return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_UTXBF) == 0;
}
/****************************************************************************
* Name: up_txempty
*
* Description:
* Return true if the tranmsit data register is empty
*
****************************************************************************/
static bool up_txempty(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
/* Return TRUE if the Transmit shift register is empty */
return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_UTRMT) != 0;
}
/****************************************************************************

View File

@ -50,6 +50,7 @@
#include "up_internal.h"
#include "up_arch.h"
#include "pic32mx-config.h"
#include "pic32mx-timer.h"
#include "pic32mx-int.h"
#include "pic32mx-internal.h"
@ -57,20 +58,6 @@
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_PIC32MX_T1PRIO
# define CONFIG_PIC32MX_T1PRIO (INT_CP0_MID_PRIORITY << 2)
#endif
#if CONFIG_PIC32MX_T1PRIO < 4
# error "CONFIG_PIC32MX_T1PRIO is too small"
#endif
#if CONFIG_PIC32MX_T1PRIO > 31
# error "CONFIG_PIC32MX_T1PRIO is too large"
#endif
/* Timer Setup **************************************************************/
/* Select a timer prescale value. Our goal is to select the timer MATCH
* register value givent the board's periperhal clock frequency and the
@ -135,6 +122,10 @@
int up_timerisr(int irq, uint32_t *regs)
{
/* Clear the pending timer interrupt */
putreg32(INT_T1, PIC32MX_INT_IFS0CLR);
/* Process timer interrupt */
sched_process_timer();

View File

@ -144,7 +144,7 @@
# define UART_STA_URXISEL_RXB4 (1 << UART_STA_URXISEL_SHIFT) /* RX buffer 1/2 */
# define UART_STA_URXISEL_RXB6 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 */
#endif
#define UART_STA_TRMT (1 << 8) /* Bit 8: Transmit shift register is empty */
#define UART_STA_UTRMT (1 << 8) /* Bit 8: Transmit shift register is empty */
#define UART_STA_UTXBF (1 << 9) /* Bit 9: Transmit buffer full status */
#define UART_STA_UTXEN (1 << 10) /* Bit 10: Transmit enable */
#define UART_STA_UTXBRK (1 << 11) /* Bit 11: Transmit break */
@ -157,7 +157,7 @@
# define UART_STA_UTXISEL_TXBE (2 << UART_STA_UTXISEL_SHIFT) /* TX buffer empty */
#define UART_STA_ADDR_SHIFT (16) /* Bits:16-23: Automatic address mask */
#define UART_STA_ADDR_MASK (0xff << UART_STA_ADDR_SHIFT)
#define UART_STA_ADM_EN (1 << 24) /* Bit 14: Automatic address detect mode enable */
#define UART_STA_ADM_EN (1 << 24) /* Bit 24: Automatic address detect mode enable */
/* UARTx transmit register */