*
*
* \author Daniele Basile <asterix@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
*/
#include "hw/hw_ser.h" /* Required for bus macros overrides */
#endif
#define SER_UART0_BUS_TXINIT do { \
PIOA_PDR = BV(RXD0) | BV(TXD0); \
+ PIO_PERIPH_SEL(PIOA_BASE, BV(RXD0) | BV(TXD0), USART0_PERIPH); \
} while (0)
#endif
/* End USART0 macros */
-#if !CPU_CM3_AT91SAM3U
+#if USART_PORTS > 1
#ifndef SER_UART1_BUS_TXINIT
/**
*
* - Disable GPIO on USART1 tx/rx pins
*/
- #if CPU_ARM_AT91
- #if !CPU_ARM_SAM7S_LARGE && !CPU_ARM_SAM7X
- #warning Check USART1 pins!
- #endif
- #define SER_UART1_BUS_TXINIT do { \
- PIOA_PDR = BV(RXD1) | BV(TXD1); \
- } while (0)
- #elif CPU_CM3_AT91SAM3
- #define SER_UART1_BUS_TXINIT do { \
- PIOB_PDR = BV(RXD1) | BV(TXD1); \
- } while (0)
- #else
- #error Unknown CPU
+ #if CPU_ARM_AT91 && !CPU_ARM_SAM7S_LARGE && !CPU_ARM_SAM7X
+ #warning Check USART1 pins!
#endif
+ #define SER_UART1_BUS_TXINIT do { \
+ PIOA_PDR = BV(RXD1) | BV(TXD1); \
+ PIO_PERIPH_SEL(PIOA_BASE, BV(RXD1) | BV(TXD1), USART1_PERIPH); \
+ } while (0)
#endif
#ifndef SER_UART1_BUS_TXBEGIN
* Default TXINIT macro - invoked in spi_init()
* The default is no action.
*/
- #define SER_SPI0_BUS_TXINIT do { \
- /* Disable PIO on SPI pins */ \
- PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
- } while (0)
+ #if CPU_CM3_SAM3
+ #define SER_SPI0_BUS_TXINIT do { \
+ /* Disable PIO on SPI pins */ \
+ PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
+ /* SPI is peripheral A on SAM3X,A,N,S,U */ \
+ PIO_PERIPH_SEL(PIOA_BASE, BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO), PIO_PERIPH_A); \
+ } while (0)
+ #else
+ #define SER_SPI0_BUS_TXINIT do { \
+ /* Disable PIO on SPI pins */ \
+ PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); \
+ } while (0)
+ #endif
#endif
#ifndef SER_SPI0_BUS_TXCLOSE
AIC_EOICR = 0; \
} while (0)
-#elif CPU_CM3_AT91SAM3
+#elif CPU_CM3_SAM3
/** Inform hw that we have served the IRQ */
#define SER_INT_ACK do { /* nop */ } while (0)
/* TX and RX buffers */
static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
-#if !CPU_CM3_AT91SAM3U
+#if USART_PORTS > 1
static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
#endif
};
static ISR_PROTO(uart0_irq_dispatcher);
-#if !CPU_CM3_AT91SAM3U
+#if USART_PORTS > 1
static ISR_PROTO(uart1_irq_dispatcher);
#endif
static ISR_PROTO(spi0_irq_handler);
UNUSED_ARG(struct Serial *, ser))
{
US0_IDR = 0xFFFFFFFF;
- PMC_PCER = BV(US0_ID);
+ pmc_periphEnable(US0_ID);
/*
* - Reset USART0
SER_UART0_BUS_TXINIT;
- sysirq_setPriority(US0_ID, SERIRQ_PRIORITY);
- sysirq_setHandler(US0_ID, uart0_irq_dispatcher);
+ sysirq_setPriority(INT_US0, SERIRQ_PRIORITY);
+ sysirq_setHandler(INT_US0, uart0_irq_dispatcher);
SER_STROBE_INIT;
}
ASSERT(0);
}
}
+
+#if USART_PORTS > 1
+
/*
* Callbacks for USART1
*/
UNUSED_ARG(struct Serial *, ser))
{
US1_IDR = 0xFFFFFFFF;
- PMC_PCER = BV(US1_ID);
+ pmc_periphEnable(US1_ID);
/*
* - Reset USART1
SER_UART1_BUS_TXINIT;
- sysirq_setPriority(US1_ID, SERIRQ_PRIORITY);
- sysirq_setHandler(US1_ID, uart1_irq_dispatcher);
+ sysirq_setPriority(INT_US1, SERIRQ_PRIORITY);
+ sysirq_setHandler(INT_US1, uart1_irq_dispatcher);
SER_STROBE_INIT;
}
}
}
+#endif /* USART_PORTS > 1 */
+
/* SPI driver */
static void spi0_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
{
* Set SPI mode.
* At reset clock division factor is set to 0, that is
* *forbidden*. Set SPI clock to minimum to keep it valid.
+ * Set all possible chip select registers in case user manually
+ * change CPS field in SPI_MR.
*/
SPI0_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI0_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI0_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI0_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
/* Disable all irqs */
SPI0_IDR = 0xFFFFFFFF;
- sysirq_setPriority(SPI0_ID, SERIRQ_PRIORITY);
- sysirq_setHandler(SPI0_ID, spi0_irq_handler);
- PMC_PCER = BV(SPI0_ID);
-
- /* Enable interrupt on tx buffer empty */
- SPI0_IER = BV(SPI_TXEMPTY);
+ //sysirq_setPriority(INT_SPI0, SERIRQ_PRIORITY);
+ sysirq_setHandler(INT_SPI0, spi0_irq_handler);
+ pmc_periphEnable(SPI0_ID);
/* Enable SPI */
SPI0_CR = BV(SPI_SPIEN);
{
hw->sending = true;
SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
+ /* Enable interrupt on tx buffer empty */
+ SPI0_IER = BV(SPI_TXEMPTY);
}
IRQ_RESTORE(flags);
* Set SPI mode.
* At reset clock division factor is set to 0, that is
* *forbidden*. Set SPI clock to minimum to keep it valid.
+ * Set all possible chip select registers in case user manually
+ * change chip select.
*/
SPI1_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI1_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI1_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
+ SPI1_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT);
/* Disable all SPI irqs */
SPI1_IDR = 0xFFFFFFFF;
- sysirq_setPriority(SPI1_ID, SERIRQ_PRIORITY);
- sysirq_setHandler(SPI1_ID, spi1_irq_dispatcher);
- PMC_PCER = BV(SPI1_ID);
-
- /* Enable interrupt on tx buffer empty */
- SPI1_IER = BV(SPI_TXEMPTY);
+ sysirq_setPriority(INT_SPI1, SERIRQ_PRIORITY);
+ sysirq_setHandler(INT_SPI1, spi1_irq_dispatcher);
+ pmc_periphEnable(SPI1_ID);
/* Enable SPI */
SPI1_CR = BV(SPI_SPIEN);
{
hw->sending = true;
SPI1_TDR = fifo_pop(&ser_handles[SER_SPI1]->txfifo);
+ /* Enable interrupt on tx buffer empty */
+ SPI1_IER = BV(SPI_TXEMPTY);
}
IRQ_RESTORE(flags);
C99INIT(txSending, tx_sending),
};
+#if USART_PORTS > 1
+
static const struct SerialHardwareVT UART1_VT =
{
C99INIT(init, uart1_init),
C99INIT(txSending, tx_sending),
};
+#endif /* USART_PORTS > 1 */
+
static const struct SerialHardwareVT SPI0_VT =
{
C99INIT(init, spi0_init),
},
C99INIT(sending, false),
},
+#if USART_PORTS > 1
{
C99INIT(hw, /**/) {
C99INIT(table, &UART1_VT),
},
C99INIT(sending, false),
},
+#endif
{
C99INIT(hw, /**/) {
SER_INT_ACK;
}
+#if USART_PORTS > 1
+
/**
* Serial 1 TX interrupt handler
*/
SER_INT_ACK;
}
+#endif /* USART_PORTS > 1 */
+
/**
* SPI0 interrupt handler
*/
if (!fifo_isempty(&ser_handles[SER_SPI0]->txfifo))
SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo);
else
+ {
UARTDescs[SER_SPI0].sending = false;
+ /* Disable interrupt on tx buffer empty */
+ SPI0_IDR = BV(SPI_TXEMPTY);
+ }
SER_INT_ACK;
if (!fifo_isempty(&ser_handles[SER_SPI1]->txfifo))
SPI1_TDR = fifo_pop(&ser_handles[SER_SPI1]->txfifo);
else
+ {
UARTDescs[SER_SPI1].sending = false;
+ /* Disable interrupt on tx buffer empty */
+ SPI1_IDR = BV(SPI_TXEMPTY);
+ }
SER_INT_ACK;