From: batt Date: Fri, 4 Apr 2008 13:43:53 +0000 (+0000) Subject: Move also cpu/ to bertos/ :-). X-Git-Tag: 1.0.0~38 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;ds=sidebyside;h=345f93de1963f49bdb194d2b06c8c5d7ba0a3e5f;hp=791e167e053bdd9250d34a9a5ccae6ccde4d6679;p=bertos.git Move also cpu/ to bertos/ :-). git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1214 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/cpu/arm/drv/kdebug_arm.c b/bertos/cpu/arm/drv/kdebug_arm.c new file mode 100644 index 00000000..9e16ba22 --- /dev/null +++ b/bertos/cpu/arm/drv/kdebug_arm.c @@ -0,0 +1,47 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief Low-level kdebug module for ARM (inplementation). + */ + +#include + +#if CPU_ARM_AT91 + #include "kdebug_at91.c" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif diff --git a/bertos/cpu/arm/drv/kdebug_at91.c b/bertos/cpu/arm/drv/kdebug_at91.c new file mode 100644 index 00000000..b7e24cd3 --- /dev/null +++ b/bertos/cpu/arm/drv/kdebug_at91.c @@ -0,0 +1,93 @@ +/** + * \file + * + * + * \brief ARM debug support (implementation). + * + * \version $Id$ + * \author Francesco Sacchi + */ + +#include "kdebug_at91.h" +#include /* for BV(), DIV_ROUND */ +#include +#include /* for CLOCK_FREQ */ +#include /* Required for bus macros overrides */ + +#include + +#if CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU + #define KDBG_WAIT_READY() while (!(DBGU_SR & BV(US_TXRDY))) {} + #define KDBG_WAIT_TXDONE() while (!(DBGU_SR & BV(US_TXEMPTY))) {} + + #define KDBG_WRITE_CHAR(c) do { DBGU_THR = (c); } while(0) + + /* Debug unit is used only for debug purposes so does not generate interrupts. */ + #define KDBG_MASK_IRQ(old) do { (void)old; } while(0) + + /* Debug unit is used only for debug purposes so does not generate interrupts. */ + #define KDBG_RESTORE_IRQ(old) do { (void)old; } while(0) + + typedef uint32_t kdbg_irqsave_t; + +#else + #error CONFIG_KDEBUG_PORT should be KDEBUG_PORT_DBGU +#endif + + +INLINE void kdbg_hw_init(void) +{ + #if CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU + /* Disable all DBGU interrupts. */ + DBGU_IDR = 0xFFFFFFFF; + /* Reset DBGU */ + DBGU_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS); + /* Set baudrate */ + DBGU_BRGR = DIV_ROUND(CLOCK_FREQ, 16 * CONFIG_KDEBUG_BAUDRATE); + /* Set DBGU mode to 8 data bits, no parity and 1 stop bit. */ + DBGU_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1; + /* Enable DBGU transmitter. */ + DBGU_CR = BV(US_TXEN); + /* Disable PIO on DGBU tx pin. */ + PIOA_PDR = BV(DTXD); + PIOA_ASR = BV(DTXD); + + #if 0 /* Disable Rx for now */ + /* Enable DBGU receiver. */ + DBGU_CR = BV(US_RXEN); + /* Disable PIO on DGBU rx pin. */ + PIOA_PDR = BV(DRXD); + PIOA_ASR = BV(DRXD); + #endif + #else + #error CONFIG_KDEBUG_PORT should be KDEBUG_PORT_DBGU + #endif /* CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU */ +} diff --git a/bertos/cpu/arm/drv/kdebug_at91.h b/bertos/cpu/arm/drv/kdebug_at91.h new file mode 100644 index 00000000..165764e5 --- /dev/null +++ b/bertos/cpu/arm/drv/kdebug_at91.h @@ -0,0 +1,55 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief ARM debug support (interface). + */ + +#ifndef DRV_KDEBUG_AT91_H +#define DRV_KDEBUG_AT91_H + +/** + * \name Values for CONFIG_KDEBUG_PORT. + * + * Select which hardware UART to use for system debug. + * + * \{ + */ +#define KDEBUG_PORT_DBGU 0 ///< Debug on Debug Unit. + +#define KDEBUG_PORT_DEFAULT KDEBUG_PORT_DBGU ///< Default debug port. +/* \} */ + +#endif /* DRV_KDEBUG_AT91_H */ diff --git a/bertos/cpu/arm/drv/ser_arm.c b/bertos/cpu/arm/drv/ser_arm.c new file mode 100644 index 00000000..dbd84d75 --- /dev/null +++ b/bertos/cpu/arm/drv/ser_arm.c @@ -0,0 +1,47 @@ +/** + * \file + * + * + * \version $Id: timer_arm.c 18260 2007-10-11 14:08:10Z batt $ + * + * \author Daniele Basile + * + * \brief Low-level USART module for ARM (inplementation). + */ + +#include + +#if CPU_ARM_AT91 + #include "ser_at91.c" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif diff --git a/bertos/cpu/arm/drv/ser_arm.h b/bertos/cpu/arm/drv/ser_arm.h new file mode 100644 index 00000000..d3abfea6 --- /dev/null +++ b/bertos/cpu/arm/drv/ser_arm.h @@ -0,0 +1,47 @@ +/** + * \file + * + * + * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ + * + * \author Daniele Basile + * + * \brief Low-level serial module for ARM (interface). + */ + +#include + +#if CPU_ARM_AT91 + #include "ser_at91.h" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif diff --git a/bertos/cpu/arm/drv/ser_at91.c b/bertos/cpu/arm/drv/ser_at91.c new file mode 100644 index 00000000..74cca47b --- /dev/null +++ b/bertos/cpu/arm/drv/ser_at91.c @@ -0,0 +1,946 @@ +/** + * \file + * + * + * \brief ARM UART and SPI I/O driver + * + * + * \version $Id: ser_at91.c 20881 2008-03-04 14:07:02Z batt $ + * \author Daniele Basile + */ + +#include + +#include +#include +#include + +#include /* Required for bus macros overrides */ +#include /* CLOCK_FREQ */ + +#include +#include + +#include + +#define SERIRQ_PRIORITY 4 ///< default priority for serial irqs. + +/** + * \name Overridable serial bus hooks + * + * These can be redefined in hw.h to implement + * special bus policies such as half-duplex, 485, etc. + * + * + * \code + * TXBEGIN TXCHAR TXEND TXOFF + * | __________|__________ | | + * | | | | | | | | | + * v v v v v v v v v + * ______ __ __ __ __ __ __ ________________ + * \/ \/ \/ \/ \/ \/ \/ + * ______/\__/\__/\__/\__/\__/\__/ + * + * \endcode + * + * \{ + */ + +#ifndef SER_UART0_BUS_TXINIT + /** + * Default TXINIT macro - invoked in uart0_init() + * + * - Disable GPIO on USART0 tx/rx pins + */ + #if !CPU_ARM_AT91SAM7S256 && !CPU_ARM_AT91SAM7X256 && !CPU_ARM_AT91SAM7X128 + #warning Check USART0 pins! + #endif + #define SER_UART0_BUS_TXINIT do { \ + PIOA_PDR = BV(RXD0) | BV(TXD0); \ + } while (0) + +#endif + +#ifndef SER_UART0_BUS_TXBEGIN + /** + * Invoked before starting a transmission + */ + #define SER_UART0_BUS_TXBEGIN +#endif + +#ifndef SER_UART0_BUS_TXCHAR + /** + * Invoked to send one character. + */ + #define SER_UART0_BUS_TXCHAR(c) do { \ + US0_THR = (c); \ + } while (0) +#endif + +#ifndef SER_UART0_BUS_TXEND + /** + * Invoked as soon as the txfifo becomes empty + */ + #define SER_UART0_BUS_TXEND +#endif + +/* End USART0 macros */ + +#ifndef SER_UART1_BUS_TXINIT + /** + * Default TXINIT macro - invoked in uart1_init() + * + * - Disable GPIO on USART1 tx/rx pins + */ + #if !CPU_ARM_AT91SAM7S256 && !CPU_ARM_AT91SAM7X256 && !CPU_ARM_AT91SAM7X128 + #warning Check USART1 pins! + #endif + #define SER_UART1_BUS_TXINIT do { \ + PIOA_PDR = BV(RXD1) | BV(TXD1); \ + } while (0) + +#endif + +#ifndef SER_UART1_BUS_TXBEGIN + /** + * Invoked before starting a transmission + */ + #define SER_UART1_BUS_TXBEGIN +#endif + +#ifndef SER_UART1_BUS_TXCHAR + /** + * Invoked to send one character. + */ + #define SER_UART1_BUS_TXCHAR(c) do { \ + US1_THR = (c); \ + } while (0) +#endif + +#ifndef SER_UART1_BUS_TXEND + /** + * Invoked as soon as the txfifo becomes empty + */ + #define SER_UART1_BUS_TXEND +#endif + +/** +* \name Overridable SPI hooks +* +* These can be redefined in hw.h to implement +* special bus policies such as slave select pin handling, etc. +* +* \{ +*/ + +#ifndef SER_SPI0_BUS_TXINIT + /** + * Default TXINIT macro - invoked in spi_init() + * The default is no action. + */ + #define SER_SPI0_BUS_TXINIT +#endif + +#ifndef SER_SPI0_BUS_TXCLOSE + /** + * Invoked after the last character has been transmitted. + * The default is no action. + */ + #define SER_SPI0_BUS_TXCLOSE +#endif + +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 + + #ifndef SER_SPI1_BUS_TXINIT + /** + * Default TXINIT macro - invoked in spi_init() + * The default is no action. + */ + #define SER_SPI1_BUS_TXINIT + #endif + + #ifndef SER_SPI1_BUS_TXCLOSE + /** + * Invoked after the last character has been transmitted. + * The default is no action. + */ + #define SER_SPI1_BUS_TXCLOSE + #endif +#endif +/*\}*/ + + +/** + * \def CONFIG_SER_STROBE + * + * This is a debug facility that can be used to + * monitor SER interrupt activity on an external pin. + * + * To use strobes, redefine the macros SER_STROBE_ON, + * SER_STROBE_OFF and SER_STROBE_INIT and set + * CONFIG_SER_STROBE to 1. + */ +#if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE + #define SER_STROBE_ON do {/*nop*/} while(0) + #define SER_STROBE_OFF do {/*nop*/} while(0) + #define SER_STROBE_INIT do {/*nop*/} while(0) +#endif + + +/* From the high-level serial driver */ +extern struct Serial ser_handles[SER_CNT]; + +/* TX and RX buffers */ +static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; +static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; + +static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; +static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; + +static unsigned char spi0_txbuffer[CONFIG_SPI0_TXBUFSIZE]; +static unsigned char spi0_rxbuffer[CONFIG_SPI0_RXBUFSIZE]; +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +static unsigned char spi1_txbuffer[CONFIG_SPI1_TXBUFSIZE]; +static unsigned char spi1_rxbuffer[CONFIG_SPI1_RXBUFSIZE]; +#endif + +/** + * Internal hardware state structure + * + * The \a sending variable is true while the transmission + * interrupt is retriggering itself. + * + * For the USARTs the \a sending flag is useful for taking specific + * actions before sending a burst of data, at the start of a trasmission + * but not before every char sent. + * + * For the SPI, this flag is necessary because the SPI sends and receives + * bytes at the same time and the SPI IRQ is unique for send/receive. + * The only way to start transmission is to write data in SPDR (this + * is done by spi_starttx()). We do this *only* if a transfer is + * not already started. + */ +struct ArmSerial +{ + struct SerialHardware hw; + volatile bool sending; +}; + + +/* + * These are to trick GCC into *not* using absolute addressing mode + * when accessing ser_handles, which is very expensive. + * + * Accessing through these pointers generates much shorter + * (and hopefully faster) code. + */ +struct Serial *ser_uart0 = &ser_handles[SER_UART0]; +struct Serial *ser_uart1 = &ser_handles[SER_UART1]; + +struct Serial *ser_spi0 = &ser_handles[SER_SPI0]; +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +struct Serial *ser_spi1 = &ser_handles[SER_SPI1]; +#endif + +static void uart0_irq_dispatcher(void); +static void uart1_irq_dispatcher(void); +static void spi0_irq_handler(void); +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +static void spi1_irq_handler(void); +#endif +/* + * Callbacks for USART0 + */ +static void uart0_init( + UNUSED_ARG(struct SerialHardware *, _hw), + UNUSED_ARG(struct Serial *, ser)) +{ + US0_IDR = 0xFFFFFFFF; + /* Set the vector. */ + AIC_SVR(US0_ID) = uart0_irq_dispatcher; + /* Initialize to edge triggered with defined priority. */ + AIC_SMR(US0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; + PMC_PCER = BV(US0_ID); + + /* + * - Reset USART0 + * - Set serial param: mode Normal, 8bit data, 1bit stop, parity none + * - Enable both the receiver and the transmitter + * - Enable only the RX complete interrupt + */ + US0_CR = BV(US_RSTRX) | BV(US_RSTTX); + US0_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO; + US0_CR = BV(US_RXEN) | BV(US_TXEN); + US0_IER = BV(US_RXRDY); + + SER_UART0_BUS_TXINIT; + + /* Enable the USART IRQ */ + AIC_IECR = BV(US0_ID); + + SER_STROBE_INIT; +} + +static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + US0_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA); +} + +static void uart0_enabletxirq(struct SerialHardware *_hw) +{ + struct ArmSerial *hw = (struct ArmSerial *)_hw; + + /* + * WARNING: racy code here! The tx interrupt sets hw->sending to false + * when it runs with an empty fifo. The order of statements in the + * if-block matters. + */ + if (!hw->sending) + { + hw->sending = true; + /* + * - Enable the transmitter + * - Enable TX empty interrupt + */ + SER_UART0_BUS_TXBEGIN; + US0_IER = BV(US_TXEMPTY); + } +} + +static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + /* Compute baud-rate period */ + US0_BRGR = CLOCK_FREQ / (16 * rate); + //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) +} + +static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) +{ + US0_MR &= ~US_PAR_MASK; + /* Set UART parity */ + switch(parity) + { + case SER_PARITY_NONE: + { + /* Parity none. */ + US0_MR |= US_PAR_NO; + break; + } + case SER_PARITY_EVEN: + { + /* Even parity. */ + US0_MR |= US_PAR_EVEN; + break; + } + case SER_PARITY_ODD: + { + /* Odd parity. */ + US0_MR |= US_PAR_ODD; + break; + } + default: + ASSERT(0); + } + +} +/* + * Callbacks for USART1 + */ +static void uart1_init( + UNUSED_ARG(struct SerialHardware *, _hw), + UNUSED_ARG(struct Serial *, ser)) +{ + US1_IDR = 0xFFFFFFFF; + /* Set the vector. */ + AIC_SVR(US1_ID) = uart1_irq_dispatcher; + /* Initialize to edge triggered with defined priority. */ + AIC_SMR(US1_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; + PMC_PCER = BV(US1_ID); + + /* + * - Reset USART1 + * - Set serial param: mode Normal, 8bit data, 1bit stop, parity none + * - Enable both the receiver and the transmitter + * - Enable only the RX complete interrupt + */ + US1_CR = BV(US_RSTRX) | BV(US_RSTTX); + US1_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO; + US1_CR = BV(US_RXEN) | BV(US_TXEN); + US1_IER = BV(US_RXRDY); + + SER_UART1_BUS_TXINIT; + + /* Enable the USART IRQ */ + AIC_IECR = BV(US1_ID); + + SER_STROBE_INIT; +} + +static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + US1_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA); +} + +static void uart1_enabletxirq(struct SerialHardware *_hw) +{ + struct ArmSerial *hw = (struct ArmSerial *)_hw; + + /* + * WARNING: racy code here! The tx interrupt sets hw->sending to false + * when it runs with an empty fifo. The order of statements in the + * if-block matters. + */ + if (!hw->sending) + { + hw->sending = true; + /* + * - Enable the transmitter + * - Enable TX empty interrupt + */ + SER_UART1_BUS_TXBEGIN; + US1_IER = BV(US_TXEMPTY); + } +} + +static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + /* Compute baud-rate period */ + US1_BRGR = CLOCK_FREQ / (16 * rate); + //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) +} + +static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) +{ + US1_MR &= ~US_PAR_MASK; + /* Set UART parity */ + switch(parity) + { + case SER_PARITY_NONE: + { + /* Parity none. */ + US1_MR |= US_PAR_NO; + break; + } + case SER_PARITY_EVEN: + { + /* Even parity. */ + US1_MR |= US_PAR_EVEN; + break; + } + case SER_PARITY_ODD: + { + /* Odd parity. */ + US1_MR |= US_PAR_ODD; + break; + } + default: + ASSERT(0); + } + +} + +/* SPI driver */ +static void spi0_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) +{ + /* Disable PIO on SPI pins */ + PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); + + /* Reset device */ + SPI0_CR = BV(SPI_SWRST); + + /* + * Set SPI to master mode, fixed peripheral select, chip select directly connected to a peripheral device, + * SPI clock set to MCK, mode fault detection disabled, loopback disable, NPCS0 active, Delay between CS = 0 + */ + SPI0_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); + + /* + * Set SPI mode. + * At reset clock division factor is set to 0, that is + * *forbidden*. Set SPI clock to minimum to keep it valid. + */ + SPI0_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + + /* Disable all irqs */ + SPI0_IDR = 0xFFFFFFFF; + /* Set the vector. */ + AIC_SVR(SPI0_ID) = spi0_irq_handler; + /* Initialize to edge triggered with defined priority. */ + AIC_SMR(SPI0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; + /* Enable the USART IRQ */ + AIC_IECR = BV(SPI0_ID); + PMC_PCER = BV(SPI0_ID); + + /* Enable interrupt on tx buffer empty */ + SPI0_IER = BV(SPI_TXEMPTY); + + /* Enable SPI */ + SPI0_CR = BV(SPI_SPIEN); + + + SER_SPI0_BUS_TXINIT; + + SER_STROBE_INIT; +} + +static void spi0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + /* Disable SPI */ + SPI0_CR = BV(SPI_SPIDIS); + + /* Disable all irqs */ + SPI0_IDR = 0xFFFFFFFF; + + SER_SPI0_BUS_TXCLOSE; + + /* Enable PIO on SPI pins */ + PIOA_PER = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); +} + +static void spi0_starttx(struct SerialHardware *_hw) +{ + struct ArmSerial *hw = (struct ArmSerial *)_hw; + + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Send data only if the SPI is not already transmitting */ + if (!hw->sending && !fifo_isempty(&ser_spi0->txfifo)) + { + hw->sending = true; + SPI0_TDR = fifo_pop(&ser_spi0->txfifo); + } + + IRQ_RESTORE(flags); +} + +static void spi0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + SPI0_CSR0 &= ~SPI_SCBR; + + ASSERT((uint8_t)DIV_ROUND(CLOCK_FREQ, rate)); + SPI0_CSR0 |= DIV_ROUND(CLOCK_FREQ, rate) << SPI_SCBR_SHIFT; +} + +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +/* SPI driver */ +static void spi1_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) +{ + /* Disable PIO on SPI pins */ + PIOA_PDR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); + + /* Reset device */ + SPI1_CR = BV(SPI_SWRST); + +/* + * Set SPI to master mode, fixed peripheral select, chip select directly connected to a peripheral device, + * SPI clock set to MCK, mode fault detection disabled, loopback disable, NPCS0 active, Delay between CS = 0 + */ + SPI1_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); + + /* + * Set SPI mode. + * At reset clock division factor is set to 0, that is + * *forbidden*. Set SPI clock to minimum to keep it valid. + */ + SPI1_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + + /* Disable all irqs */ + SPI1_IDR = 0xFFFFFFFF; + /* Set the vector. */ + AIC_SVR(SPI1_ID) = spi1_irq_handler; + /* Initialize to edge triggered with defined priority. */ + AIC_SMR(SPI1_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; + /* Enable the USART IRQ */ + AIC_IECR = BV(SPI1_ID); + PMC_PCER = BV(SPI1_ID); + + /* Enable interrupt on tx buffer empty */ + SPI1_IER = BV(SPI_TXEMPTY); + + /* Enable SPI */ + SPI1_CR = BV(SPI_SPIEN); + + + SER_SPI1_BUS_TXINIT; + + SER_STROBE_INIT; +} + +static void spi1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + /* Disable SPI */ + SPI1_CR = BV(SPI_SPIDIS); + + /* Disable all irqs */ + SPI1_IDR = 0xFFFFFFFF; + + SER_SPI1_BUS_TXCLOSE; + + /* Enable PIO on SPI pins */ + PIOA_PER = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); +} + +static void spi1_starttx(struct SerialHardware *_hw) +{ + struct ArmSerial *hw = (struct ArmSerial *)_hw; + + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Send data only if the SPI is not already transmitting */ + if (!hw->sending && !fifo_isempty(&ser_spi1->txfifo)) + { + hw->sending = true; + SPI1_TDR = fifo_pop(&ser_spi1->txfifo); + } + + IRQ_RESTORE(flags); +} + +static void spi1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + SPI1_CSR0 &= ~SPI_SCBR; + + ASSERT((uint8_t)DIV_ROUND(CLOCK_FREQ, rate)); + SPI1_CSR0 |= DIV_ROUND(CLOCK_FREQ, rate) << SPI_SCBR_SHIFT; +} +#endif + +static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity)) +{ + // nop +} + + +static bool tx_sending(struct SerialHardware* _hw) +{ + struct ArmSerial *hw = (struct ArmSerial *)_hw; + return hw->sending; +} + +// FIXME: move into compiler.h? Ditch? +#if COMPILER_C99 + #define C99INIT(name,val) .name = val +#elif defined(__GNUC__) + #define C99INIT(name,val) name: val +#else + #warning No designated initializers, double check your code + #define C99INIT(name,val) (val) +#endif + +/* + * High-level interface data structures + */ +static const struct SerialHardwareVT UART0_VT = +{ + C99INIT(init, uart0_init), + C99INIT(cleanup, uart0_cleanup), + C99INIT(setBaudrate, uart0_setbaudrate), + C99INIT(setParity, uart0_setparity), + C99INIT(txStart, uart0_enabletxirq), + C99INIT(txSending, tx_sending), +}; + +static const struct SerialHardwareVT UART1_VT = +{ + C99INIT(init, uart1_init), + C99INIT(cleanup, uart1_cleanup), + C99INIT(setBaudrate, uart1_setbaudrate), + C99INIT(setParity, uart1_setparity), + C99INIT(txStart, uart1_enabletxirq), + C99INIT(txSending, tx_sending), +}; + +static const struct SerialHardwareVT SPI0_VT = +{ + C99INIT(init, spi0_init), + C99INIT(cleanup, spi0_cleanup), + C99INIT(setBaudrate, spi0_setbaudrate), + C99INIT(setParity, spi_setparity), + C99INIT(txStart, spi0_starttx), + C99INIT(txSending, tx_sending), +}; +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +static const struct SerialHardwareVT SPI1_VT = +{ + C99INIT(init, spi1_init), + C99INIT(cleanup, spi1_cleanup), + C99INIT(setBaudrate, spi1_setbaudrate), + C99INIT(setParity, spi_setparity), + C99INIT(txStart, spi1_starttx), + C99INIT(txSending, tx_sending), +}; +#endif + +static struct ArmSerial UARTDescs[SER_CNT] = +{ + { + C99INIT(hw, /**/) { + C99INIT(table, &UART0_VT), + C99INIT(txbuffer, uart0_txbuffer), + C99INIT(rxbuffer, uart0_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart0_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)), + }, + C99INIT(sending, false), + }, + { + C99INIT(hw, /**/) { + C99INIT(table, &UART1_VT), + C99INIT(txbuffer, uart1_txbuffer), + C99INIT(rxbuffer, uart1_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart1_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)), + }, + C99INIT(sending, false), + }, + + { + C99INIT(hw, /**/) { + C99INIT(table, &SPI0_VT), + C99INIT(txbuffer, spi0_txbuffer), + C99INIT(rxbuffer, spi0_rxbuffer), + C99INIT(txbuffer_size, sizeof(spi0_txbuffer)), + C99INIT(rxbuffer_size, sizeof(spi0_rxbuffer)), + }, + C99INIT(sending, false), + }, + #if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 + { + C99INIT(hw, /**/) { + C99INIT(table, &SPI1_VT), + C99INIT(txbuffer, spi1_txbuffer), + C99INIT(rxbuffer, spi1_rxbuffer), + C99INIT(txbuffer_size, sizeof(spi1_txbuffer)), + C99INIT(rxbuffer_size, sizeof(spi1_rxbuffer)), + }, + C99INIT(sending, false), + } + + #endif +}; + +struct SerialHardware *ser_hw_getdesc(int unit) +{ + ASSERT(unit < SER_CNT); + return &UARTDescs[unit].hw; +} + +/** + * Serial 0 TX interrupt handler + */ +static void uart0_irq_tx(void) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; + + if (fifo_isempty(txfifo)) + { + /* + * - Disable the TX empty interrupts + */ + US0_IDR = BV(US_TXEMPTY); + SER_UART0_BUS_TXEND; + UARTDescs[SER_UART0].sending = false; + } + else + { + char c = fifo_pop(txfifo); + SER_UART0_BUS_TXCHAR(c); + } + + SER_STROBE_OFF; +} + +/** + * Serial 0 RX complete interrupt handler. + */ +static void uart0_irq_rx(void) +{ + SER_STROBE_ON; + + /* Should be read before US_CRS */ + ser_uart0->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); + + char c = US0_RHR; + struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo; + + if (fifo_isfull(rxfifo)) + ser_uart0->status |= SERRF_RXFIFOOVERRUN; + else + fifo_push(rxfifo, c); + + SER_STROBE_OFF; +} + +/** + * Serial IRQ dispatcher for USART0. + */ +static void uart0_irq_dispatcher(void) __attribute__ ((interrupt)); +static void uart0_irq_dispatcher(void) +{ + if (US0_CSR & BV(US_RXRDY)) + uart0_irq_rx(); + + if (US0_CSR & BV(US_TXEMPTY)) + uart0_irq_tx(); + + /* Inform hw that we have served the IRQ */ + AIC_EOICR = 0; +} + +/** + * Serial 1 TX interrupt handler + */ +static void uart1_irq_tx(void) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; + + if (fifo_isempty(txfifo)) + { + /* + * - Disable the TX empty interrupts + */ + US1_IDR = BV(US_TXEMPTY); + SER_UART1_BUS_TXEND; + UARTDescs[SER_UART1].sending = false; + } + else + { + char c = fifo_pop(txfifo); + SER_UART1_BUS_TXCHAR(c); + } + + SER_STROBE_OFF; +} + +/** + * Serial 1 RX complete interrupt handler. + */ +static void uart1_irq_rx(void) +{ + SER_STROBE_ON; + + /* Should be read before US_CRS */ + ser_uart1->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); + + char c = US1_RHR; + struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo; + + if (fifo_isfull(rxfifo)) + ser_uart1->status |= SERRF_RXFIFOOVERRUN; + else + fifo_push(rxfifo, c); + + SER_STROBE_OFF; +} + +/** + * Serial IRQ dispatcher for USART1. + */ +static void uart1_irq_dispatcher(void) __attribute__ ((interrupt)); +static void uart1_irq_dispatcher(void) +{ + if (US1_CSR & BV(US_RXRDY)) + uart1_irq_rx(); + + if (US1_CSR & BV(US_TXEMPTY)) + uart1_irq_tx(); + + /* Inform hw that we have served the IRQ */ + AIC_EOICR = 0; +} + +/** + * SPI0 interrupt handler + */ +static void spi0_irq_handler(void) __attribute__ ((interrupt)); +static void spi0_irq_handler(void) +{ + SER_STROBE_ON; + + char c = SPI0_RDR; + /* Read incoming byte. */ + if (!fifo_isfull(&ser_spi0->rxfifo)) + fifo_push(&ser_spi0->rxfifo, c); + /* + * FIXME + else + ser_spi0->status |= SERRF_RXFIFOOVERRUN; + */ + + /* Send */ + if (!fifo_isempty(&ser_spi0->txfifo)) + SPI0_TDR = fifo_pop(&ser_spi0->txfifo); + else + UARTDescs[SER_SPI0].sending = false; + + /* Inform hw that we have served the IRQ */ + AIC_EOICR = 0; + SER_STROBE_OFF; +} + + +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +/** + * SPI1 interrupt handler + */ +static void spi1_irq_handler(void) __attribute__ ((interrupt)); +static void spi1_irq_handler(void) +{ + SER_STROBE_ON; + + char c = SPI1_RDR; + /* Read incoming byte. */ + if (!fifo_isfull(&ser_spi1->rxfifo)) + fifo_push(&ser_spi1->rxfifo, c); + /* + * FIXME + else + ser_spi1->status |= SERRF_RXFIFOOVERRUN; + */ + + /* Send */ + if (!fifo_isempty(&ser_spi1->txfifo)) + SPI1_TDR = fifo_pop(&ser_spi1->txfifo); + else + UARTDescs[SER_SPI1].sending = false; + + /* Inform hw that we have served the IRQ */ + AIC_EOICR = 0; + SER_STROBE_OFF; +} +#endif diff --git a/bertos/cpu/arm/drv/ser_at91.h b/bertos/cpu/arm/drv/ser_at91.h new file mode 100644 index 00000000..fd836c41 --- /dev/null +++ b/bertos/cpu/arm/drv/ser_at91.h @@ -0,0 +1,83 @@ +/** + * \file + * + * + * \brief High level serial I/O API + * + * \version $Id: ser_at91.h 20552 2008-02-14 16:40:41Z batt $ + * \author Daniele Basile + */ + +#ifndef SER_AT91_H +#define SER_AT91_H + +#include /* BV() */ +#include /* uint32_t */ +#include /* CPU_* */ + +/** \name Serial Error/status flags. */ +/*\{*/ +typedef uint32_t serstatus_t; + +/* Software errors */ +#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ +#define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */ +#define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */ + +/* + * Hardware errors. + * These flags map directly to the ARM USART Channel Status Register (US_CSR). + */ +#define SERRF_RXSROVERRUN BV(5) /**< Rx shift register overrun */ +#define SERRF_FRAMEERROR BV(6) /**< Stop bit missing */ +#define SERRF_PARITYERROR BV(7) /**< Parity error */ +#define SERRF_NOISEERROR 0 /**< Unsupported */ +/*\}*/ + +/** + * \name Serial hw numbers + * + * \{ + */ +enum +{ +SER_UART0, +SER_UART1, +SER_SPI0, +#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 +SER_SPI1, +#endif +SER_CNT /**< Number of serial ports */ +}; +/*\}*/ + +#endif /* SER_AT91_H */ diff --git a/bertos/cpu/arm/drv/sysirq_at91.c b/bertos/cpu/arm/drv/sysirq_at91.c new file mode 100644 index 00000000..281c7963 --- /dev/null +++ b/bertos/cpu/arm/drv/sysirq_at91.c @@ -0,0 +1,171 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief System IRQ handler for Atmel AT91 ARM7 processors. + * + * In Atmel AT91 ARM7TDMI processors, there are various + * peripheral interrupt sources. + * In general, every source has its own interrupt vector, so it + * is possible to assign a specific handler for each interrupt + * independently. + * However, there are a few sources called "system sources" that + * share a common IRQ line and vector, called "system IRQ". + * So a unique system IRQ dispatcher is implemented here. + * This module also contains an interface to manage every source + * independently. It is possible to assign to every system IRQ + * a specific IRQ handler. + * + * \see sysirq_setHandler + * \see sysirq_setEnable + */ + +#include "sysirq_at91.h" +#include +#include +#include +#include +#include + +/** + * Enable/disable the Periodic Interrupt Timer + * interrupt. + */ +INLINE void pit_setEnable(bool enable) +{ + if (enable) + PIT_MR |= BV(PITIEN); + else + PIT_MR &= ~BV(PITIEN); +} + +/** + * Table containing all system irqs. + */ +static SysIrq sysirq_tab[] = +{ + /* PIT, Periodic Interval Timer (System timer)*/ + { + .enabled = false, + .setEnable = pit_setEnable, + .handler = NULL, + }, + /* TODO: add other system sources here */ +}; + +STATIC_ASSERT(countof(sysirq_tab) == SYSIRQ_CNT); + +/** + * System IRQ dispatcher. + * This is the entry point for all system IRQs in AT91. + * This function checks for interrupt enable state of + * various sources (system timer, etc..) and calls + * the corresponding handler. + */ +static void sysirq_dispatcher(void) __attribute__ ((interrupt)); +static void sysirq_dispatcher(void) +{ + for (unsigned i = 0; i < countof(sysirq_tab); i++) + { + if (sysirq_tab[i].enabled + && sysirq_tab[i].handler) + sysirq_tab[i].handler(); + } + + /* Inform hw that we have served the IRQ */ + AIC_EOICR = 0; +} + +#define SYSIRQ_PRIORITY 0 ///< default priority for system irqs. + + +MOD_DEFINE(sysirq); + +/** + * Init system IRQ handling. + * \note all system interrupts are disabled. + */ +void sysirq_init(void) +{ + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Disable all system interrupts */ + for (unsigned i = 0; i < countof(sysirq_tab); i++) + sysirq_tab[i].setEnable(false); + + /* Set the vector. */ + AIC_SVR(SYSC_ID) = sysirq_dispatcher; + /* Initialize to edge triggered with defined priority. */ + AIC_SMR(SYSC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SYSIRQ_PRIORITY; + /* Clear pending interrupt */ + AIC_ICCR = BV(SYSC_ID); + /* Enable the system IRQ */ + AIC_IECR = BV(SYSC_ID); + + IRQ_RESTORE(flags); + MOD_INIT(sysirq); +} + + +/** + * Helper function used to set handler for system IRQ \a irq. + */ +void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler) +{ + ASSERT(irq < SYSIRQ_CNT); + sysirq_tab[irq].handler = handler; +} + +/** + * Helper function used to enable/disable system IRQ \a irq. + */ +void sysirq_setEnable(sysirq_t irq, bool enable) +{ + ASSERT(irq < SYSIRQ_CNT); + + sysirq_tab[irq].setEnable(enable); + sysirq_tab[irq].enabled = enable; +} + +/** + * Helper function used to get system IRQ \a irq state. + */ +bool sysirq_enabled(sysirq_t irq) +{ + ASSERT(irq < SYSIRQ_CNT); + + return sysirq_tab[irq].enabled; +} diff --git a/bertos/cpu/arm/drv/sysirq_at91.h b/bertos/cpu/arm/drv/sysirq_at91.h new file mode 100644 index 00000000..ad094fca --- /dev/null +++ b/bertos/cpu/arm/drv/sysirq_at91.h @@ -0,0 +1,73 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief System irq handler for Atmel AT91 ARM7 processors (interface). + */ + +#ifndef DRV_AT91_SYSIRQ_H +#define DRV_AT91_SYSIRQ_H + +#include + +typedef void (* sysirq_handler_t)(void); ///< Type for system irq handler. +typedef void (* sysirq_setEnable_t)(bool); ///< Type for system irq enable/disable function. + +/** + * Structure used to define a system interrupt source. + */ +typedef struct SysIrq +{ + bool enabled; ///< Getter for irq enable/disable state. + sysirq_setEnable_t setEnable; ///< Setter for irq enable/disable state. + sysirq_handler_t handler; ///< IRQ handler. +} SysIrq; + +/** + * System IRQ ID list. + */ +typedef enum sysirq_t +{ + SYSIRQ_PIT, ///< Periodic Interval Timer + /* TODO: add all system irqs */ + SYSIRQ_CNT +} sysirq_t; + +void sysirq_init(void); +void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler); +void sysirq_setEnable(sysirq_t irq, bool enable); +bool sysirq_enabled(sysirq_t irq); + +#endif /* ARCH_ARM_SYSIRQ_H */ diff --git a/bertos/cpu/arm/drv/timer_arm.c b/bertos/cpu/arm/drv/timer_arm.c new file mode 100644 index 00000000..405366ce --- /dev/null +++ b/bertos/cpu/arm/drv/timer_arm.c @@ -0,0 +1,47 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief Low-level timer module for ARM (inplementation). + */ + +#include + +#if CPU_ARM_AT91 + #include "timer_at91.c" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif diff --git a/bertos/cpu/arm/drv/timer_arm.h b/bertos/cpu/arm/drv/timer_arm.h new file mode 100644 index 00000000..60b096cc --- /dev/null +++ b/bertos/cpu/arm/drv/timer_arm.h @@ -0,0 +1,47 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief Low-level timer module for ARM (interface). + */ + +#include + +#if CPU_ARM_AT91 + #include "timer_at91.h" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif diff --git a/bertos/cpu/arm/drv/timer_at91.c b/bertos/cpu/arm/drv/timer_at91.c new file mode 100644 index 00000000..e27e8a63 --- /dev/null +++ b/bertos/cpu/arm/drv/timer_at91.c @@ -0,0 +1,95 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief Low-level timer module for Atmel AT91 (inplementation). + */ + +#include "timer_at91.h" +#include +#include "sysirq_at91.h" + +#include // BV() +#include +#include +#include + + +/** HW dependent timer initialization */ +#if (CONFIG_TIMER == TIMER_ON_PIT) + INLINE void timer_hw_irq(void) + { + /* Reset counters, this is needed to reset timer and interrupt flags */ + uint32_t dummy = PIVR; + (void) dummy; + } + + INLINE bool timer_hw_triggered(void) + { + return PIT_SR & BV(PITS); + } + + INLINE void timer_hw_init(void) + { + cpuflags_t flags; + + MOD_CHECK(sysirq); + + IRQ_SAVE_DISABLE(flags); + + PIT_MR = TIMER_HW_CNT; + /* Register system interrupt handler. */ + sysirq_setHandler(SYSIRQ_PIT, timer_handler); + + /* Enable interval timer and interval timer interrupts */ + PIT_MR |= BV(PITEN); + sysirq_setEnable(SYSIRQ_PIT, true); + + /* Reset counters, this is needed to start timer and interrupt flags */ + uint32_t dummy = PIVR; + (void) dummy; + + IRQ_RESTORE(flags); + } + + INLINE hptime_t timer_hw_hpread(void) + { + /* In the upper part of PIT_PIIR there is unused data */ + return PIIR & CPIV_MASK; + } + +#else + #error Unimplemented value for CONFIG_TIMER +#endif /* CONFIG_TIMER */ diff --git a/bertos/cpu/arm/drv/timer_at91.h b/bertos/cpu/arm/drv/timer_at91.h new file mode 100644 index 00000000..87bccd1e --- /dev/null +++ b/bertos/cpu/arm/drv/timer_at91.h @@ -0,0 +1,81 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * \brief Low-level timer module for Atmel AT91 (interface). + */ + +#ifndef DRV_AT91_TIMER_H +#define DRV_AT91_TIMER_H + +#include /* CONFIG_TIMER */ +#include /* uint8_t */ +#include /* CLOCK_FREQ */ + +/** + * \name Values for CONFIG_TIMER. + * + * Select which hardware timer interrupt to use for system clock and softtimers. + * + * \{ + */ +#define TIMER_ON_PIT 1 ///< System timer on Periodic interval timer + +#define TIMER_DEFAULT TIMER_ON_PIT ///< Default system timer +/* \} */ + +/* + * Hardware dependent timer initialization. + */ +#if (CONFIG_TIMER == TIMER_ON_PIT) + + void timer_handler(void); + + #define DEFINE_TIMER_ISR void timer_handler(void) + #define TIMER_TICKS_PER_SEC 1000 + #define TIMER_HW_CNT (CLOCK_FREQ / (16 * TIMER_TICKS_PER_SEC) - 1) + + /** Frequency of the hardware high-precision timer. */ + #define TIMER_HW_HPTICKS_PER_SEC (CLOCK_FREQ / 16) + + /// Type of time expressed in ticks of the hardware high-precision timer + typedef uint32_t hptime_t; +#else + + #error Unimplemented value for CONFIG_TIMER +#endif /* CONFIG_TIMER */ + + +#endif /* DRV_TIMER_AT91_H */ diff --git a/bertos/cpu/arm/hw/crt.s b/bertos/cpu/arm/hw/crt.s new file mode 100644 index 00000000..98d723ee --- /dev/null +++ b/bertos/cpu/arm/hw/crt.s @@ -0,0 +1,223 @@ +/**************************************************************************** +* Copyright (c) 2006 by Michael Fischer. 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 of the author 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. +* +**************************************************************************** +* +* History: +* +* 18.12.06 mifi First Version +* The hardware initialization is based on the startup file +* crtat91sam7x256_rom.S from NutOS 4.2.1. +* Therefore partial copyright by egnite Software GmbH. +****************************************************************************/ + +/* + * Some defines for the program status registers + */ + ARM_MODE_USER = 0x10 /* Normal User Mode */ + ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ + ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ + ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ + ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ + ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ + ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ + ARM_MODE_MASK = 0x1F + + I_BIT = 0x80 /* disable IRQ when I bit is set */ + F_BIT = 0x40 /* disable IRQ when I bit is set */ + +/* + * Register Base Address + */ + AIC_BASE = 0xFFFFF000 + AIC_EOICR_OFF = 0x130 + AIC_IDCR_OFF = 0x124 + + RSTC_MR = 0xFFFFFD08 + RSTC_KEY = 0xA5000000 + RSTC_URSTEN = 0x00000001 + + WDT_BASE = 0xFFFFFD40 + WDT_MR_OFF = 0x00000004 + WDT_WDDIS = 0x00008000 + + MC_BASE = 0xFFFFFF00 + MC_FMR_OFF = 0x00000060 + MC_FWS_1FWS = 0x00480100 + + .section .vectors,"ax" + .code 32 + +/****************************************************************************/ +/* Vector table and reset entry */ +/****************************************************************************/ +_vectors: + ldr pc, ResetAddr /* Reset */ + ldr pc, UndefAddr /* Undefined instruction */ + ldr pc, SWIAddr /* Software interrupt */ + ldr pc, PAbortAddr /* Prefetch abort */ + ldr pc, DAbortAddr /* Data abort */ + ldr pc, ReservedAddr /* Reserved */ + ldr pc, [pc, #-0xF20] /* IRQ interrupt */ + ldr pc, FIQAddr /* FIQ interrupt */ + +.extern maion + +ResetAddr: .word ResetHandler +UndefAddr: .word UndefHandler +SWIAddr: .word SWIHandler +PAbortAddr: .word PAbortHandler +DAbortAddr: .word DAbortHandler +ReservedAddr: .word 0 +IRQAddr: .word IRQHandler +FIQAddr: .word FIQHandler + + .ltorg + + .section .init, "ax" + .code 32 + + .global ResetHandler + .global ExitFunction + .extern main +/****************************************************************************/ +/* Reset handler */ +/****************************************************************************/ +ResetHandler: + /* + * The watchdog is enabled after processor reset. Disable it. + */ + ldr r1, =WDT_BASE + ldr r0, =WDT_WDDIS + str r0, [r1, #WDT_MR_OFF] + + + /* + * Enable user reset: assertion length programmed to 1ms + */ + ldr r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8)) + ldr r1, =RSTC_MR + str r0, [r1, #0] + + + /* + * Use 2 cycles for flash access. + */ + ldr r1, =MC_BASE + ldr r0, =MC_FWS_1FWS + str r0, [r1, #MC_FMR_OFF] + + + /* + * Disable all interrupts. Useful for debugging w/o target reset. + */ + ldr r1, =AIC_BASE + mvn r0, #0 + str r0, [r1, #AIC_EOICR_OFF] + str r0, [r1, #AIC_IDCR_OFF] + + + /* + * Setup a stack for each mode + */ + msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ + ldr sp, =__stack_und_end + + msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ + ldr sp, =__stack_abt_end + + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ + ldr sp, =__stack_fiq_end + + msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ + ldr sp, =__stack_irq_end + + msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ + ldr sp, =__stack_svc_end + + + /* + * Clear .bss section + */ + ldr r1, =__bss_start + ldr r2, =__bss_end + ldr r3, =0 +bss_clear_loop: + cmp r1, r2 + strne r3, [r1], #+4 + bne bss_clear_loop + + + /* + * Jump to main + */ + + mov r0, #0 /* No arguments */ + mov r1, #0 /* No arguments */ + ldr r2, =main + mov lr, pc + bx r2 /* And jump... */ + +ExitFunction: + nop + nop + nop + b ExitFunction + + +/****************************************************************************/ +/* Default interrupt handler */ +/****************************************************************************/ + +UndefHandler: + b UndefHandler + +SWIHandler: + b SWIHandler + +PAbortHandler: + b PAbortHandler + +DAbortHandler: + b DAbortHandler + +IRQHandler: + b IRQHandler + +FIQHandler: + b FIQHandler + + .weak ExitFunction + .weak UndefHandler, PAbortHandler, DAbortHandler + .weak IRQHandler, FIQHandler + + .ltorg +/*** EOF ***/ + + diff --git a/bertos/cpu/arm/hw/crtat91sam7_rom.S b/bertos/cpu/arm/hw/crtat91sam7_rom.S new file mode 100644 index 00000000..0a2fa4a7 --- /dev/null +++ b/bertos/cpu/arm/hw/crtat91sam7_rom.S @@ -0,0 +1,331 @@ +/** + * \file + * + * + * \version $Id: $ + * + * \author Francesco Sacchi + * + * \brief AT91SAM7S256 CRT, adapted from NUt/OS, see license below. + */ + +/* + * Copyright (C) 2005-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + * + */ + +#include "hw_cpu.h" +#include + + +#if CLOCK_FREQ != 48023000L +#error Clock registers set for 48MHz operation, revise following code if you want a different clock. +#endif + + +#if CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X256 + /** + * With a 18.420MHz cristal, master clock is: + * (((18.420 * PLL_MUL_VAL + 1) / PLL_DIV_VAL) / AT91MCK_PRES) = 48.023MHz + */ + #define PLL_MUL_VAL 72 /**< Real multiplier value is PLL_MUL_VAL + 1! */ + #define PLL_DIV_VAL 14 + #define AT91MCK_PRES PMC_PRES_CLK_2 + + /** + * Register I/O adresses. + * \{ + */ + #define MC_BASE 0xFFFFFF00 + #define MC_FMR_OFF 0x00000060 + #define MC_FWS_2R3W 0x00000100 + + #define AIC_BASE 0xFFFFF000 + #define AIC_EOICR_OFF 0x00000130 + #define AIC_IDCR_OFF 0x00000124 + + #define WDT_BASE 0xFFFFFD40 + #define WDT_MR_OFF 0x00000004 + #define WDT_WDDIS (1 << 15) + + #define PMC_BASE 0xFFFFFC00 + #define PMC_SR_OFF 0x00000068 + #define PMC_MCKR_OFF 0x00000030 + #define PMC_MOSCS (1 << 0) + #define PMC_LOCK (1 << 2) + #define PMC_MCKRDY (1 << 3) + #define PMC_CSS_PLL_CLK 0x00000003 + #define PMC_PRES_CLK_2 0x00000004 + + #define CKGR_MOR_OFF 0x00000020 + #define CKGR_PLLR_OFF 0x0000002C + #define CKGR_MOSCEN (1 << 0) + #define CKGR_MUL_SHIFT 16 + #define CKGR_PLLCOUNT_SHIFT 8 + + #define RSTC_MR 0xFFFFFD08 + #define RSTC_KEY 0xA5000000 + #define RSTC_URSTEN (1 << 0) + + #define ARM_MODE_FIQ 0x11 + #define ARM_MODE_IRQ 0x12 + #define ARM_MODE_SVC 0x13 + #define ARM_MODE_ABORT 0x17 + #define ARM_MODE_UNDEF 0x1B + +#else + #error No register I/O definition for selected ARM CPU +#endif +/*\}*/ + +/* + * Section 0: Vector table and reset entry. + */ + .section .vectors,"ax",%progbits + + .global __vectors +__vectors: + ldr pc, [pc, #24] /* Reset */ + ldr pc, [pc, #24] /* Undefined instruction */ + ldr pc, [pc, #24] /* Software interrupt */ + ldr pc, [pc, #24] /* Prefetch abort */ + ldr pc, [pc, #24] /* Data abort */ + ldr pc, [pc, #24] /* Reserved */ + + /* + * On IRQ the PC will be loaded from AIC_IVR, which + * provides the address previously set in AIC_SVR. + * The interrupt routine will be called in ARM_MODE_IRQ + * with IRQ disabled and FIQ unchanged. + */ + ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */ + ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */ + + .word _init + .word __undef + .word __swi + .word __prefetch_abort + .word __data_abort + + .weak __undef + .set __undef, __xcpt_dummy_undef + .weak __swi + .set __swi, __xcpt_dummy_swi + .weak __prefetch_abort + .set __prefetch_abort, __xcpt_dummy_pref + .weak __data_abort + .set __data_abort, __xcpt_dummy_dab + +/** .global __xcpt_dummy*/ +__xcpt_dummy_undef: + b __xcpt_dummy_undef + +__xcpt_dummy_swi: + b __xcpt_dummy_swi + +__xcpt_dummy_pref: + b __xcpt_dummy_pref + +__xcpt_dummy_dab: + b __xcpt_dummy_dab + + + .ltorg +/* + * Hardware initialization. + */ + .section .init, "ax", %progbits + .globl _init +_init: + /* + * Use 2 cycles for flash access. + */ + ldr r1, =MC_BASE + mov r0, #MC_FWS_2R3W + str r0, [r1, #MC_FMR_OFF] + + /* + * Disable all interrupts. Useful for debugging w/o target reset. + */ + ldr r1, =AIC_BASE + mvn r0, #0 + str r0, [r1, #AIC_EOICR_OFF] + str r0, [r1, #AIC_IDCR_OFF] + + /* + * The watchdog is enabled after processor reset. Disable it. + */ + ldr r1, =WDT_BASE + ldr r0, =WDT_WDDIS + str r0, [r1, #WDT_MR_OFF] + + /* + * Enable the main oscillator. Set startup time of 6 * 8 slow + * clock cycles and wait until oscillator is stabilized. + */ + ldr r1, =PMC_BASE + mov r0, #(6 << 8) + orr r0, r0, #CKGR_MOSCEN + str r0, [r1, #CKGR_MOR_OFF] +wait_moscs: + ldr r0, [r1, #PMC_SR_OFF] + tst r0, #PMC_MOSCS + beq wait_moscs + + /* + * Set PLL: + * PLLfreq = crystal / divider * (multiplier + 1) + * Wait 28 clock cycles until PLL is locked. + */ + ldr r0, =((PLL_MUL_VAL << CKGR_MUL_SHIFT) | (28 << CKGR_PLLCOUNT_SHIFT) | PLL_DIV_VAL) + + str r0, [r1, #CKGR_PLLR_OFF] +wait_lock: + ldr r0, [r1, #PMC_SR_OFF] + tst r0, #PMC_LOCK + beq wait_lock + + /* + * Set master clock prescaler. + */ + mov r0, #AT91MCK_PRES + str r0, [r1, #PMC_MCKR_OFF] +wait_presrdy: + ldr r0, [r1, #PMC_SR_OFF] + tst r0, #PMC_MCKRDY + beq wait_presrdy + + /* + * Switch to PLL clock. Trying to set this together with the + * prescaler fails (see datasheets). + */ + ldr r0, [r1, #PMC_MCKR_OFF] + orr r0, r0, #PMC_CSS_PLL_CLK + str r0, [r1, #PMC_MCKR_OFF] +wait_pllsel: + ldr r0, [r1, #PMC_SR_OFF] + tst r0, #PMC_MCKRDY + beq wait_pllsel + + /* + * Enable external reset key. + */ + ldr r0, =(RSTC_KEY | RSTC_URSTEN) + ldr r1, =RSTC_MR + str r0, [r1, #0] + + /* + * Set exception stack pointers + */ + ldr r0, =__stack_fiq_end + msr CPSR_c, #ARM_MODE_FIQ | 0xC0 + mov r13, r0 + ldr r0, =__stack_irq_end + msr CPSR_c, #ARM_MODE_IRQ | 0xC0 + mov r13, r0 + ldr r0, =__stack_abt_end + msr CPSR_c, #ARM_MODE_ABORT | 0xC0 + mov r13, r0 + ldr r0, =__stack_und_end + msr CPSR_c, #ARM_MODE_UNDEF | 0xC0 + mov r13, r0 + ldr r0, =__stack_svc_end + msr CPSR_c, #ARM_MODE_SVC | 0xC0 + mov r13, r0 + + /* + * Clear .bss + */ + ldr r1, =__bss_start + ldr r2, =__bss_end + ldr r3, =0 + +_40: + cmp r1, r2 + strne r3, [r1], #+4 + bne _40 + + /* + * Relocate .data section (Copy from ROM to RAM). + */ + ldr r1, =__etext + ldr r2, =__data_start + ldr r3, =__data_end + +_41: + cmp r2, r3 + ldrlo r0, [r1], #4 + strlo r0, [r2], #4 + blo _41 + + /* + * Initialize user stack pointer. + */ + ldr r13, =__stack_end + + /* + * Jump to main + */ + ldr r0, =main + bx r0 + +End: + b End + + .ltorg diff --git a/bertos/cpu/arm/hw/switch.h b/bertos/cpu/arm/hw/switch.h new file mode 100644 index 00000000..9ed15b94 --- /dev/null +++ b/bertos/cpu/arm/hw/switch.h @@ -0,0 +1,90 @@ +/** + * \file + * + * + * \brief Kernel scheduler macros. + * + * \version $Id$ + * + * \author Francesco Sacchi + * \author Stefano Fedrigo + */ + +#ifndef CPU_ARM_HW_SWITCH_H +#define CPU_ARM_HW_SWITCH_H + +#include + +/** + * Interrupt entry point. + * Needed because AT91 uses an Interrupt Controller with auto-vectoring. + */ +#define SCHEDULER_IRQ_ENTRY \ + asm volatile("sub lr, lr, #4 \n\t" /* Adjust LR */ \ + "stmfd sp!, {r0} \n\t" /* Save r0 */ \ + "stmfd sp, {sp}^ \n\t" /* Save user SP */ \ + "sub sp, sp, #4 \n\t" /* Decrement irq SP, writeback is illegal */ \ + "ldmfd sp!, {r0} \n\t" /* Restore user SP immedately in r0 */ \ + "stmfd r0!, {lr} \n\t" /* Store system LR in user stack */ \ + "stmfd r0, {r1-r12,lr}^ \n\t" /* Store registers on user stack (user LR too) */ \ + "sub r0, r0, #52 \n\t" /* Decrement r0, writeback is illegal */ \ + "ldmfd sp!, {r1} \n\t" /* Restore r0 */ \ + "stmfd r0!, {r1} \n\t" /* Store r0 in user stack too */ \ + "mrs r1, spsr \n\t" /* Save SPSR... */ \ + "stmfd r0!, {r1} \n\t" /* ... in user stack */ \ + "ldr r1, =CurrentProcess \n\t" /* Load in r1 &CurrentProcess->stack */ \ + "ldr r1, [r1, %0] \n\t" \ + "str r0, [r1] \n\t" /* Store the process SP */ \ + "sub fp, sp, #4 \n\t" /* Store the process SP */ \ + : /* no output */ \ + : "n" (offsetof(Process, stack)) \ + ) + + +#define SCHEDULER_IRQ_EXIT \ + asm volatile("ldr lr, =CurrentProcess \n\t" /* Load &CurrentProcess->stack */ \ + "ldr lr, [lr, %0] \n\t" \ + "ldr lr, [lr] \n\t" /* Load current process SP */ \ + "ldr r0, =0xFFFFF000 \n\t" /* End of interrupt for AT91 */ \ + "str r0, [r0, #0x130] \n\t" /* */ \ + "ldmfd lr!, {r0} \n\t" /* Pop status reg */ \ + "msr spsr, r0 \n\t" /* ... */ \ + "ldmfd lr, {r0-r12,lr}^ \n\t" /* Restore user regs */ \ + "add lr, lr, #56 \n\t" /* 52 + irq link register (extracted below) */ \ + "stmfd sp!, {lr} \n\t" /* Push user stack pointer in irq stack */ \ + "ldmfd sp, {sp}^ \n\t" /* Restore user SP */ \ + "sub sp, sp, #4 \n\t" /* Align irq SP */ \ + "ldmdb lr, {pc}^ \n\t" /* And return to user space (We use ldmdb cause lr is sp+4) */ \ + : /* no output */ \ + : "n" (offsetof(Process, stack)) \ + ) + +#endif /* CPU_ARM_HW_SWITCH_H */ diff --git a/bertos/cpu/arm/io/arm.h b/bertos/cpu/arm/io/arm.h new file mode 100644 index 00000000..5690c317 --- /dev/null +++ b/bertos/cpu/arm/io/arm.h @@ -0,0 +1,54 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * ARM I/O registers. + */ + + +#ifndef ARM_H +#define ARM_H + +#include + +#if CPU_ARM_AT91 + #include "at91.h" +/*#elif Add other ARM families here */ +#else + #error Unknown CPU +#endif + + +#endif /* ARM_H */ diff --git a/bertos/cpu/arm/io/at91.h b/bertos/cpu/arm/io/at91.h new file mode 100644 index 00000000..7bdde9b9 --- /dev/null +++ b/bertos/cpu/arm/io/at91.h @@ -0,0 +1,85 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 common definitions. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_H +#define AT91_H + +#include + +#if CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X256 + #include "at91sam7.h" + +#else + #error Missing I/O definitions for CPU. +#endif + +#endif /* AT91_H */ diff --git a/bertos/cpu/arm/io/at91_adc.h b/bertos/cpu/arm/io/at91_adc.h new file mode 100644 index 00000000..2abe435b --- /dev/null +++ b/bertos/cpu/arm/io/at91_adc.h @@ -0,0 +1,199 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Daniele Basile + * + * AT91SAM7 Analog to Digital Converter. + * + */ + + +#ifndef AT91_ADC_H +#define AT91_ADC_H + + +/** + * ADC control register + */ +#define ADC_CR_OFF 0x00000000 ///< Control register offeset. +#define ADC_CR (*((reg32_t *)(ADC_BASE + ADC_CR_OFF))) ///< Control register address. +#define ADC_SWRST 0 ///< Software reset. +#define ADC_START 1 ///< Start conversion. + + +/** + * ADC mode register + */ +#define ADC_MR_OFF 0x00000004 ///< Mode register offeset. +#define ADC_MR (*((reg32_t *)(ADC_BASE + ADC_MR_OFF))) ///< Mode register address. +#define ADC_TRGEN 0 ///< Trigger enable. + +#define ADC_TRGSEL_TIOA0 0x00000000 ///< TIOA output of the timer counter channel 0. +#define ADC_TRGSEL_TIOA1 0x00000002 ///< TIOA output of the timer counter channel 1. +#define ADC_TRGSEL_TIOA2 0x00000004 ///< TIOA output of the timer counter channel 2. +#define ADC_TRGSEL_EXT 0x0000000C ///< External trigger. + +#define ADC_LOWRES 4 ///< Resolution 0: 10-bit, 1: 8-bit. +#define ADC_SLEEP 5 ///< Sleep mode. + +/** + * Prescaler rate selection. + * ADCClock = MCK / ((ADC_PRESCALER_VALUE + 1) * 2) + */ +#define ADC_PRESCALER_MASK 0x00003F00 ///< Prescaler rate selection mask. +#define ADC_PRESCALER_SHIFT 8 ///< Prescale rate selection shift. + +/** + * Start up timer. + * Startup time = (ADC_STARTUP_VALUE + 1) * 8 /ADCClock + */ +#define ADC_STARTUP_MASK 0x001F0000 ///< Start up timer mask. +#define ADC_STARTUP_SHIFT 16 ///< Start up timer shift. + + +/** + * Sample & hold time. + * Sample & hold time = (ADC_SHTIM_VALUE + 1) * 8 /ADCClock + */ +#define ADC_SHTIME_MASK 0x0F000000 ///< Sample & hold time mask. +#define ADC_SHTIME_SHIFT 24 ///< Sample & hold time shift. + + +/** + * ADC channel enable register + */ +#define ADC_CHER_OFF 0x00000010 ///< Channel enable register offeset. +#define ADC_CHER (*((reg32_t *)(ADC_BASE + ADC_CHER_OFF))) ///< Channel enable register address. + +/** + * ADC channel disable register + */ +#define ADC_CHDR_OFF 0x00000014 ///< Channel disable register offeset. +#define ADC_CHDR (*((reg32_t *)(ADC_BASE + ADC_CHDR_OFF))) ///< Channel disable register address. + +/** + * ADC channel status register + */ +#define ADC_CHSR_OFF 0x00000018 ///< Channel status register offeset. +#define ADC_CHSR (*((reg32_t *)(ADC_BASE + ADC_CHSR_OFF))) ///< Channel status register address. + +#define ADC_CH_MASK 0x000000FF ///< Channel mask. +#define ADC_CH0 0 ///< Channel 0 +#define ADC_CH1 1 ///< Channel 1 +#define ADC_CH2 2 ///< Channel 2 +#define ADC_CH3 3 ///< Channel 3 +#define ADC_CH4 4 ///< Channel 4 +#define ADC_CH5 5 ///< Channel 5 +#define ADC_CH6 6 ///< Channel 6 +#define ADC_CH7 7 ///< Channel 7 + +/** + * ADC status register + */ +#define ADC_SR_OFF 0x0000001C ///< Status register offeset. +#define ADC_SR (*((reg32_t *)(ADC_BASE + ADC_SR_OFF))) ///< Status register address. + +/** + * ADC Interrupt enable register. + */ +#define ADC_IER_OFF 0x00000024 ///< Interrupt enable register offeset. +#define ADC_IER (*((reg32_t *)(ADC_BASE + ADC_IER_OFF))) ///< Interrupt enable register. + +/** + * ADC Interrupt disable register. + */ +#define ADC_IDR_OFF 0x00000028 ///< Interrupt disable register offeset. +#define ADC_IDR (*((reg32_t *)(ADC_BASE + ADC_IDR_OFF))) ///< Interrupt disable register. + +/** + * ADC Interrupt mask register. + */ +#define ADC_IMR_OFF 0x0000002C ///< Interrupt mask register offeset. +#define ADC_IMR (*((reg32_t *)(ADC_BASE + ADC_IMR_OFF))) ///< Interrupt mask register. + +#define ADC_EOC_MASK 0x000000FF ///< End of converison mask. +#define ADC_EOC0 0 ///< End of conversion channel 0. +#define ADC_EOC1 1 ///< End of conversion channel 1. +#define ADC_EOC2 2 ///< End of conversion channel 2. +#define ADC_EOC3 3 ///< End of conversion channel 3. +#define ADC_EOC4 4 ///< End of conversion channel 4. +#define ADC_EOC5 5 ///< End of conversion channel 5. +#define ADC_EOC6 6 ///< End of conversion channel 6. +#define ADC_EOC7 7 ///< End of conversion channel 7. + +#define ADC_OVRE0 8 ///< Overrun error channel 0. +#define ADC_OVRE1 9 ///< Overrun error channel 1. +#define ADC_OVRE2 10 ///< Overrun error channel 2. +#define ADC_OVRE3 11 ///< Overrun error channel 3. +#define ADC_OVRE4 12 ///< Overrun error channel 4. +#define ADC_OVRE5 13 ///< Overrun error channel 5. +#define ADC_OVRE6 14 ///< Overrun error channel 6. +#define ADC_OVRE7 15 ///< Overrun error channel 7. + +#define ADC_DRDY 16 ///< Data ready. +#define ADC_GOVRE 17 ///< General overrun error. +#define ADC_ENDRX 18 ///< End of RX buffer. +#define ADC_RXBUFF 19 ///< Rx buffer full. + +/** + * ADC last convert data register. + */ +#define ADC_LCDR_OFF 0x00000020 ///< Last converted data register offeset. +#define ADC_LCDR (*((reg32_t *)(ADC_BASE + ADC_LCDR_OFF))) ///< Last converted data register. + +/** + * ADC channel data register. + * + * \{ + */ +#define ADC_CDR0_OFF 0x00000030 ///< Channel data register 0 offeset. +#define ADC_CDR1_OFF 0x00000034 ///< Channel data register 1 offeset. +#define ADC_CDR2_OFF 0x00000038 ///< Channel data register 2 offeset. +#define ADC_CDR3_OFF 0x0000003C ///< Channel data register 3 offeset. +#define ADC_CDR4_OFF 0x00000040 ///< Channel data register 4 offeset. +#define ADC_CDR5_OFF 0x00000044 ///< Channel data register 5 offeset. +#define ADC_CDR6_OFF 0x00000048 ///< Channel data register 6 offeset. +#define ADC_CDR7_OFF 0x0000004C ///< Channel data register 7 offeset. + +#define ADC_CDR0 (*((reg32_t *)(ADC_BASE + ADC_CDR0_OFF))) ///< Channel data register 0. +#define ADC_CDR1 (*((reg32_t *)(ADC_BASE + ADC_CDR1_OFF))) ///< Channel data register 1. +#define ADC_CDR2 (*((reg32_t *)(ADC_BASE + ADC_CDR2_OFF))) ///< Channel data register 2. +#define ADC_CDR3 (*((reg32_t *)(ADC_BASE + ADC_CDR3_OFF))) ///< Channel data register 3. +#define ADC_CDR4 (*((reg32_t *)(ADC_BASE + ADC_CDR4_OFF))) ///< Channel data register 4. +#define ADC_CDR5 (*((reg32_t *)(ADC_BASE + ADC_CDR5_OFF))) ///< Channel data register 5. +#define ADC_CDR6 (*((reg32_t *)(ADC_BASE + ADC_CDR6_OFF))) ///< Channel data register 6. +#define ADC_CDR7 (*((reg32_t *)(ADC_BASE + ADC_CDR7_OFF))) ///< Channel data register 7. +/* \} */ + +#endif /* AT91_ADC_H */ diff --git a/bertos/cpu/arm/io/at91_aic.h b/bertos/cpu/arm/io/at91_aic.h new file mode 100644 index 00000000..8fdd2914 --- /dev/null +++ b/bertos/cpu/arm/io/at91_aic.h @@ -0,0 +1,223 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 advanced interrupt controller. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_AIC_H +#define AT91_AIC_H + +#include + + + +/** + * Source mode register array. + */ +#define AIC_SMR(i) (*((reg32_t *)(AIC_BASE + (i) * 4))) + +/** + * Priority mask. + * Priority levels can be between 0 (lowest) and 7 (highest). + */ +#define AIC_PRIOR_MASK 0x00000007 + +/** + * Interrupt source type mask. + * Internal interrupts can level sensitive or edge triggered. + * + * External interrupts can triggered on positive or negative levels or + * on rising or falling edges. + */ +/*\{*/ +#define AIC_SRCTYPE_MASK 0x00000060 + +#define AIC_SRCTYPE_INT_LEVEL_SENSITIVE 0x00000000 ///< Internal level sensitive. +#define AIC_SRCTYPE_INT_EDGE_TRIGGERED 0x00000020 ///< Internal edge triggered. +#define AIC_SRCTYPE_EXT_LOW_LEVEL 0x00000000 ///< External low level. +#define AIC_SRCTYPE_EXT_NEGATIVE_EDGE 0x00000020 ///< External falling edge. +#define AIC_SRCTYPE_EXT_HIGH_LEVEL 0x00000040 ///< External high level. +#define AIC_SRCTYPE_EXT_POSITIVE_EDGE 0x00000060 ///< External rising edge. +/*\}*/ + + +/** + * Type for interrupt handlers. + */ +typedef void (*irq_handler_t)(void); + +/** Interrupt Source Vector Registers */ +/*\{*/ +/** Source vector register array. + * + * Stores the addresses of the corresponding interrupt handlers. + */ +#define AIC_SVR(i) (*((volatile irq_handler_t *)(AIC_BASE + 0x80 + (i) * 4))) +/*\}*/ + +/** Interrupt Vector Register */ +/*\{*/ +#define AIC_IVR_OFF 0x00000100 ///< IRQ vector register offset. +#define AIC_IVR (*((reg32_t *)(AIC_BASE + AIC_IVR_OFF))) ///< IRQ vector register address. +/*\}*/ + +/** Fast Interrupt Vector Register */ +/*\{*/ +#define AIC_FVR_OFF 0x00000104 ///< FIQ vector register offset. +#define AIC_FVR (*((reg32_t *)(AIC_BASE + AIC_FVR_OFF))) ///< FIQ vector register address. +/*\}*/ + +/** Interrupt Status Register */ +/*\{*/ +#define AIC_ISR_OFF 0x00000108 ///< Interrupt status register offset. +#define AIC_ISR (*((reg32_t *)(AIC_BASE + AIC_ISR_OFF))) ///< Interrupt status register address. +#define AIC_IRQID_MASK 0x0000001F ///< Current interrupt identifier mask. +/*\}*/ + +/** Interrupt Pending Register */ +/*\{*/ +#define AIC_IPR_OFF 0x0000010C ///< Interrupt pending register offset. +#define AIC_IPR (*((reg32_t *)(AIC_BASE + AIC_IPR_OFF))) ///< Interrupt pending register address. +/*\}*/ + +/** Interrupt Mask Register */ +/*\{*/ +#define AIC_IMR_OFF 0x00000110 ///< Interrupt mask register offset. +#define AIC_IMR (*((reg32_t *)(AIC_BASE + AIC_IMR_OFF))) ///< Interrupt mask register address. +/*\}*/ + +/** Interrupt Core Status Register */ +/*\{*/ +#define AIC_CISR_OFF 0x00000114 ///< Core interrupt status register offset. +#define AIC_CISR (*((reg32_t *)(AIC_BASE + AIC_CISR_OFF))) ///< Core interrupt status register address. +#define AIC_NFIQ 1 ///< Core FIQ Status +#define AIC_NIRQ 2 ///< Core IRQ Status +/*\}*/ + +/** Interrupt Enable Command Register */ +/*\{*/ +#define AIC_IECR_OFF 0x00000120 ///< Interrupt enable command register offset. +#define AIC_IECR (*((reg32_t *)(AIC_BASE + AIC_IECR_OFF))) ///< Interrupt enable command register address. +/*\}*/ + +/** Interrupt Disable Command Register */ +/*\{*/ +#define AIC_IDCR_OFF 0x00000124 ///< Interrupt disable command register offset. +#define AIC_IDCR (*((reg32_t *)(AIC_BASE + AIC_IDCR_OFF))) ///< Interrupt disable command register address. +/*\}*/ + +/** Interrupt Clear Command Register */ +/*\{*/ +#define AIC_ICCR_OFF 0x00000128 ///< Interrupt clear command register offset. +#define AIC_ICCR (*((reg32_t *)(AIC_BASE + AIC_ICCR_OFF))) ///< Interrupt clear command register address. +/*\}*/ + +/** Interrupt Set Command Register */ +/*\{*/ +#define AIC_ISCR_OFF 0x0000012C ///< Interrupt set command register offset. +#define AIC_ISCR (*((reg32_t *)(AIC_BASE + AIC_ISCR_OFF))) ///< Interrupt set command register address. +/*\}*/ + +/** End Of Interrupt Command Register */ +/*\{*/ +#define AIC_EOICR_OFF 0x00000130 ///< End of interrupt command register offset. +#define AIC_EOICR (*((reg32_t *)(AIC_BASE + AIC_EOICR_OFF))) ///< End of interrupt command register address. +/*\}*/ + +/** Spurious Interrupt Vector Register */ +/*\{*/ +#define AIC_SPU_OFF 0x00000134 ///< Spurious vector register offset. +#define AIC_SPU (*((reg32_t *)(AIC_BASE + AIC_SPU_OFF)== ///< Spurious vector register address. +/*\}*/ + +/** Debug Control Register */ +/*\{*/ +#define AIC_DCR_OFF 0x0000138 ///< Debug control register offset. +#define AIC_DCR (*((reg32_t *)(AIC_BASE + AIC_DCR_OFF))) ///< Debug control register address. +/*\}*/ + +/** Fast Forcing Enable Register */ +/*\{*/ +#define AIC_FFER_OFF 0x00000140 ///< Fast forcing enable register offset. +#define AIC_FFER (*((reg32_t *)(AIC_BASE + AIC_FFER_OFF))) ///< Fast forcing enable register address. +/*\}*/ + +/** Fast Forcing Disable Register */ +/*\{*/ +#define AIC_FFDR_OFF 0x00000144 ///< Fast forcing disable register address. +#define AIC_FFDR (*((reg32_t *)(AIC_BASE + AIC_FFDR_OFF))) ///< Fast forcing disable register address. +/*\}*/ + +/** Fast Forcing Status Register */ +/*\{*/ +#define AIC_FFSR_OFF 0x00000148 ///< Fast forcing status register address. +#define AIC_FFSR (*((reg32_t *)(AIC_BASE + AIC_FFSR_OFF))) ///< Fast forcing status register address. +/*\}*/ + +#endif /* AT91_AIC_H */ diff --git a/bertos/cpu/arm/io/at91_dbgu.h b/bertos/cpu/arm/io/at91_dbgu.h new file mode 100644 index 00000000..5fa700de --- /dev/null +++ b/bertos/cpu/arm/io/at91_dbgu.h @@ -0,0 +1,107 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 Debug unit. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ +#ifndef AT91_DBGU_H +#define AT91_DBGU_H + +#define DBGU_CR (*((reg32_t *)(DBGU_BASE + US_CR_OFF))) /// + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 Memory controller. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_MC_H +#define AT91_MC_H + +#define MC_RCR_OFF 0x00000000 ///< MC remap control register offset. +#define MC_RCR (*((reg32_t *)(MC_BASE + MC_RCR_OFF))) ///< MC remap control register address. +#define MC_RCB 0 ///< Remap command. + +#define MC_ASR_OFF 0x00000004 ///< MC abort status register offset. +#define MC_ASR (*((reg32_t *)(MC_BASE + MC_ASR_OFF))) ///< MC abort status register address. +#define MC_UNDADD 0 ///< Undefined Addess Abort status. +#define MC_MISADD 1 ///< Misaligned Addess Abort status. +#define MC_ABTSZ_MASK 0x00000300 ///< Abort size status mask. +#define MC_ABTSZ_BYTE 0x00000000 ///< Byte size abort. +#define MC_ABTSZ_HWORD 0x00000100 ///< Half-word size abort. +#define MC_ABTSZ_WORD 0x00000200 ///< Word size abort. +#define MC_ABTTYP_MASK 0x00000C00 ///< Abort type status mask. +#define MC_ABTTYP_DATAR 0x00000000 ///< Data read abort. +#define MC_ABTTYP_DATAW 0x00000400 ///< Data write abort. +#define MC_ABTTYP_FETCH 0x00000800 ///< Code fetch abort. +#define MC_MST_PDC 0x00020000 ///< PDC abort source. +#define MC_MST_ARM 0x00040000 ///< ARM abort source. +#define MC_SVMST_PDC 0x02000000 ///< Saved PDC abort source. +#define MC_SVMST_ARM 0x04000000 ///< Saved ARM abort source. + +#define MC_AASR_OFF 0x00000008 ///< MC abort address status register offset. +#define MC_AASR (*((reg32_t *)(MC_BASE + MC_AASR_OFF))) ///< MC abort address status register address. + +#define MC_FMR_OFF 0x00000060 ///< MC flash mode register offset. +#define MC_FMR (*((reg32_t *)(MC_BASE + MC_FMR_OFF))) ///< MC flash mode register address. +#define MC_FRDY 0 ///< Flash ready. +#define MC_LOCKE 2 ///< Lock error. +#define MC_PROGE 3 ///< Programming error. +#define MC_NEBP 7 ///< No erase before programming. +#define MC_FWS_MASK 0x00000300 ///< Flash wait state mask. +#define MC_FWS_1R2W 0x00000000 ///< 1 cycle for read, 2 for write operations. +#define MC_FWS_2R3W 0x00000100 ///< 2 cycles for read, 3 for write operations. +#define MC_FWS_3R4W 0x00000200 ///< 3 cycles for read, 4 for write operations. +#define MC_FWS_4R4W 0x00000300 ///< 4 cycles for read and write operations. +#define MC_FMCN_MASK 0x00FF0000 ///< Flash microsecond cycle number mask. + +#define MC_FCR_OFF 0x00000064 ///< MC flash command register offset. +#define MC_FCR (*((reg32_t *)(MC_BASE + MC_FCR_OFF))) ///< MC flash command register address. +#define MC_FCMD_MASK 0x0000000F ///< Flash command mask. +#define MC_FCMD_NOP 0x00000000 ///< No command. +#define MC_FCMD_WP 0x00000001 ///< Write page. +#define MC_FCMD_SLB 0x00000002 ///< Set lock bit. +#define MC_FCMD_WPL 0x00000003 ///< Write page and lock. +#define MC_FCMD_CLB 0x00000004 ///< Clear lock bit. +#define MC_FCMD_EA 0x00000008 ///< Erase all. +#define MC_FCMD_SGPB 0x0000000B ///< Set general purpose NVM bit. +#define MC_FCMD_CGPB 0x0000000D ///< Clear general purpose NVM bit. +#define MC_FCMD_SSB 0x0000000F ///< Set security bit. +#define MC_PAGEN_MASK 0x0003FF00 ///< Page number mask. +#define MC_KEY 0x5A000000 ///< Writing protect key. + +#define MC_FSR_OFF 0x00000068 ///< MC flash status register offset. +#define MC_FSR (*((reg32_t *)(MC_BASE + MC_FSR_OFF))) ///< MC flash status register address. +#define MC_SECURITY 4 ///< Security bit status. + +#define MC_GPNVM0 8 ///< General purpose NVM bit 0. +#define MC_GPNVM1 9 ///< General purpose NVM bit 1. +#define MC_GPNVM2 10 ///< General purpose NVM bit 2. + +#define MC_LOCKS0 16 ///< Lock region 0 lock status. +#define MC_LOCKS1 17 ///< Lock region 1 lock status. +#define MC_LOCKS2 18 ///< Lock region 2 lock status. +#define MC_LOCKS3 19 ///< Lock region 3 lock status. +#define MC_LOCKS4 20 ///< Lock region 4 lock status. +#define MC_LOCKS5 21 ///< Lock region 5 lock status. +#define MC_LOCKS6 22 ///< Lock region 6 lock status. +#define MC_LOCKS7 23 ///< Lock region 7 lock status. +#define MC_LOCKS8 24 ///< Lock region 8 lock status. +#define MC_LOCKS9 25 ///< Lock region 9 lock status. +#define MC_LOCKS10 26 ///< Lock region 10 lock status. +#define MC_LOCKS11 27 ///< Lock region 11 lock status. +#define MC_LOCKS12 28 ///< Lock region 12 lock status. +#define MC_LOCKS13 29 ///< Lock region 13 lock status. +#define MC_LOCKS14 30 ///< Lock region 14 lock status. +#define MC_LOCKS15 31 ///< Lock region 15 lock status. + +#endif /* AT91_MC_H */ diff --git a/bertos/cpu/arm/io/at91_pio.h b/bertos/cpu/arm/io/at91_pio.h new file mode 100644 index 00000000..3aa47565 --- /dev/null +++ b/bertos/cpu/arm/io/at91_pio.h @@ -0,0 +1,297 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 Parallel input/output controller. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_PIO_H +#define AT91_PIO_H + +/** PIO Register Offsets */ +/*\{*/ +#define PIO_PER_OFF 0x00000000 ///< PIO enable register offset. +#define PIO_PDR_OFF 0x00000004 ///< PIO disable register offset. +#define PIO_PSR_OFF 0x00000008 ///< PIO status register offset. +#define PIO_OER_OFF 0x00000010 ///< Output enable register offset. +#define PIO_ODR_OFF 0x00000014 ///< Output disable register offset. +#define PIO_OSR_OFF 0x00000018 ///< Output status register offset. +#define PIO_IFER_OFF 0x00000020 ///< Input filter enable register offset. +#define PIO_IFDR_OFF 0x00000024 ///< Input filter disable register offset. +#define PIO_IFSR_OFF 0x00000028 ///< Input filter status register offset. +#define PIO_SODR_OFF 0x00000030 ///< Set output data register offset. +#define PIO_CODR_OFF 0x00000034 ///< Clear output data register offset. +#define PIO_ODSR_OFF 0x00000038 ///< Output data status register offset. +#define PIO_PDSR_OFF 0x0000003C ///< Pin data status register offset. +#define PIO_IER_OFF 0x00000040 ///< Interrupt enable register offset. +#define PIO_IDR_OFF 0x00000044 ///< Interrupt disable register offset. +#define PIO_IMR_OFF 0x00000048 ///< Interrupt mask register offset. +#define PIO_ISR_OFF 0x0000004C ///< Interrupt status register offset. +#if PIO_HAS_MULTIDRIVER +#define PIO_MDER_OFF 0x00000050 ///< Multi-driver enable register offset. +#define PIO_MDDR_OFF 0x00000054 ///< Multi-driver disable register offset. +#define PIO_MDSR_OFF 0x00000058 ///< Multi-driver status register offset. +#endif /* PIO_HAS_MULTIDRIVER */ +#if PIO_HAS_PULLUP +#define PIO_PUDR_OFF 0x00000060 ///< Pull-up disable register offset. +#define PIO_PUER_OFF 0x00000064 ///< Pull-up enable register offset. +#define PIO_PUSR_OFF 0x00000068 ///< Pull-up status register offset. +#endif /* PIO_HAS_PULLUP */ +#if PIO_HAS_PERIPHERALSELECT +#define PIO_ASR_OFF 0x00000070 ///< PIO peripheral A select register offset. +#define PIO_BSR_OFF 0x00000074 ///< PIO peripheral B select register offset. +#define PIO_ABSR_OFF 0x00000078 ///< PIO peripheral AB status register offset. +#endif /* PIO_HAS_PERIPHERALSELECT */ +#if PIO_HAS_OUTPUTWRITEENABLE +#define PIO_OWER_OFF 0x000000A0 ///< PIO output write enable register offset. +#define PIO_OWDR_OFF 0x000000A4 ///< PIO output write disable register offset. +#define PIO_OWSR_OFF 0x000000A8 ///< PIO output write status register offset. +#endif /* PIO_HAS_OUTPUTWRITEENABLE */ +/*\}*/ + +/** Single PIO Register Addresses */ +/*\{*/ +#if defined(PIO_BASE) + #define PIO_ACCESS(offset) (*((reg32_t *)(PIO_BASE + (offset)))) + + #define PIO_PER PIO_ACCESS(PIO_PER_OFF) ///< PIO enable register address. + #define PIO_PDR PIO_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. + #define PIO_PSR PIO_ACCESS(PIO_PSR_OFF) ///< PIO status register address. + #define PIO_OER PIO_ACCESS(PIO_OER_OFF) ///< Output enable register address. + #define PIO_ODR PIO_ACCESS(PIO_ODR_OFF) ///< Output disable register address. + #define PIO_OSR PIO_ACCESS(PIO_OSR_OFF) ///< Output status register address. + #define PIO_IFER PIO_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. + #define PIO_IFDR PIO_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. + #define PIO_IFSR PIO_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. + #define PIO_SODR PIO_ACCESS(PIO_SODR_OFF) ///< Set output data register address. + #define PIO_CODR PIO_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. + #define PIO_ODSR PIO_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. + #define PIO_PDSR PIO_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. + #define PIO_IER PIO_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. + #define PIO_IDR PIO_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. + #define PIO_IMR PIO_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. + #define PIO_ISR PIO_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. + #if PIO_HAS_MULTIDRIVER + #define PIO_MDER PIO_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. + #define PIO_MDDR PIO_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. + #define PIO_MDSR PIO_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. + #endif /* PIO_HAS_MULTIDRIVER */ + #if PIO_HAS_PULLUP + #define PIO_PUDR PIO_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. + #define PIO_PUER PIO_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. + #define PIO_PUSR PIO_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. + #endif /* PIO_HAS_PULLUP */ + #if PIO_HAS_PERIPHERALSELECT + #define PIO_ASR PIO_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. + #define PIO_BSR PIO_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. + #define PIO_ABSR PIO_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. + #endif /* PIO_HAS_PERIPHERALSELECT */ + #if PIO_HAS_OUTPUTWRITEENABLE + #define PIO_OWER PIO_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. + #define PIO_OWDR PIO_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. + #define PIO_OWSR PIO_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. + #endif /* PIO_HAS_OUTPUTWRITEENABLE */ +#endif /* PIO_BASE */ +/*\}*/ + +/** PIO A Register Addresses */ +/*\{*/ +#if defined(PIOA_BASE) + #define PIOA_ACCESS(offset) (*((reg32_t *)(PIOA_BASE + (offset)))) + + #define PIOA_PER PIOA_ACCESS(PIO_PER_OFF) ///< PIO enable register address. + #define PIOA_PDR PIOA_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. + #define PIOA_PSR PIOA_ACCESS(PIO_PSR_OFF) ///< PIO status register address. + #define PIOA_OER PIOA_ACCESS(PIO_OER_OFF) ///< Output enable register address. + #define PIOA_ODR PIOA_ACCESS(PIO_ODR_OFF) ///< Output disable register address. + #define PIOA_OSR PIOA_ACCESS(PIO_OSR_OFF) ///< Output status register address. + #define PIOA_IFER PIOA_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. + #define PIOA_IFDR PIOA_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. + #define PIOA_IFSR PIOA_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. + #define PIOA_SODR PIOA_ACCESS(PIO_SODR_OFF) ///< Set output data register address. + #define PIOA_CODR PIOA_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. + #define PIOA_ODSR PIOA_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. + #define PIOA_PDSR PIOA_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. + #define PIOA_IER PIOA_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. + #define PIOA_IDR PIOA_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. + #define PIOA_IMR PIOA_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. + #define PIOA_ISR PIOA_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. + #if PIO_HAS_MULTIDRIVER + #define PIOA_MDER PIOA_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. + #define PIOA_MDDR PIOA_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. + #define PIOA_MDSR PIOA_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. + #endif /* PIO_HAS_MULTIDRIVER */ + #if PIO_HAS_PULLUP + #define PIOA_PUDR PIOA_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. + #define PIOA_PUER PIOA_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. + #define PIOA_PUSR PIOA_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. + #endif /* PIO_HAS_PULLUP */ + #if PIO_HAS_PERIPHERALSELECT + #define PIOA_ASR PIOA_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. + #define PIOA_BSR PIOA_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. + #define PIOA_ABSR PIOA_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. + #endif /* PIO_HAS_PERIPHERALSELECT */ + #if PIO_HAS_OUTPUTWRITEENABLE + #define PIOA_OWER PIOA_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. + #define PIOA_OWDR PIOA_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. + #define PIOA_OWSR PIOA_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. + #endif /* PIO_HAS_OUTPUTWRITEENABLE */ +#endif /* PIOA_BASE */ +/*\}*/ + +/** PIO B Register Addresses */ +/*\{*/ +#if defined(PIOB_BASE) + #define PIOB_ACCESS(offset) (*((reg32_t *)(PIOB_BASE + (offset)))) + + #define PIOB_PER PIOB_ACCESS(PIO_PER_OFF) ///< PIO enable register address. + #define PIOB_PDR PIOB_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. + #define PIOB_PSR PIOB_ACCESS(PIO_PSR_OFF) ///< PIO status register address. + #define PIOB_OER PIOB_ACCESS(PIO_OER_OFF) ///< Output enable register address. + #define PIOB_ODR PIOB_ACCESS(PIO_ODR_OFF) ///< Output disable register address. + #define PIOB_OSR PIOB_ACCESS(PIO_OSR_OFF) ///< Output status register address. + #define PIOB_IFER PIOB_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. + #define PIOB_IFDR PIOB_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. + #define PIOB_IFSR PIOB_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. + #define PIOB_SODR PIOB_ACCESS(PIO_SODR_OFF) ///< Set output data register address. + #define PIOB_CODR PIOB_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. + #define PIOB_ODSR PIOB_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. + #define PIOB_PDSR PIOB_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. + #define PIOB_IER PIOB_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. + #define PIOB_IDR PIOB_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. + #define PIOB_IMR PIOB_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. + #define PIOB_ISR PIOB_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. + #if PIO_HAS_MULTIDRIVER + #define PIOB_MDER PIOB_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. + #define PIOB_MDDR PIOB_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. + #define PIOB_MDSR PIOB_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. + #endif /* PIO_HAS_MULTIDRIVER */ + #if PIO_HAS_PULLUP + #define PIOB_PUDR PIOB_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. + #define PIOB_PUER PIOB_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. + #define PIOB_PUSR PIOB_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. + #endif /* PIO_HAS_PULLUP */ + #if PIO_HAS_PERIPHERALSELECT + #define PIOB_ASR PIOB_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. + #define PIOB_BSR PIOB_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. + #define PIOB_ABSR PIOB_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. + #endif /* PIO_HAS_PERIPHERALSELECT */ + #if PIO_HAS_OUTPUTWRITEENABLE + #define PIOB_OWER PIOB_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. + #define PIOB_OWDR PIOB_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. + #define PIOB_OWSR PIOB_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. + #endif /* PIO_HAS_OUTPUTWRITEENABLE */ +#endif /* PIOB_BASE */ +/*\}*/ + +/** PIO C Register Addresses */ +/*\{*/ +#if defined(PIOC_BASE) + #define PIOC_ACCESS(offset) (*((reg32_t *)(PIOC_BASE + (offset)))) + + #define PIOC_PER PIOC_ACCESS(PIO_PER_OFF) ///< PIO enable register address. + #define PIOC_PDR PIOC_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. + #define PIOC_PSR PIOC_ACCESS(PIO_PSR_OFF) ///< PIO status register address. + #define PIOC_OER PIOC_ACCESS(PIO_OER_OFF) ///< Output enable register address. + #define PIOC_ODR PIOC_ACCESS(PIO_ODR_OFF) ///< Output disable register address. + #define PIOC_OSR PIOC_ACCESS(PIO_OSR_OFF) ///< Output status register address. + #define PIOC_IFER PIOC_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. + #define PIOC_IFDR PIOC_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. + #define PIOC_IFSR PIOC_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. + #define PIOC_SODR PIOC_ACCESS(PIO_SODR_OFF) ///< Set output data register address. + #define PIOC_CODR PIOC_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. + #define PIOC_ODSR PIOC_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. + #define PIOC_PDSR PIOC_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. + #define PIOC_IER PIOC_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. + #define PIOC_IDR PIOC_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. + #define PIOC_IMR PIOC_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. + #define PIOC_ISR PIOC_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. + #if PIO_HAS_MULTIDRIVER + #define PIOC_MDER PIOC_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. + #define PIOC_MDDR PIOC_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. + #define PIOC_MDSR PIOC_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. + #endif /* PIO_HAS_MULTIDRIVER */ + #if PIO_HAS_PULLUP + #define PIOC_PUDR PIOC_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. + #define PIOC_PUER PIOC_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. + #define PIOC_PUSR PIOC_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. + #endif /* PIO_HAS_PULLUP */ + #if PIO_HAS_PERIPHERALSELECT + #define PIOC_ASR PIOC_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. + #define PIOC_BSR PIOC_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. + #define PIOC_ABSR PIOC_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. + #endif /* PIO_HAS_PERIPHERALSELECT */ + #if PIO_HAS_OUTPUTWRITEENABLE + #define PIOC_OWER PIOC_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. + #define PIOC_OWDR PIOC_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. + #define PIOC_OWSR PIOC_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. + #endif /* PIO_HAS_OUTPUTWRITEENABLE */ +#endif /* PIOC_BASE */ +/*\}*/ + +#endif /* AT91_PIO_H */ diff --git a/bertos/cpu/arm/io/at91_pit.h b/bertos/cpu/arm/io/at91_pit.h new file mode 100644 index 00000000..9bfc3f98 --- /dev/null +++ b/bertos/cpu/arm/io/at91_pit.h @@ -0,0 +1,115 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 periodic interval timer. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2007 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_PIT_H +#define AT91_PIT_H + +#include +/** + *Periodic Inverval Timer Mode Register + *\{ + */ +#define PIT_MR_OFF 0x00000000 ///< Mode register offset. +#define PIT_MR (*((reg32_t *)(PIT_BASE + PIT_MR_OFF))) ///< Mode register address. + +#define PIV_MASK 0x000FFFFF ///< Periodic interval value mask. +#define PIV_SHIFT 0 ///< Periodic interval value shift. +#define PITEN 24 ///< Periodic interval timer enable. +#define PITIEN 25 ///< Periodic interval timer interrupt enable. +/*\}*/ + +/** + * Periodic Inverval Timer Status Register + *\{ + */ +#define PIT_SR_OFF 0x00000004 ///< Status register offset. +#define PIT_SR (*((reg32_t *)(PIT_BASE + PIT_SR_OFF))) ///< Status register address. + +#define PITS 0 ///< Timer has reached PIV. +/*\}*/ + +/** + * Periodic Inverval Timer Value and Image Registers + *\{ + */ +#define PIVR_OFF 0x00000008 ///< Value register offset. +#define PIVR (*((reg32_t *)(PIT_BASE + PIVR_OFF))) ///< Value register address. + +#define PIIR_OFF 0x0000000C ///< Image register offset. +#define PIIR (*((reg32_t *)(PIT_BASE + PIIR_OFF))) ///< Image register address. +#define CPIV_MASK 0x000FFFFF ///< Current periodic interval value mask. +#define CPIV_SHIFT 0 ///< Current periodic interval value SHIFT. +#define PICNT_MASK 0xFFF00000 ///< Periodic interval counter mask. +#define PICNT_SHIFT 20 ///< Periodic interval counter LSB. +/*\}*/ + +#endif /* AT91_PIT_H */ diff --git a/bertos/cpu/arm/io/at91_pmc.h b/bertos/cpu/arm/io/at91_pmc.h new file mode 100644 index 00000000..b7d5b4f5 --- /dev/null +++ b/bertos/cpu/arm/io/at91_pmc.h @@ -0,0 +1,195 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 power management controller. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_PMC_H +#define AT91_PMC_H + +/** System Clock Enable, Disable and Status Register */ +/*\{*/ +#define PMC_SCER_OFF 0x00000000 ///< System clock enable register offset. +#define PMC_SCER (*((reg32_t *)(PMC_BASE + PMC_SCER_OFF))) ///< System clock enable register address. +#define PMC_SCDR_OFF 0x00000004 ///< System clock disable register offset. +#define PMC_SCDR (*((reg32_t *)(PMC_BASE + PMC_SCDR_OFF))) ///< System clock disable register address. +#define PMC_SCSR_OFF 0x00000008 ///< System clock status register offset. +#define PMC_SCSR (*((reg32_t *)(PMC_BASE + PMC_SCSR_OFF))) ///< System clock status register address. + +#define PMC_PCK 0 ///< Processor clock. +#define PMC_UDP 7 ///< USB device port clock. +#define PMC_PCK0 8 ///< Programmable clock 0 output. +#define PMC_PCK1 9 ///< Programmable clock 1 output. +#define PMC_PCK2 10 ///< Programmable clock 2 output. +/*\}*/ + +/** Peripheral Clock Enable, Disable and Status Register */ +/*\{*/ +#define PMC_PCER_OFF 0x00000010 ///< Peripheral clock enable register offset. +#define PMC_PCER (*((reg32_t *)(PMC_BASE + PMC_PCER_OFF))) ///< Peripheral clock enable register address. +#define PMC_PCDR_OFF 0x00000014 ///< Peripheral clock disable register offset. +#define PMC_PCDR (*((reg32_t *)(PMC_BASE + PMC_PCDR_OFF))) ///< Peripheral clock disable register address. +#define PMC_PCSR_OFF 0x00000018 ///< Peripheral clock status register offset. +#define PMC_PCSR (*((reg32_t *)(PMC_BASE + PMC_PCSR_OFF))) ///< Peripheral clock status register address. +/*\}*/ + +/** Clock Generator Main Oscillator Register */ +/*\{*/ +#define CKGR_MOR_OFF 0x00000020 ///< Main oscillator register offset. +#define CKGR_MOR (*((reg32_t *)(PMC_BASE + CKGR_MOR_OFF))) ///< Main oscillator register address. + +#define CKGR_MOSCEN 0 ///< Main oscillator enable. +#define CKGR_OSCBYPASS 1 ///< Main oscillator bypass. +#define CKGR_OSCOUNT_MASK 0x0000FF00 ///< Main oscillator start-up time mask. +#define CKGR_OSCOUNT_SHIFT 8 ///< Main oscillator start-up time LSB. +/*\}*/ + +/** Clock Generator Main Clock Frequency Register */ +/*\{*/ +#define CKGR_MCFR_OFF 0x00000024 ///< Main clock frequency register offset. +#define CKGR_MCFR (*((reg32_t *)(PMC_BASE + CKGR_MCFR_OFF))) ///< Main clock frequency register address. + +#define CKGR_MAINF_MASK 0x0000FFFF ///< Main clock frequency mask mask. +#define CKGR_MAINRDY 16 ///< Main clock ready. +/*\}*/ + +/** PLL Registers */ +/*\{*/ +#define CKGR_PLLR_OFF 0x0000002C ///< Clock generator PLL register offset. +#define CKGR_PLLR (*((reg32_t *)(PMC_BASE + CKGR_PLLR_OFF))) ///< Clock generator PLL register address. + +#define CKGR_DIV_MASK 0x000000FF ///< Divider. +#define CKGR_DIV_SHIFT 0 ///< Least significant bit of the divider. +#define CKGR_DIV_0 0x00000000 ///< Divider output is 0. +#define CKGR_DIV_BYPASS 0x00000001 ///< Divider is bypassed. +#define CKGR_PLLCOUNT_MASK 0x00003F00 ///< PLL counter mask. +#define CKGR_PLLCOUNT_SHIFT 8 ///< PLL counter LSB. + +#define CKGR_OUT_MASK 0x0000C000 ///< PLL output frequency range. +#define CKGR_OUT_0 0x00000000 ///< Please refer to the PLL datasheet. +#define CKGR_OUT_1 0x00004000 ///< Please refer to the PLL datasheet. +#define CKGR_OUT_2 0x00008000 ///< Please refer to the PLL datasheet. +#define CKGR_OUT_3 0x0000C000 ///< Please refer to the PLL datasheet. +#define CKGR_MUL_MASK 0x07FF0000 ///< PLL multiplier. +#define CKGR_MUL_SHIFT 16 ///< Least significant bit of the PLL multiplier. + +#define CKGR_USBDIV_MASK 0x30000000 ///< Divider for USB clocks. +#define CKGR_USBDIV_1 0x00000000 ///< Divider output is PLL clock output. +#define CKGR_USBDIV_2 0x10000000 ///< Divider output is PLL clock output divided by 2. +#define CKGR_USBDIV_4 0x20000000 ///< Divider output is PLL clock output divided by 4. +/*\}*/ + +/** Master Clock Register */ +/*\{*/ +#define PMC_MCKR_OFF 0x00000030 ///< Master clock register offset. +#define PMC_MCKR (*((reg32_t *)(PMC_BASE + PMC_MCKR_OFF))) ///< Master clock register address. + +#define PMC_PCKR0_OFF 0x00000040 ///< Programmable clock 0 register offset. +#define PMC_PCKR0 (*((reg32_t *)(PMC_BASE + PMC_PCKR0_OFF))) ///< Programmable clock 0 register address. +#define PMC_PCKR1_OFF 0x00000044 ///< Programmable clock 1 register offset. +#define PMC_PCKR1 (*((reg32_t *)(PMC_BASE + PMC_PCKR1_OFF))) ///< Programmable clock 1 register address. +#define PMC_PCKR2_OFF 0x00000048 ///< Programmable clock 2 register offset. +#define PMC_PCKR2 (*((reg32_t *)(PMC_BASE + PMC_PCKR2_OFF))) ///< Programmable clock 2 register address. + +#define PMC_CSS_MASK 0x00000003 ///< Clock selection mask. +#define PMC_CSS_SLOW_CLK 0x00000000 ///< Slow clock selected. +#define PMC_CSS_MAIN_CLK 0x00000001 ///< Main clock selected. +#define PMC_CSS_PLL_CLK 0x00000003 ///< PLL clock selected. + +#define PMC_PRES_MASK 0x0000001C ///< Clock prescaler mask. +#define PMC_PRES_SHIFT 2 ///< Clock prescaler LSB. +#define PMC_PRES_CLK 0x00000000 ///< Selected clock, not divided. +#define PMC_PRES_CLK_2 0x00000004 ///< Selected clock divided by 2. +#define PMC_PRES_CLK_4 0x00000008 ///< Selected clock divided by 4. +#define PMC_PRES_CLK_8 0x0000000C ///< Selected clock divided by 8. +#define PMC_PRES_CLK_16 0x00000010 ///< Selected clock divided by 16. +#define PMC_PRES_CLK_32 0x00000014 ///< Selected clock divided by 32. +#define PMC_PRES_CLK_64 0x00000018 ///< Selected clock divided by 64. +/*\}*/ + +/** Power Management Status and Interrupt Registers */ +/*\{*/ +#define PMC_IER_OFF 0x00000060 ///< Interrupt enable register offset. +#define PMC_IER (*((reg32_t *)(PMC_BASE + PMC_IER_OFF))) ///< Interrupt enable register address. +#define PMC_IDR_OFF 0x00000064 ///< Interrupt disable register offset. +#define PMC_IDR (*((reg32_t *)(PMC_BASE + PMC_IDR_OFF))) ///< Interrupt disable register address. +#define PMC_SR_OFF 0x00000068 ///< Status register offset. +#define PMC_SR (*((reg32_t *)(PMC_BASE + PMC_SR_OFF))) ///< Status register address. +#define PMC_IMR_OFF 0x0000006C ///< Interrupt mask register offset. +#define PMC_IMR (*((reg32_t *)(PMC_BASE + PMC_IMR_OFF))) ///< Interrupt mask register address. + +#define PMC_MOSCS 0 ///< Main oscillator. +#define PMC_LOCK 2 ///< PLL lock. +#define PMC_MCKRDY 3 ///< Master clock ready. +#define PMC_PCKRDY0 8 ///< Programmable clock 0 ready. +#define PMC_PCKRDY1 9 ///< Programmable clock 1 ready. +#define PMC_PCKRDY2 10 ///< Programmable clock 2 ready. +/*\}*/ + +#endif /* AT91_PMC_H */ diff --git a/bertos/cpu/arm/io/at91_pwm.h b/bertos/cpu/arm/io/at91_pwm.h new file mode 100644 index 00000000..f4ae4c3c --- /dev/null +++ b/bertos/cpu/arm/io/at91_pwm.h @@ -0,0 +1,221 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91SAM7 Pulse Width Modulation Controller. + */ + +#ifndef AT91_PWM_H +#define AT91_PWM_H + +/** + * PWM Mode Register. + */ +/*\{*/ +#define PWM_MR_OFF 0x00000000 ///< PWM Mode Register offset. +#define PWM_MR (*((reg32_t *)(PWMC_BASE + PWM_MR_OFF))) ///< PWM Mode Register. +#define PWM_MR_DIVA_MASK 0x000000FF ///< PWM Mode Divide factor A Mask. +#define PWM_MR_DIVA_SHIFT 0 ///< PWM Mode Divide factor A LSB. +#define PWM_MR_DIVB_MASK 0x00FF0000 ///< PWM Mode Divide factor B Mask. +#define PWM_MR_DIVB_SHIFT 16 ///< PWM Mode Divide factor B LSB. + +#define PWM_MR_PREA_MASK 0x00000F00 ///< PWM Mode prescaler A Mask. +#define PWM_MR_PREA_SHIFT 8 ///< PWM Mode prescaler A LSB. +#define PWM_MR_PREB_MASK 0x0F000000 ///< PWM Mode prescaler B Mask. +#define PWM_MR_PREB_SHIFT 24 ///< PWM Mode prescaler B LSB. + +#define PWM_MR_PRE_MCK 0 ///< PWM Mode prescaler set to MCK. +#define PWM_MR_PRE_MCK_DIV2 1 ///< PWM Mode prescaler set to MCK/2. +#define PWM_MR_PRE_MCK_DIV4 2 ///< PWM Mode prescaler set to MCK/4. +#define PWM_MR_PRE_MCK_DIV8 3 ///< PWM Mode prescaler set to MCK/8. +#define PWM_MR_PRE_MCK_DIV16 4 ///< PWM Mode prescaler set to MCK/16. +#define PWM_MR_PRE_MCK_DIV32 5 ///< PWM Mode prescaler set to MCK/32. +#define PWM_MR_PRE_MCK_DIV64 6 ///< PWM Mode prescaler set to MCK/64. +#define PWM_MR_PRE_MCK_DIV128 7 ///< PWM Mode prescaler set to MCK/128. +#define PWM_MR_PRE_MCK_DIV256 8 ///< PWM Mode prescaler set to MCK/256. +#define PWM_MR_PRE_MCK_DIV512 9 ///< PWM Mode prescaler set to MCK/512. +#define PWM_MR_PRE_MCK_DIV1024 10 ///< PWM Mode prescaler set to MCK/1024. +/*\}*/ + +/** + * PWM Channel IDs. + */ +/*\{*/ +#define PWM_CHID_MASK 0x0000000F +#define PWM_CHID0 0 +#define PWM_CHID1 1 +#define PWM_CHID2 2 +#define PWM_CHID3 3 +/*\}*/ + +/** + * PWM Enable Register. + */ +/*\{*/ +#define PWM_ENA_OFF 0x00000004 ///< PWM Enable Register offset. +#define PWM_ENA (*((reg32_t *)(PWMC_BASE + PWM_ENA_OFF))) ///< PWM Enable Register. +/*\}*/ + +/** + * PWM Disable Register. + */ +/*\{*/ +#define PWM_DIS_OFF 0x00000008 ///< PWM Disable Register offset. +#define PWM_DIS (*((reg32_t *)(PWMC_BASE + PWM_DIS_OFF))) ///< PWM Disable Register. +/*\}*/ + +/** + * PWM Status Register. + */ +/*\{*/ +#define PWM_SR_OFF 0x0000000C ///< PWM Status Register offset. +#define PWM_SR (*((reg32_t *)(PWMC_BASE + PWM_SR_OFF))) ///< PWM Status Register. +/*\}*/ + +/** + * PWM Interrupt Enable Register. + */ +/*\{*/ +#define PWM_IER_OFF 0x00000010 ///< PWM Interrupt Enable Register offset. +#define PWM_IER (*((reg32_t *)(PWMC_BASE + PWM_IER_OFF))) ///< PWM Interrupt Enable Register. +/*\}*/ + +/** + * PWM Interrupt Disable Register. + */ +/*\{*/ +#define PWM_IDR_OFF 0x00000014 ///< PWM Interrupt Disable Register offset. +#define PWM_IDR (*((reg32_t *)(PWMC_BASE + PWM_IDR_OFF))) ///< PWM Interrupt Disable Register. +/*\}*/ + +/** + * PWM Interrupt Mask Register. + */ +/*\{*/ +#define PWM_IMR_OFF 0x00000018 ///< PWM Interrupt Mask Register offset. +#define PWM_IMR (*((reg32_t *)(PWMC_BASE + PWM_IMR_OFF))) ///< PWM Interrupt Mask Register. +/*\}*/ + +/** + * PWM Interrupt Status Register. + */ +/*\{*/ +#define PWM_ISR_OFF 0x0000001C ///< PWM Interrupt Status Register offset. +#define PWM_ISR (*((reg32_t *)(PWMC_BASE + PWM_ISR_OFF))) ///< PWM Interrupt Status Register. +/*\}*/ + +#define PWM_CH0_OFF 0x00000200 ///< PWM Channel 0 registers offset. +#define PWM_CH1_OFF 0x00000220 ///< PWM Channel 1 registers offset. +#define PWM_CH2_OFF 0x00000240 ///< PWM Channel 2 registers offset. +#define PWM_CH3_OFF 0x00000260 ///< PWM Channel 3 registers offset. + +/** + * PWM Channel Mode Register. + */ +/*\{*/ +#define PWM_CMR_OFF 0x00000000 ///< PWM Channel Mode Register offset. +#define PWM_CMR0 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Mode Register. +#define PWM_CMR1 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Mode Register. +#define PWM_CMR2 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Mode Register. +#define PWM_CMR3 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Mode Register. + +#define PWM_CPRE_MCK 0 ///< PWM Mode prescaler set to MCK. +#define PWM_CPRE_MCK_DIV2 1 ///< PWM Mode prescaler set to MCK/2. +#define PWM_CPRE_MCK_DIV4 2 ///< PWM Mode prescaler set to MCK/4. +#define PWM_CPRE_MCK_DIV8 3 ///< PWM Mode prescaler set to MCK/8. +#define PWM_CPRE_MCK_DIV16 4 ///< PWM Mode prescaler set to MCK/16. +#define PWM_CPRE_MCK_DIV32 5 ///< PWM Mode prescaler set to MCK/32. +#define PWM_CPRE_MCK_DIV64 6 ///< PWM Mode prescaler set to MCK/64. +#define PWM_CPRE_MCK_DIV128 7 ///< PWM Mode prescaler set to MCK/128. +#define PWM_CPRE_MCK_DIV256 8 ///< PWM Mode prescaler set to MCK/256. +#define PWM_CPRE_MCK_DIV512 9 ///< PWM Mode prescaler set to MCK/512. +#define PWM_CPRE_MCK_DIV1024 10 ///< PWM Mode prescaler set to MCK/1024. +#define PWM_CPRE_CLKA 11 ///< PWM Mode prescaler set to CLKA. +#define PWM_CPRE_CLKB 12 ///< PWM Mode prescaler set to CLKB. + +#define PWM_CALG 8 ///< PWM Mode channel alignment. +#define PWM_CPOL 9 ///< PWM Mode channel polarity. +#define PWM_CPD 10 ///< PWM Mode channel update period. +/*\}*/ + + +/** + * PWM Channel Duty Cycle Register. + */ +/*\{*/ +#define PWM_CDTY_OFF 0x00000004 ///< PWM Channel Duty Cycle Register offset. +#define PWM_CDTY0 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Duty Cycle Register. +#define PWM_CDTY1 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Duty Cycle Register. +#define PWM_CDTY2 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Duty Cycle Register. +#define PWM_CDTY3 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Duty Cycle Register. +/*\}*/ + + +/** + * PWM Channel Period Register. + */ +/*\{*/ +#define PWM_CPRD_OFF 0x00000008 ///< PWM Channel Period Register offset. +#define PWM_CPRD0 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Period Register. +#define PWM_CPRD1 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Period Register. +#define PWM_CPRD2 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Period Register. +#define PWM_CPRD3 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Period Register. +/*\}*/ + + +/** + * PWM Channel Counter Register. + */ +/*\{*/ +#define PWM_CCNT_OFF 0x0000000C ///< PWM Channel Counter Register offset. +#define PWM_CCNT0 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Counter Register. +#define PWM_CCNT1 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Counter Register. +#define PWM_CCNT2 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Counter Register. +#define PWM_CCNT3 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Counter Register. +/*\}*/ + + +/** + * PWM Channel Update Register. + */ +/*\{*/ +#define PWM_CUPD_OFF 0x00000010 ///< PWM Channel Update Register offset. +#define PWM_CUPD0 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Update Register. +#define PWM_CUPD1 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Update Register. +#define PWM_CUPD2 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Update Register. +#define PWM_CUPD3 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Update Register. +/*\}*/ + +#endif /* AT91_PWM_H */ diff --git a/bertos/cpu/arm/io/at91_rstc.h b/bertos/cpu/arm/io/at91_rstc.h new file mode 100644 index 00000000..96be7c34 --- /dev/null +++ b/bertos/cpu/arm/io/at91_rstc.h @@ -0,0 +1,112 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 reset controller. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_RTSC_H +#define AT91_RTSC_H + +/** Reset Controller Control Register */ +/*\{*/ +#define RSTC_CR (*((reg32_t *)(RSTC_BASE + 0x00))) ///< Reset controller control register address. +#define RSTC_PROCRST 0 ///< Processor reset. +#define RSTC_PERRST 2 ///< Peripheral reset. +#define RSTC_EXTRST 3 ///< External reset. +#define RSTC_KEY 0xA5000000 ///< Password. +/*\}*/ + +/** Reset Controller Status Register */ +/*\{*/ +#define RSTC_SR (*((reg32_t *)(RSTC_BASE + 0x04))) ///< Reset controller status register address. +#define RSTC_URSTS 0 ///< User reset status. +#define RSTC_BODSTS 1 ///< Brownout detection status. +#define RSTC_RSTTYP_MASK 0x00000700 ///< Reset type. +#define RSTC_RSTTYP_POWERUP 0x00000000 ///< Power-up reset. +//#define RSTC_RSTTYP_WAKEUP 0x00000100 ///< VDDCORE rising. +#define RSTC_RSTTYP_WATCHDOG 0x00000200 ///< Watchdog reset. +#define RSTC_RSTTYP_SOFTWARE 0x00000300 ///< Software reset. +#define RSTC_RSTTYP_USER 0x00000400 ///< User reset. +#define RSTC_RSTTYP_BROWNOUT 0x00000500 ///< Brownout reset. +#define RSTC_NRSTL 16 ///< NRST pin level. +#define RSTC_SRCMP 17 ///< Software reset command in progress. +/*\}*/ + +/** Reset Controller Mode Register */ +/*\{*/ +#define RSTC_MR (*((reg32_t *)(RSTC_BASE + 0x08))) ///< Reset controller mode register address. +#define RSTC_URSTEN 0 ///< User reset enable. +#define RSTC_URSTIEN 4 ///< User reset interrupt enable. +#define RSTC_ERSTL_MASK 0x00000F00 ///< External reset length. +#define RSTC_ERSTL_SHIFT 8 ///< Least significant bit of external reset length. +#define RSTC_BODIEN 16 ///< Brown-out detection interrupt enable. +/*\}*/ + + +#endif /* AT91_RTSC_H */ diff --git a/bertos/cpu/arm/io/at91_spi.h b/bertos/cpu/arm/io/at91_spi.h new file mode 100644 index 00000000..4766b75d --- /dev/null +++ b/bertos/cpu/arm/io/at91_spi.h @@ -0,0 +1,282 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91SAM7 SPI register definitions. + * This file is based on NUT/OS implementation. See license below. + + */ + +/* + * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + + */ + +#ifndef AT91_SPI_H +#define AT91_SPI_H + +/** + * SPI Control Register + */ +/*\{*/ +#define SPI_CR_OFF 0x00000000 ///< Control register offset. + +#define SPI_SPIEN 0 ///< SPI enable. +#define SPI_SPIDIS 1 ///< SPI disable. +#define SPI_SWRST 7 ///< Software reset. +#define SPI_LASTXFER 24 ///< Last transfer. +/*\}*/ + +/** + * SPI Mode Register + */ +/*\{*/ +#define SPI_MR_OFF 0x00000004 ///< Mode register offset. + +#define SPI_MSTR 0 ///< Master mode. +#define SPI_PS 1 ///< Peripheral select. +#define SPI_PCSDEC 2 ///< Chip select decode. +#define SPI_FDIV 3 ///< Clock selection. +#define SPI_MODFDIS 4 ///< Mode fault detection. +#define SPI_LLB 7 ///< Local loopback enable. +#define SPI_PCS 0x000F0000 ///< Peripheral chip select mask. +#define SPI_PCS_0 0x000E0000 ///< Peripheral chip select 0. +#define SPI_PCS_1 0x000D0000 ///< Peripheral chip select 1. +#define SPI_PCS_2 0x000B0000 ///< Peripheral chip select 2. +#define SPI_PCS_3 0x00070000 ///< Peripheral chip select 3. +#define SPI_PCS_SHIFT 16 ///< Least significant bit of peripheral chip select. +#define SPI_DLYBCS 0xFF000000 ///< Mask for delay between chip selects. +#define SPI_DLYBCS_SHIFT 24 ///< Least significant bit of delay between chip selects. +/*\}*/ + +/** + * SPI Receive Data Register + */ +/*\{*/ +#define SPI_RDR_OFF 0x00000008 ///< Receive data register offset. + +#define SPI_RD 0x0000FFFF ///< Receive data mask. +#define SPI_RD_SHIFT 0 ///< Least significant bit of receive data. +/*\}*/ + +/** + * SPI Transmit Data Register + */ +/*\{*/ +#define SPI_TDR_OFF 0x0000000C ///< Transmit data register offset. + +#define SPI_TD 0x0000FFFF ///< Transmit data mask. +#define SPI_TD_SHIFT 0 ///< Least significant bit of transmit data. +/*\}*/ + +/** + * SPI Status and Interrupt Register + */ +/*\{*/ +#define SPI_SR_OFF 0x00000010 ///< Status register offset. +#define SPI_IER_OFF 0x00000014 ///< Interrupt enable register offset. +#define SPI_IDR_OFF 0x00000018 ///< Interrupt disable register offset. +#define SPI_IMR_OFF 0x0000001C ///< Interrupt mask register offset. + +#define SPI_RDRF 0 ///< Receive data register full. +#define SPI_TDRE 1 ///< Transmit data register empty. +#define SPI_MODF 2 ///< Mode fault error. +#define SPI_OVRES 3 ///< Overrun error status. +#define SPI_ENDRX 4 ///< End of RX buffer. +#define SPI_ENDTX 5 ///< End of TX buffer. +#define SPI_RXBUFF 6 ///< RX buffer full. +#define SPI_TXBUFE 7 ///< TX buffer empty. +#define SPI_NSSR 8 ///< NSS rising. +#define SPI_TXEMPTY 9 ///< Transmission register empty. +#define SPI_SPIENS 16 ///< SPI enable status. +/*\}*/ + +/** + * SPI Chip Select Registers + */ +/*\{*/ +#define SPI_CSR0_OFF 0x00000030 ///< Chip select register 0 offset. +#define SPI_CSR1_OFF 0x00000034 ///< Chip select register 1 offset. +#define SPI_CSR2_OFF 0x00000038 ///< Chip select register 2 offset. +#define SPI_CSR3_OFF 0x0000003C ///< Chip select register 3 offset. + +#define SPI_CPOL 0 ///< Clock polarity. +#define SPI_NCPHA 1 ///< Clock phase. +#define SPI_CSAAT 3 ///< Chip select active after transfer. +#define SPI_BITS 0x000000F0 ///< Bits per transfer mask. +#define SPI_BITS_8 0x00000000 ///< 8 bits per transfer. +#define SPI_BITS_9 0x00000010 ///< 9 bits per transfer. +#define SPI_BITS_10 0x00000020 ///< 10 bits per transfer. +#define SPI_BITS_11 0x00000030 ///< 11 bits per transfer. +#define SPI_BITS_12 0x00000040 ///< 12 bits per transfer. +#define SPI_BITS_13 0x00000050 ///< 13 bits per transfer. +#define SPI_BITS_14 0x00000060 ///< 14 bits per transfer. +#define SPI_BITS_15 0x00000070 ///< 15 bits per transfer. +#define SPI_BITS_16 0x00000080 ///< 16 bits per transfer. +#define SPI_BITS_SHIFT 4 ///< Least significant bit of bits per transfer. +#define SPI_SCBR 0x0000FF00 ///< Serial clock baud rate mask. +#define SPI_SCBR_SHIFT 8 ///< Least significant bit of serial clock baud rate. +#define SPI_DLYBS 0x00FF0000 ///< Delay before SPCK mask. +#define SPI_DLYBS_SHIFT 16 ///< Least significant bit of delay before SPCK. +#define SPI_DLYBCT 0xFF000000 ///< Delay between consecutive transfers mask. +#define SPI_DLYBCT_SHIFT 24 ///< Least significant bit of delay between consecutive transfers. +/*\}*/ + +/** + * Single SPI Register Addresses + */ +/*\{*/ +#if defined(SPI_BASE) + #define SPI0_BASE SPI_BASE + #define SPI_CR SPI0_CR ///< SPI Control Register Write-only. + #define SPI_MR SPI0_MR ///< SPI Mode Register Read/Write Reset=0x0. + #define SPI_RDR SPI0_RDR ///< SPI Receive Data Register Read-only Reset=0x0. + #define SPI_TDR SPI0_TDR ///< SPI Transmit Data Register Write-only . + #define SPI_SR SPI0_SR ///< SPI Status Register Read-only Reset=0x000000F0. + #define SPI_IER SPI0_IER ///< SPI Interrupt Enable Register Write-only. + #define SPI_IDR SPI0_IDR ///< SPI Interrupt Disable Register Write-only. + #define SPI_IMR SPI0_IMR ///< SPI Interrupt Mask Register Read-only Reset=0x0. + #define SPI_CSR0 SPI0_CSR0 ///< SPI Chip Select Register 0 Read/Write Reset=0x0. + #define SPI_CSR1 SPI0_CSR1 ///< SPI Chip Select Register 1 Read/Write Reset=0x0. + #define SPI_CSR2 SPI0_CSR2 ///< SPI Chip Select Register 2 Read/Write Reset=0x0. + #define SPI_CSR3 SPI0_CSR3 ///< SPI Chip Select Register 3 Read/Write Reset=0x0. + #if defined(SPI_HAS_PDC) + #define SPI_RPR SPI0_RPR ///< PDC channel 0 receive pointer register. + #define SPI_RCR SPI0_RCR ///< PDC channel 0 receive counter register. + #define SPI_TPR SPI0_TPR ///< PDC channel 0 transmit pointer register. + #define SPI_TCR SPI0_TCR ///< PDC channel 0 transmit counter register. + #define SPI_RNPR SPI0_RNPR ///< PDC channel 0 receive next pointer register. + #define SPI_RNCR SPI0_RNCR ///< PDC channel 0 receive next counter register. + #define SPI_TNPR SPI0_TNPR ///< PDC channel 0 transmit next pointer register. + #define SPI_TNCR SPI0_TNCR ///< PDC channel 0 transmit next counter register. + #define SPI_PTCR SPI0_PTCR ///< PDC channel 0 transfer control register. + #define SPI_PTSR SPI0_PTSR ///< PDC channel 0 transfer status register. + #endif /* SPI_HAS_PDC */ +#endif /* SPI_BASE */ +/*\}*/ + +/** + * SPI 0 Register Addresses + */ +/*\{*/ +#if defined(SPI0_BASE) + #define SPI0_CR (*((reg32_t *)(SPI0_BASE + SPI_CR_OFF))) ///< SPI Control Register Write-only. + #define SPI0_MR (*((reg32_t *)(SPI0_BASE + SPI_MR_OFF))) ///< SPI Mode Register Read/Write Reset=0x0. + #define SPI0_RDR (*((reg32_t *)(SPI0_BASE + SPI_RDR_OFF))) ///< SPI Receive Data Register Read-only Reset=0x0. + #define SPI0_TDR (*((reg32_t *)(SPI0_BASE + SPI_TDR_OFF))) ///< SPI Transmit Data Register Write-only . + #define SPI0_SR (*((reg32_t *)(SPI0_BASE + SPI_SR_OFF))) ///< SPI Status Register Read-only Reset=0x000000F0. + #define SPI0_IER (*((reg32_t *)(SPI0_BASE + SPI_IER_OFF))) ///< SPI Interrupt Enable Register Write-only. + #define SPI0_IDR (*((reg32_t *)(SPI0_BASE + SPI_IDR_OFF))) ///< SPI Interrupt Disable Register Write-only. + #define SPI0_IMR (*((reg32_t *)(SPI0_BASE + SPI_IMR_OFF))) ///< SPI Interrupt Mask Register Read-only Reset=0x0. + #define SPI0_CSR0 (*((reg32_t *)(SPI0_BASE + SPI_CSR0_OFF))) ///< SPI Chip Select Register 0 Read/Write Reset=0x0. + #define SPI0_CSR1 (*((reg32_t *)(SPI0_BASE + SPI_CSR1_OFF))) ///< SPI Chip Select Register 1 Read/Write Reset=0x0. + #define SPI0_CSR2 (*((reg32_t *)(SPI0_BASE + SPI_CSR2_OFF))) ///< SPI Chip Select Register 2 Read/Write Reset=0x0. + #define SPI0_CSR3 (*((reg32_t *)(SPI0_BASE + SPI_CSR3_OFF))) ///< SPI Chip Select Register 3 Read/Write Reset=0x0. + #if defined(SPI_HAS_PDC) + #define SPI0_RPR (*((reg32_t *)(SPI0_BASE + PERIPH_RPR_OFF)) ///< PDC channel 0 receive pointer register. + #define SPI0_RCR (*((reg32_t *)(SPI0_BASE + PERIPH_RCR_OFF)) ///< PDC channel 0 receive counter register. + #define SPI0_TPR (*((reg32_t *)(SPI0_BASE + PERIPH_TPR_OFF)) ///< PDC channel 0 transmit pointer register. + #define SPI0_TCR (*((reg32_t *)(SPI0_BASE + PERIPH_TCR_OFF)) ///< PDC channel 0 transmit counter register. + #define SPI0_RNPR (*((reg32_t *)(SPI0_BASE + PERIPH_RNPR_OFF)) ///< PDC channel 0 receive next pointer register. + #define SPI0_RNCR (*((reg32_t *)(SPI0_BASE + PERIPH_RNCR_OFF)) ///< PDC channel 0 receive next counter register. + #define SPI0_TNPR (*((reg32_t *)(SPI0_BASE + PERIPH_TNPR_OFF)) ///< PDC channel 0 transmit next pointer register. + #define SPI0_TNCR (*((reg32_t *)(SPI0_BASE + PERIPH_TNCR_OFF)) ///< PDC channel 0 transmit next counter register. + #define SPI0_PTCR (*((reg32_t *)(SPI0_BASE + PERIPH_PTCR_OFF)) ///< PDC channel 0 transfer control register. + #define SPI0_PTSR (*((reg32_t *)(SPI0_BASE + PERIPH_PTSR_OFF)) ///< PDC channel 0 transfer status register. + #endif /* SPI_HAS_PDC */ +#endif /* SPI0_BASE */ +/*\}*/ + +/** + * SPI 1 Register Addresses + */ +/*\{*/ +#if defined(SPI1_BASE) + #define SPI1_CR (*((reg32_t *)(SPI1_BASE + SPI_CR_OFF))) ///< SPI Control Register Write-only. + #define SPI1_MR (*((reg32_t *)(SPI1_BASE + SPI_MR_OFF))) ///< SPI Mode Register Read/Write Reset=0x0. + #define SPI1_RDR (*((reg32_t *)(SPI1_BASE + SPI_RDR_OFF))) ///< SPI Receive Data Register Read-only Reset=0x0. + #define SPI1_TDR (*((reg32_t *)(SPI1_BASE + SPI_TDR_OFF))) ///< SPI Transmit Data Register Write-only . + #define SPI1_SR (*((reg32_t *)(SPI1_BASE + SPI_SR_OFF))) ///< SPI Status Register Read-only Reset=0x000000F0. + #define SPI1_IER (*((reg32_t *)(SPI1_BASE + SPI_IER_OFF))) ///< SPI Interrupt Enable Register Write-only. + #define SPI1_IDR (*((reg32_t *)(SPI1_BASE + SPI_IDR_OFF))) ///< SPI Interrupt Disable Register Write-only. + #define SPI1_IMR (*((reg32_t *)(SPI1_BASE + SPI_IMR_OFF))) ///< SPI Interrupt Mask Register Read-only Reset=0x0. + #define SPI1_CSR0 (*((reg32_t *)(SPI1_BASE + SPI_CSR0_OFF))) ///< SPI Chip Select Register 0 Read/Write Reset=0x0. + #define SPI1_CSR1 (*((reg32_t *)(SPI1_BASE + SPI_CSR1_OFF))) ///< SPI Chip Select Register 1 Read/Write Reset=0x0. + #define SPI1_CSR2 (*((reg32_t *)(SPI1_BASE + SPI_CSR2_OFF))) ///< SPI Chip Select Register 2 Read/Write Reset=0x0. + #define SPI1_CSR3 (*((reg32_t *)(SPI1_BASE + SPI_CSR3_OFF))) ///< SPI Chip Select Register 3 Read/Write Reset=0x0. + #if defined(SPI_HAS_PDC) + #define SPI1_RPR (*((reg32_t *)(SPI1_BASE + PERIPH_RPR_OFF))) ///< PDC channel 1 receive pointer register. + #define SPI1_RCR (*((reg32_t *)(SPI1_BASE + PERIPH_RCR_OFF))) ///< PDC channel 1 receive counter register. + #define SPI1_TPR (*((reg32_t *)(SPI1_BASE + PERIPH_TPR_OFF))) ///< PDC channel 1 transmit pointer register. + #define SPI1_TCR (*((reg32_t *)(SPI1_BASE + PERIPH_TCR_OFF))) ///< PDC channel 1 transmit counter register. + #define SPI1_RNPR (*((reg32_t *)(SPI1_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 1 receive next pointer register. + #define SPI1_RNCR (*((reg32_t *)(SPI1_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 1 receive next counter register. + #define SPI1_TNPR (*((reg32_t *)(SPI1_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 1 transmit next pointer register. + #define SPI1_TNCR (*((reg32_t *)(SPI1_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 1 transmit next counter register. + #define SPI1_PTCR (*((reg32_t *)(SPI1_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 1 transfer control register. + #define SPI1_PTSR (*((reg32_t *)(SPI1_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 1 transfer status register. + #endif /* SPI_HAS_PDC */ +#endif /* SPI1_BASE */ +/*\}*/ + +#endif /* AT91_SPI_H */ diff --git a/bertos/cpu/arm/io/at91_tc.h b/bertos/cpu/arm/io/at91_tc.h new file mode 100644 index 00000000..080d5881 --- /dev/null +++ b/bertos/cpu/arm/io/at91_tc.h @@ -0,0 +1,321 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Daniele Basile + * + * AT91SAM7 Conunter timer definition. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_TC_H +#define AT91_TC_H + + +/** + * Timer Counter Control Register + */ +#define TC_TC0_OFF 0x00000000 ///< Channel 0 control register offset. +#define TC_TC1_OFF 0x00000040 ///< Channel 1 control register offset. +#define TC_TC2_OFF 0x00000080 ///< Channel 2 control register offset. +#define TC0_CCR (*((reg32_t *)(TC_BASE + TC_TC0_OFF))) ///< Channel 0 control register address. +#define TC1_CCR (*((reg32_t *)(TC_BASE + TC_TC1_OFF))) ///< Channel 1 control register address. +#define TC2_CCR (*((reg32_t *)(TC_BASE + TC_TC2_OFF))) ///< Channel 2 control register address. +#define TC_CLKEN 0 ///< Clock enable command. +#define TC_CLKDIS 1 ///< Clock disable command. +#define TC_SWTRG 2 ///< Software trigger command. + +/** + * Timer Counter Channel Mode Register + */ +#define TC_CMR_OFF 0x00000004 ///< Mode register offset. +#define TC0_CMR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_CMR_OFF))) ///< Channel 0 mode register address. +#define TC1_CMR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_CMR_OFF))) ///< Channel 1 mode register address. +#define TC2_CMR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_CMR_OFF))) ///< Channel 2 mode register address. + +#define TC_CLKS_MASK 0x00000007 ///< Clock selection mask. +#define TC_CLKS_MCK2 0x00000000 ///< Selects MCK / 2. +#define TC_CLKS_MCK8 0x00000001 ///< Selects MCK / 8. +#define TC_CLKS_MCK32 0x00000002 ///< Selects MCK / 32. +#define TC_CLKS_MCK128 0x00000003 ///< Selects MCK / 128. +#define TC_CLKS_MCK1024 0x00000004 ///< Selects MCK / 1024. +#define TC_CLKS_XC0 0x00000005 ///< Selects external clock 0. +#define TC_CLKS_XC1 0x00000006 ///< Selects external clock 1. +#define TC_CLKS_XC2 0x00000007 ///< Selects external clock 2. + +#define TC_CLKI 3 ///< Increments on falling edge. + +#define TC_BURST_MASK 0x00000030 ///< Burst signal selection mask. +#define TC_BURST_NONE 0x00000000 ///< Clock is not gated by an external signal. +#define TC_BUSRT_XC0 0x00000010 ///< ANDed with external clock 0. +#define TC_BURST_XC1 0x00000020 ///< ANDed with external clock 1. +#define TC_BURST_XC2 0x00000030 ///< ANDed with external clock 2. + + + +#define TC_WAVE 15 ///< Selects waveform mode. +//To select capture mode you must set TC_WAVE bit to 0. +//#define TC_CAPT 15 ///< Selects capture mode. + +/** + * Capture Mode + */ +#define TC_CPCTRG 14 ///< RC Compare Enable Trigger Enable. +#define TC_LDBSTOP 6 ///< Counter clock stopped on RB loading. +#define TC_LDBDIS 7 ///< Counter clock disabled on RB loading. + +#define TC_ETRGEDG_MASK 0x00000300 ///< External trigger edge selection mask. +#define TC_ETRGEDG_RISING_EDGE 0x00000100 ///< Trigger on external rising edge. +#define TC_ETRGEDG_FALLING_EDGE 0x00000200 ///< Trigger on external falling edge. +#define TC_ETRGEDG_BOTH_EDGE 0x00000300 ///< Trigger on both external edges. + +#define TC_ABETRG_MASK 0x00000400 ///< TIOA or TIOB external trigger selection mask. +#define TC_ABETRG_TIOA 10 ///< TIOA used as an external trigger. +//To use external trigger TIOB you must set TC_ABETRG_TIOA bit to 0. +//#define TC_ABETRG_TIOB 10 ///< TIOB used as an external trigger. + + +#define TC_LDRA_MASK 0x00030000 ///< RA loading selection mask. +#define TC_LDRA_RISING_EDGE 0x00010000 ///< Load RA on rising edge of TIOA. +#define TC_LDRA_FALLING_EDGE 0x00020000 ///< Load RA on falling edge of TIOA. +#define TC_LDRA_BOTH_EDGE 0x00030000 ///< Load RA on any edge of TIOA. + +#define TC_LDRB_MASK 0x000C0000 ///< RB loading selection mask. +#define TC_LDRB_RISING_EDGE 0x00040000 ///< Load RB on rising edge of TIOA. +#define TC_LDRB_FALLING_EDGE 0x00080000 ///< Load RB on falling edge of TIOA. +#define TC_LDRB_BOTH_EDGE 0x000C0000 ///< Load RB on any edge of TIOA. + + +/** + * Waveform Mode + */ +#define TC_CPCSTOP 6 ///< Counter clock stopped on RC compare. +#define TC_CPCDIS 7 ///< Counter clock disabled on RC compare. + +#define TC_EEVTEDG_MASK 0x00000300 ///< External event edge selection mask. +#define TC_EEVTEDG_RISING_EDGE 0x00000100 ///< External event on rising edge.. +#define TC_EEVTEDG_FALLING_EDGE 0x00000200 ///< External event on falling edge.. +#define TC_EEVTEDG_BOTH_EDGE 0x00000300 ///< External event on any edge.. + +#define TC_EEVT_MASK 0x00000C00 ///< External event selection mask. +#define TC_EEVT_TIOB 0x00000000 ///< TIOB selected as external event. +#define TC_EEVT_XC0 0x00000400 ///< XC0 selected as external event. +#define TC_EEVT_XC1 0x00000800 ///< XC1 selected as external event. +#define TC_EEVT_XC2 0x00000C00 ///< XC2 selected as external event. + +#define TC_ENETRG 12 ///< External event trigger enable. + +#define TC_WAVSEL_MASK 0x00006000 ///< Waveform selection mask. +#define TC_WAVSEL_UP_RC 0x00000000 ///< UP mode whitout automatic trigger on RC compare. +#define TC_WAVSEL_UP_RC_TRG 0x00004000 ///< UP mode whit automatic trigger on RC compare. +#define TC_WAVSEL_UPDOWN_RC 0x00002000 ///< UPDOWN mode whitout automatic trigger on RC compare. +#define TC_WAVSEL_UPDOWN_RC_TRG 0x00003000 ///< UPDOWN mode whit automatic trigger on RC compare. + + +#define TC_ACPA_MASK 0x00030000 ///< Masks RA compare effect on TIOA. +#define TC_ACPA_SET_OUTPUT 0x00010000 ///< RA compare sets TIOA. +#define TC_ACPA_CLEAR_OUTPUT 0x00020000 ///< RA compare clears TIOA. +#define TC_ACPA_TOGGLE_OUTPUT 0x00030000 ///< RA compare toggles TIOA. + +#define TC_ACPC_MASK 0x000C0000 ///< Masks RC compare effect on TIOA. +#define TC_ACPC_SET_OUTPUT 0x00040000 ///< RC compare sets TIOA. +#define TC_ACPC_CLEAR_OUTPUT 0x00080000 ///< RC compare clears TIOA. +#define TC_ACPC_TOGGLE_OUTPUT 0x000C0000 ///< RC compare toggles TIOA. + +#define TC_AEEVT_MASK 0x00300000 ///< Masks external event effect on TIOA. +#define TC_AEEVT_SET_OUTPUT 0x00100000 ///< External event sets TIOA. +#define TC_AEEVT_CLEAR_OUTPUT 0x00200000 ///< External event clears TIOA. +#define TC_AEEVT_TOGGLE_OUTPUT 0x00300000 ///< External event toggles TIOA. + +#define TC_ASWTRG_MASK 0x00C00000 ///< Masks software trigger effect on TIOA. +#define TC_ASWTRG_SET_OUTPUT 0x00400000 ///< Software trigger sets TIOA. +#define TC_ASWTRG_CLEAR_OUTPUT 0x00800000 ///< Software trigger clears TIOA. +#define TC_ASWTRG_TOGGLE_OUTPUT 0x00C00000 ///< Software trigger toggles TIOA. + +#define TC_BCPB_MASK 0x03000000 ///< Masks RB compare effect on TIOB. +#define TC_BCPB_SET_OUTPUT 0x01000000 ///< RB compare sets TIOB. +#define TC_BCPB_CLEAR_OUTPUT 0x02000000 ///< RB compare clears TIOB. +#define TC_BCPB_TOGGLE_OUTPUT 0x03000000 ///< RB compare toggles TIOB. + +#define TC_BCPC_MASK 0x0C000000 ///< Masks RC compare effect on TIOB. +#define TC_BCPC_SET_OUTPUT 0x04000000 ///< RC compare sets TIOB. +#define TC_BCPC_CLEAR_OUTPUT 0x08000000 ///< RC compare clears TIOB. +#define TC_BCPC_TOGGLE_OUTPUT 0x0C000000 ///< RC compare toggles TIOB. + +#define TC_BEEVT_MASK 0x30000000 ///< Masks external event effect on TIOB. +#define TC_BEEVT_SET_OUTPUT 0x10000000 ///< External event sets TIOB. +#define TC_BEEVT_CLEAR_OUTPUT 0x20000000 ///< External event clears TIOB. +#define TC_BEEVT_TOGGLE_OUTPUT 0x30000000 ///< External event toggles TIOB. + +#define TC_BSWTRG_MASK 0xC0000000 ///< Masks software trigger effect on TIOB. +#define TC_BSWTRG_SET_OUTPUT 0x40000000 ///< Software trigger sets TIOB. +#define TC_BSWTRG_CLEAR_OUTPUT 0x80000000 ///< Software trigger clears TIOB. +#define TC_BSWTRG_TOGGLE_OUTPUT 0xC0000000 ///< Software trigger toggles TIOB. + +/** + * Counter Value Register + */ +#define TC_CV_OFF 0x00000010 ///< Counter register value offset. +#define TC0_CV (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_CV_OFF))) ///< Counter 0 value. +#define TC1_CV (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_CV_OFF))) ///< Counter 1 value. +#define TC2_CV (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_CV_OFF))) ///< Counter 2 value. + +/** + * Timer Counter Register A + */ +#define TC_RA_OFF 0x00000014 ///< Register A offset. +#define TC0_RA (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RA_OFF))) ///< Channel 0 register A. +#define TC1_RA (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RA_OFF))) ///< Channel 1 register A. +#define TC2_RA (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RA_OFF))) ///< Channel 2 register A. + + +/** + * Timer Counter Register B + */ +#define TC_RB_OFF 0x00000018 ///< Register B offset. +#define TC0_RB (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RB_OFF))) ///< Channel 0 register B. +#define TC1_RB (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RB_OFF))) ///< Channel 1 register B. +#define TC2_RB (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RB_OFF))) ///< Channel 2 register B. + + +/** + * Timer Counter Register C + */ +#define TC_RC_OFF 0x0000001C ///< Register C offset. +#define TC0_RC (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RC_OFF))) ///< Channel 0 register C. +#define TC1_RC (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RC_OFF))) ///< Channel 1 register C. +#define TC2_RC (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RC_OFF))) ///< Channel 2 register C. + + + +/** + * Timer Counter Status and Interrupt Registers + */ +#define TC_SR_OFF 0x00000020 ///< Status Register offset. +#define TC0_SR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_SR_OFF))) ///< Status register address. +#define TC1_SR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_SR_OFF))) ///< Status register address. +#define TC2_SR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_SR_OFF))) ///< Status register address. + +#define TC_IER_OFF 0x00000024 ///< Interrupt Enable Register offset. +#define TC0_IER (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IER_OFF))) ///< Channel 0 interrupt enable register address. +#define TC1_IER (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IER_OFF))) ///< Channel 1 interrupt enable register address. +#define TC2_IER (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IER_OFF))) ///< Channel 2 interrupt enable register address. + +#define TC_IDR_OFF 0x00000028 ///< Interrupt Disable Register offset. +#define TC0_IDR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IDR_OFF))) ///< Channel 0 interrupt disable register address. +#define TC1_IDR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IDR_OFF))) ///< Channel 1 interrupt disable register address. +#define TC2_IDR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IDR_OFF))) ///< Channel 2 interrupt disable register address. + +#define TC_IMR_OFF 0x0000002C ///< Interrupt Mask Register offset. +#define TC0_IMR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IMR_OFF))) ///< Channel 0 interrupt mask register address. +#define TC1_IMR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IMR_OFF))) ///< Channel 1 interrupt mask register address. +#define TC2_IMR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IMR_OFF))) ///< Channel 2 interrupt mask register address. + +#define TC_COVFS 0 ///< Counter overflow flag. +#define TC_LOVRS 1 ///< Load overrun flag. +#define TC_CPAS 2 ///< RA compare flag. +#define TC_CPBS 3 ///< RB compare flag. +#define TC_CPCS 4 ///< RC compare flag. +#define TC_LDRAS 5 ///< RA loading flag. +#define TC_LDRBS 6 ///< RB loading flag. +#define TC_ETRGS 7 ///< External trigger flag. +#define TC_CLKSTA 16 ///< Clock enable flag. +#define TC_MTIOA 17 ///< TIOA flag. +#define TC_MTIOB 18 ///< TIOB flag. + + +/** + * Timer Counter Block Control Register + */ +#define TC_BCR_OFF 0x000000C0 ///< Block control register offset. +#define TC_BCR (*((reg32_t *)(TC_BASE + TC_BCR_OFF))) ///< Block control register address. +#define TC_SYNC 0 ///< Synchronisation trigger + + +/** + * Timer Counter Block Mode Register + */ +#define TC_BMR_OFF 0x000000C4 ///< Block mode register offset. +#define TC_BMR (*((reg32_t *)(TC_BASE + TC_BMR_OFF))) ///< Block mode register address. +#define TC_TC0XC0S 0x00000003 ///< External clock signal 0 selection mask. +#define TC_TCLK0XC0 0x00000000 ///< Selects TCLK0. +#define TC_NONEXC0 0x00000001 ///< None selected. +#define TC_TIOA1XC0 0x00000002 ///< Selects TIOA1. +#define TC_TIOA2XC0 0x00000003 ///< Selects TIOA2. + +#define TC_TC1XC1S 0x0000000C ///< External clock signal 1 selection mask. +#define TC_TCLK1XC1 0x00000000 ///< Selects TCLK1. +#define TC_NONEXC1 0x00000004 ///< None selected. +#define TC_TIOA0XC1 0x00000008 ///< Selects TIOA0. +#define TC_TIOA2XC1 0x0000000C ///< Selects TIOA2. + +#define TC_TC2XC2S 0x00000030 ///< External clock signal 2 selection mask. +#define TC_TCLK2XC2 0x00000000 ///< Selects TCLK2. +#define TC_NONEXC2 0x00000010 ///< None selected. +#define TC_TIOA0XC2 0x00000020 ///< Selects TIOA0. +#define TC_TIOA1XC2 0x00000030 ///< Selects TIOA1. + + +#endif /* AT91_TC_H */ diff --git a/bertos/cpu/arm/io/at91_twi.h b/bertos/cpu/arm/io/at91_twi.h new file mode 100644 index 00000000..1d7be6ab --- /dev/null +++ b/bertos/cpu/arm/io/at91_twi.h @@ -0,0 +1,191 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91SAM7 Two wire interface. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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 (*((reg32_t *)(INCLUDING NEGLIGENCE OR OTHERWISE))) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_TWI_H +#define AT91_TWI_H + + +/** + * TWI Control Register. + * \{ + */ +#define TWI_CR_OFF 0x00000000 ///< Control register offset. +#define TWI_CR (*((reg32_t *)(TWI_BASE + TWI_CR_OFF))) ///< Control register address. +#define TWI_START 0 ///< Send start condition. +#define TWI_STOP 1 ///< Send stop condition. +#define TWI_MSEN 2 ///< Enable master mode. +#define TWI_MSDIS 3 ///< Disable master mode. +/* +#define TWI_SVEN 4 ///< Enable slave mode. +#define TWI_SVDIS 5 ///< Disable slave mode. +*/ +#define TWI_SWRST 7 ///< Software reset. +/*\}*/ + +/** + * TWI Master Mode Register. + * \{ + */ +#define TWI_MMR_OFF 0x00000004 ///< Master mode register offset. +#define TWI_MMR (*((reg32_t *)(TWI_BASE + TWI_MMR_OFF))) ///< Master mode register address. +#define TWI_IADRSZ_SHIFT 8 ///< Internal device address size shift. +#define TWI_IADRSZ 0x00000300 ///< Internal device address size mask. +#define TWI_IADRSZ_NONE 0x00000000 ///< No internal device address. +#define TWI_IADRSZ_1BYTE 0x00000100 ///< One byte internal device address. +#define TWI_IADRSZ_2BYTE 0x00000200 ///< Two byte internal device address. +#define TWI_IADRSZ_3BYTE 0x00000300 ///< Three byte internal device address. +#define TWI_MREAD 12 ///< Master read direction. +#define TWI_DADR 0x007F0000 ///< Device address mask. +#define TWI_DADR_SHIFT 16 ///< Device address LSB. +/*\}*/ + +/** + * TWI Internal Address Register. + * \{ + */ +#define TWI_IADR_OFF 0x0000000C ///< Internal address register offset. +#define TWI_IADR (*((reg32_t *)(TWI_BASE + TWI_IADR_OFF))) ///< Internal address register address. +#define TWI_IADR_MASK 0x00FFFFFF ///< Internal address mask. +#define TWI_IADR_SHIFT 0 ///< Internal address LSB. +/*\}*/ + +/** + * TWI Clock Waveform Generator Register. + * \{ + */ +#define TWI_CWGR_OFF 0x00000010 ///< Clock waveform generator register offset. +#define TWI_CWGR (*((reg32_t *)(TWI_BASE + TWI_CWGR_OFF))) ///< Clock waveform generator register address. +#define TWI_CLDIV 0x000000FF ///< Clock low divider mask. +#define TWI_CLDIV_SHIFT 0 ///< Clock low divider LSB. +#define TWI_CHDIV 0x0000FF00 ///< Clock high divider mask. +#define TWI_CHDIV_SHIFT 8 ///< Clock high divider LSB. +#define TWI_CKDIV 0x00070000 ///< Clock divider mask. +#define TWI_CKDIV_SHIFT 16 ///< Clock divider LSB. +/*\}*/ + +/** + * TWI Status and Interrupt Registers. + * \{ + */ +#define TWI_SR_OFF 0x00000020 ///< Status register offset. +#define TWI_SR (*((reg32_t *)(TWI_BASE + TWI_SR_OFF))) ///< Status register address. + +#define TWI_IER_OFF 0x00000024 ///< Interrupt enable register offset. +#define TWI_IER (*((reg32_t *)(TWI_BASE + TWI_IER_OFF))) ///< Interrupt enable register address. + +#define TWI_IDR_OFF 0x00000028 ///< Interrupt disable register offset. +#define TWI_IDR (*((reg32_t *)(TWI_BASE + TWI_IDR_OFF))) ///< Interrupt disable register address. + +#define TWI_IMR_OFF 0x0000002C ///< Interrupt mask register offset. +#define TWI_IMR (*((reg32_t *)(TWI_BASE + TWI_IMR_OFF))) ///< Interrupt mask register address. + +#define TWI_TXCOMP 0 ///< Transmission completed. +#define TWI_RXRDY 1 ///< Receive holding register ready. +#define TWI_TXRDY 2 ///< Transmit holding register ready. + +/* +#define TWI_SVREAD 0x00000008 ///< Slave read. +#define TWI_SVACC 0x00000010 ///< Slave access. +#define TWI_GACC 0x00000020 ///< General call access. +*/ + +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 +#define TWI_OVRE 6 ///< Overrun error. +#define TWI_UNRE 7 ///< Underrun error. +#endif + +#define TWI_NACK 8 ///< Not acknowledged. +/* +#define TWI_ARBLST 0x00000200 ///< Arbitration lost. +#define TWI_SCLWS 0x00000400 ///< Clock wait state. +#define TWI_EOSACC 0x00000800 ///< End of slave access. +*/ +/*\}*/ + +/** + * TWI Receive Holding Register. + * \{ + */ +#define TWI_RHR_OFF 0x00000030 ///< Receive holding register offset. +#define TWI_RHR (*((reg32_t *)(TWI_BASE + TWI_RHR_OFF))) ///< Receive holding register address. +/*\}*/ + +/** + * TWI Transmit Holding Register. + * \{ + */ +#define TWI_THR_OFF 0x00000034 ///< Transmit holding register offset. +#define TWI_THR (*((reg32_t *)(TWI_BASE + TWI_THR_OFF))) ///< Transmit holding register address. +/*\}*/ + + +#endif /* AT91_TWI_H */ diff --git a/bertos/cpu/arm/io/at91_us.h b/bertos/cpu/arm/io/at91_us.h new file mode 100644 index 00000000..20541a76 --- /dev/null +++ b/bertos/cpu/arm/io/at91_us.h @@ -0,0 +1,344 @@ +/** + * \file + * + * + * \version $Id: at91_us.h 20544 2008-02-14 12:15:57Z batt $ + * + * \author Daniele Basile + * + * AT91 UART User interface. + * This file is based on NUT/OS implementation. See license below. + */ +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_US_H +#define AT91_US_H + +/** + * USART Control Register + */ +/*\{*/ +#define US_CR_OFF 0x00000000 ///< USART control register offset. +#define US0_CR (*((reg32_t *)(USART0_BASE + US_CR_OFF))) ///< Channel 0 control register address. +#define US1_CR (*((reg32_t *)(USART1_BASE + US_CR_OFF))) ///< Channel 1 control register address. +#define US_RSTRX 2 ///< Reset receiver. +#define US_RSTTX 3 ///< Reset transmitter. +#define US_RXEN 4 ///< Receiver enable. +#define US_RXDIS 5 ///< Receiver disable. +#define US_TXEN 6 ///< Transmitter enable. +#define US_TXDIS 7 ///< Transmitter disable. +#define US_RSTSTA 8 ///< Reset status bits. +#define US_STTBRK 9 ///< Start break. +#define US_STPBRK 10 ///< Stop break. +#define US_STTTO 11 ///< Start timeout. +#define US_SENDA 12 ///< Send next byte with address bit set. +#define US_RSTIT 13 ///< Reset interations. +#define US_RSTNAK 14 ///< Reset non acknowledge. +#define US_RETTO 15 ///< Rearm time out. +#define US_DTREN 16 ///< Data terminal ready enable. +#define US_DTRDIS 17 ///< Data terminal ready disable. +#define US_RTSEN 18 ///< Request to send enable. +#define US_RTSDIS 19 ///< Request to send disable. +/*\}*/ + +/** + * Mode Register + */ +/*\{*/ +#define US_MR_OFF 0x00000004 ///< USART mode register offset. +#define US0_MR (*((reg32_t *)(USART0_BASE + US_MR_OFF))) ///< Channel 0 mode register address. +#define US1_MR (*((reg32_t *)(USART1_BASE + US_MR_OFF))) ///< Channel 1 mode register address. + +#define US_USART_MODE_MASK 0x0000000F ///< USART mode mask. +#define US_USART_MODE_NORMA 0x00000000 ///< Normal. +#define US_USART_MODE_RS485 0x00000001 ///< RS485. +#define US_USART_MODE_HW_HDSH 0x00000002 ///< Hardware handshaking. +#define US_USART_MODE_MODEM 0x00000003 ///< Modem. +#define US_USART_MODE_ISO7816T0 0x00000004 ///< ISO7816 protocol: T=0. +#define US_USART_MODE_ISO7816T1 0x00000006 ///< ISO7816 protocol: T=1. +#define US_USART_MODE_IRDA 0x00000008 ///< IrDA. + +#define US_CLKS_MASK 0x00000030 ///< Clock selection mask. +#define US_CLKS_MCK 0x00000000 ///< Master clock. +#define US_CLKS_MCK8 0x00000010 ///< Master clock divided by 8. +#define US_CLKS_SCK 0x00000020 ///< External clock. +#define US_CLKS_SLCK 0x00000030 ///< Slow clock. + +#define US_CHRL_MASK 0x000000C0 ///< Masks data length. +#define US_CHRL_5 0x00000000 ///< 5 data bits. +#define US_CHRL_6 0x00000040 ///< 6 data bits. +#define US_CHRL_7 0x00000080 ///< 7 data bits. +#define US_CHRL_8 0x000000C0 ///< 8 data bits. + +#define US_SYNC 8 ///< Synchronous mode enable. + +#define US_PAR_MASK 0x00000E00 ///< Parity mode mask. +#define US_PAR_EVEN 0x00000000 ///< Even parity. +#define US_PAR_ODD 0x00000200 ///< Odd parity. +#define US_PAR_SPACE 0x00000400 ///< Space parity. +#define US_PAR_MARK 0x00000600 ///< Marked parity. +#define US_PAR_NO 0x00000800 ///< No parity. +#define US_PAR_MULTIDROP 0x00000C00 ///< Multi-drop mode. + +#define US_NBSTOP_MASK 0x00003000 ///< Masks stop bit length. +#define US_NBSTOP_1 0x00000000 ///< 1 stop bit. +#define US_NBSTOP_1_5 0x00001000 ///< 1.5 stop bits. +#define US_NBSTOP_2 0x00002000 ///< 2 stop bits. + +#define US_CHMODE_MASK 0x0000C000 ///< Channel mode mask. +#define US_CHMODE_NORMAL 0x00000000 ///< Normal mode. +#define US_CHMODE_AUTOMATIC_ECHO 0x00004000 ///< Automatic echo. +#define US_CHMODE_LOCAL_LOOPBACK 0x00008000 ///< Local loopback. +#define US_CHMODE_REMOTE_LOOPBACK 0x0000C000 ///< Remote loopback. + +#define US_MSBF 16 ///< Bit order. +#define US_MODE9 17 ///< 9 bit mode. +#define US_CLKO 18 ///< Clock output select. +#define US_OVER 19 ///< Oversampling mode. +#define US_INACK 20 ///< Inhibit non acknowledge. +#define US_DSNACK 21 ///< Disable successive nack. + +#define US_MAX_INTERATION_MASK 0x07000000 ///< Max numer of interation in mode ISO7816 T=0. + +#define US_FILTER 28 ///< Infrared receive line filter. + +/*\}*/ + +/** + * Status and Interrupt Register + */ +/*\{*/ +#define US_IER_OFF 0x00000008 ///< USART interrupt enable register offset. +#define US0_IER (*((reg32_t *)(USART0_BASE + US_IER_OFF))) ///< Channel 0 interrupt enable register address. +#define US1_IER (*((reg32_t *)(USART1_BASE + US_IER_OFF))) ///< Channel 1 interrupt enable register address. + +#define US_IDR_OFF 0x0000000C ///< USART interrupt disable register offset. +#define US0_IDR (*((reg32_t *)(USART0_BASE + US_IDR_OFF))) ///< Channel 0 interrupt disable register address. +#define US1_IDR (*((reg32_t *)(USART1_BASE + US_IDR_OFF))) ///< Channel 1 interrupt disable register address. + +#define US_IMR_OFF 0x00000010 ///< USART interrupt mask register offset. +#define US0_IMR (*((reg32_t *)(USART0_BASE + US_IMR_OFF))) ///< Channel 0 interrupt mask register address. +#define US1_IMR (*((reg32_t *)(USART1_BASE + US_IMR_OFF))) ///< Channel 1 interrupt mask register address. + +#define US_CSR_OFF 0x00000014 ///< USART status register offset. +#define US0_CSR (*((reg32_t *)(USART0_BASE + US_CSR_OFF))) ///< Channel 0 status register address. +#define US1_CSR (*((reg32_t *)(USART1_BASE + US_CSR_OFF))) ///< Channel 1 status register address. +#define US_CSR_RI 20 ///< Image of RI input. +#define US_CSR_DSR 21 ///< Image of DSR input. +#define US_CSR_DCD 22 ///< Image of DCD input. +#define US_CSR_CTS 23 ///< Image of CTS input. + +#define US_RXRDY 0 ///< Receiver ready. +#define US_TXRDY 1 ///< Transmitter ready. +#define US_RXBRK 2 ///< Receiver break. +#define US_ENDRX 3 ///< End of receiver PDC transfer. +#define US_ENDTX 4 ///< End of transmitter PDC transfer. +#define US_OVRE 5 ///< Overrun error. +#define US_FRAME 6 ///< Framing error. +#define US_PARE 7 ///< Parity error. +#define US_TIMEOUT 8 ///< Receiver timeout. +#define US_TXEMPTY 9 ///< Transmitter empty. +#define US_ITERATION 10 ///< Iteration interrupt enable. +#define US_TXBUFE 11 ///< Buffer empty interrupt enable. +#define US_RXBUFF 12 ///< Buffer full interrupt enable. +#define US_NACK 13 ///< Non acknowledge interrupt enable. +#define US_RIIC 16 ///< Ring indicator input change enable. +#define US_DSRIC 17 ///< Data set ready input change enable. +#define US_DCDIC 18 ///< Data carrier detect input change interrupt enable. +#define US_CTSIC 19 ///< Clear to send input change interrupt enable. + +/** + * Receiver Holding Register + */ +/*\{*/ +#define US_RHR_OFF 0x00000018 ///< USART receiver holding register offset. +#define US0_RHR (*((reg32_t *)(USART0_BASE + US_RHR_OFF))) ///< Channel 0 receiver holding register address. +#define US1_RHR (*((reg32_t *)(USART1_BASE + US_RHR_OFF))) ///< Channel 1 receiver holding register address. +#define US_RHR_RXCHR_MASK 0x000001FF ///< Last char received if US_RXRDY is set. +#define US_RHR_RXSYNH 15 ///< Received sync. +/*\}*/ + +/** + * Transmitter Holding Register + */ +/*\{*/ +#define US_THR_OFF 0x0000001C ///< USART transmitter holding register offset. +#define US0_THR (*((reg32_t *)(USART0_BASE + US_THR_OFF))) ///< Channel 0 transmitter holding register address. +#define US1_THR (*((reg32_t *)(USART1_BASE + US_THR_OFF))) ///< Channel 1 transmitter holding register address. +#define US_THR_TXCHR_MASK 0x000001FF ///< Next char to be trasmitted. +#define US_THR_TXSYNH 15 ///< Sync field to be trasmitted. +/*\}*/ + +/** + * Baud Rate Generator Register + */ +/*\{*/ +#define US_BRGR_OFF 0x00000020 ///< USART baud rate register offset. +#define US0_BRGR (*((reg32_t *)(USART0_BASE + US_BRGR_OFF))) ///< Channel 0 baud rate register address. +#define US1_BRGR (*((reg32_t *)(USART1_BASE + US_BRGR_OFF))) ///< Channel 1 baud rate register address. +/*\}*/ + +/** + * Receiver Timeout Register + */ +/*\{*/ +#define US_RTOR_OFF 0x00000024 ///< USART receiver timeout register offset. +#define US0_RTOR (*((reg32_t *)(USART0_BASE + US_RTOR_OFF))) ///< Channel 0 receiver timeout register address. +#define US1_RTOR (*((reg32_t *)(USART1_BASE + US_RTOR_OFF))) ///< Channel 1 receiver timeout register address. +/*\}*/ + +/** + * Transmitter Time Guard Register + */ +/*\{*/ +#define US_TTGR_OFF 0x00000028 ///< USART transmitter time guard register offset. +#define US0_TTGR (*((reg32_t *)(USART0_BASE + US_TTGR_OFF))) ///< Channel 0 transmitter time guard register address. +#define US1_TTGR (*((reg32_t *)(USART1_BASE + US_TTGR_OFF))) ///< Channel 1 transmitter time guard register address. +/*\}*/ + +/** + * FI DI Ratio Register +*/ +/*\{*/ +#define US_FIDI_OFF 0x00000040 ///< USART FI DI ratio register offset. +#define US0_FIDI (*((reg32_t *)(USART0_BASE + US_FIDI_OFF))) ///< Channel 0 FI DI ratio register address. +#define US1_FIDI (*((reg32_t *)(USART1_BASE + US_FIDI_OFF))) ///< Channel 1 FI DI ratio register address. +/*\}*/ + +/** + * Error Counter Register + */ +/*\{*/ +#define US_NER_OFF 0x00000044 ///< USART error counter register offset. +#define US0_NER (*((reg32_t *)(USART0_BASE + US_NER_OFF))) ///< Channel 0 error counter register address. +#define US1_NER (*((reg32_t *)(USART1_BASE + US_NER_OFF))) ///< Channel 1 error counter register address. +/*\}*/ + +/** + * IrDA Filter Register + */ +/*\{*/ +#define US_IF_OFF 0x0000004C ///< USART IrDA filter register offset. +#define US0_IF (*((reg32_t *)(USART0_BASE + US_IF_OFF))) ///< Channel 0 IrDA filter register address. +#define US1_IF (*((reg32_t *)(USART1_BASE + US_IF_OFF))) ///< Channel 1 IrDA filter register address. +/*\}*/ + +#if USART_HAS_PDC + + /** + * Receive Pointer Register + */ + /*\{*/ + #define US0_RPR (*((reg32_t *)(USART0_BASE + PERIPH_RPR_OFF))) ///< Channel 0 receive pointer register address. + #define US1_RPR (*((reg32_t *)(USART1_BASE + PERIPH_RPR_OFF))) ///< Channel 1 receive pointer register address. + /*\}*/ + + /** + * Receive Counter Register + */ + /*\{*/ + #define US0_RCR (*((reg32_t *)(USART0_BASE + PERIPH_RCR_OFF))) ///< Channel 0 receive counter register address. + #define US1_RCR (*((reg32_t *)(USART1_BASE + PERIPH_RCR_OFF))) ///< Channel 1 receive counter register address. + /*\}*/ + + /** + * Transmit Pointer Register + */ + /*\{*/ + #define US0_TPR (*((reg32_t *)(USART0_BASE + PERIPH_TPR_OFF))) ///< Channel 0 transmit pointer register address. + #define US1_TPR (*((reg32_t *)(USART1_BASE + PERIPH_TPR_OFF))) ///< Channel 1 transmit pointer register address. + /*\}*/ + + /** + * Transmit Counter Register + */ + /*\{*/ + #define US0_TCR (*((reg32_t *)(USART0_BASE + PERIPH_TCR_OFF))) ///< Channel 0 transmit counter register address. + #define US1_TCR (*((reg32_t *)(USART1_BASE + PERIPH_TCR_OFF))) ///< Channel 1 transmit counter register address. + /*\}*/ + + #if defined(PERIPH_RNPR_OFF) && defined(PERIPH_RNCR_OFF) + #define US0_RNPR (*((reg32_t *)(USART0_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 0 receive next pointer register. + #define US1_RNPR (*((reg32_t *)(USART1_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 1 receive next pointer register. + #define US0_RNCR (*((reg32_t *)(USART0_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 0 receive next counter register. + #define US1_RNCR (*((reg32_t *)(USART1_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 1 receive next counter register. + #endif + + #if defined(PERIPH_TNPR_OFF) && defined(PERIPH_TNCR_OFF) + #define US0_TNPR (*((reg32_t *)(USART0_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 0 transmit next pointer register. + #define US1_TNPR (*((reg32_t *)(USART1_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 1 transmit next pointer register. + #define US0_TNCR (*((reg32_t *)(USART0_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 0 transmit next counter register. + #define US1_TNCR (*((reg32_t *)(USART1_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 1 transmit next counter register. + #endif + + #if defined(PERIPH_PTCR_OFF) + #define US0_PTCR (*((reg32_t *)(USART0_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 0 transfer control register. + #define US1_PTCR (*((reg32_t *)(USART1_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 1 transfer control register. + #endif + + #if defined(PERIPH_PTSR_OFF) + #define US0_PTSR (*((reg32_t *)(USART0_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 0 transfer status register. + #define US1_PTSR (*((reg32_t *)(USART1_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 1 transfer status register. + #endif + +#endif /* USART_HAS_PDC */ + +#endif /* AT91_US_H */ diff --git a/bertos/cpu/arm/io/at91_wdt.h b/bertos/cpu/arm/io/at91_wdt.h new file mode 100644 index 00000000..ed394665 --- /dev/null +++ b/bertos/cpu/arm/io/at91_wdt.h @@ -0,0 +1,111 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * + * AT91 Watchdog. + * This file is based on NUT/OS implementation. See license below. + */ + + +/* + * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91_WDT_H +#define AT91_WDT_H + + +/** Watch Dog Control Register */ +/*\{*/ +#define WDT_CR_OFF 0x00000000 ///< Watchdog control register offset. +#define WDT_CR (*((reg32_t *)(WDT_BASE + WDT_CR_OFF))) ///< Watchdog control register address. +#define WDT_WDRSTT 0 ///< Watchdog restart. +#define WDT_KEY 0xA5000000 ///< Watchdog password. +/*\}*/ + +/** Watch Dog Mode Register */ +/*\{*/ +#define WDT_MR_OFF 0x00000004 ///< Mode register offset. +#define WDT_MR (*((reg32_t *)(WDT_BASE + WDT_MR_OFF))) ///< Mode register address. +#define WDT_WDV_MASK 0x00000FFF ///< Counter value mask. +#define WDT_WDV_SHIFT 0 ///< Counter value LSB. +#define WDT_WDFIEN 12 ///< Fault interrupt enable. +#define WDT_WDRSTEN 13 ///< Reset enable. +#define WDT_WDRPROC 14 ///< Eset processor enable. +#define WDT_WDDIS 15 ///< Watchdog disable. +#define WDT_WDD_MASK 0x0FFF0000 ///< Delta value mask. +#define WDT_WDD_SHIFT 16 ///< Delta value LSB. +#define WDT_WDDBGHLT 28 ///< Watchdog debug halt. +#define WDT_WDIDLEHLT 29 ///< Watchdog idle halt. +/*\}*/ + +/** Watch Dog Status Register */ +/*\{*/ +#define WDT_SR_OFF 0x00000008 ///< Status register offset. +#define WDT_SR (*((reg32_t *)(WDT_BASE + WDT_SR_OFF))) ///< Status register address. +#define WDT_WDUNF 0 ///< Watchdog underflow. +#define WDT_WDERR 1 ///< Watchdog error. +/*\}*/ + + +#endif /* AT91_WDT_H */ diff --git a/bertos/cpu/arm/io/at91sam7.h b/bertos/cpu/arm/io/at91sam7.h new file mode 100644 index 00000000..978c9e34 --- /dev/null +++ b/bertos/cpu/arm/io/at91sam7.h @@ -0,0 +1,341 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Francesco Sacchi + * \author Daniele Basile + * + * AT91SAM7 register definitions. + * This file is based on NUT/OS implementation. See license below. + */ + +/* + * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + */ + +#ifndef AT91SAM7_H +#define AT91SAM7_H + +#include + +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7S256 + #define FLASH_BASE 0x100000UL + #define RAM_BASE 0x200000UL + + #define TC_BASE 0xFFFA0000 ///< Timer/counter base address. + #define UDP_BASE 0xFFFB0000 ///< USB device port base address. + #define TWI_BASE 0xFFFB8000 ///< Two-wire interface base address. + #define USART0_BASE 0xFFFC0000 ///< USART 0 base address. + #define USART1_BASE 0xFFFC4000 ///< USART 1 base address. + #define PWMC_BASE 0xFFFCC000 ///< PWM controller base address. + #define SSC_BASE 0xFFFD4000 ///< Serial synchronous controller base address. + #define ADC_BASE 0xFFFD8000 ///< ADC base address. + + #define AIC_BASE 0xFFFFF000 ///< AIC base address. + #define DBGU_BASE 0xFFFFF200 ///< DBGU base address. + #define PIOA_BASE 0xFFFFF400 ///< PIO A base address. + #define PMC_BASE 0xFFFFFC00 ///< PMC base address. + #define RSTC_BASE 0xFFFFFD00 ///< Resect controller register base address. + #define RTT_BASE 0xFFFFFD20 ///< Realtime timer base address. + #define PIT_BASE 0xFFFFFD30 ///< Periodic interval timer base address. + #define WDT_BASE 0xFFFFFD40 ///< Watch Dog register base address. + #define VREG_BASE 0xFFFFFD60 ///< Voltage regulator mode controller base address. + #define MC_BASE 0xFFFFFF00 ///< Memory controller base. + + #if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define CAN_BASE 0xFFFD0000 ///< PWM controller base address. + #define EMAC_BASE 0xFFFDC000 ///< Ethernet MAC address. + #define SPI0_BASE 0xFFFE0000 ///< SPI0 base address. + #define SPI1_BASE 0xFFFE4000 ///< SPI1 base address. + #define PIOB_BASE 0xFFFFF600 ///< PIO base address. + #endif + + #if CPU_ARM_AT91SAM7S256 + #define SPI_BASE 0xFFFE0000 ///< SPI0 base address. + #endif + + #define PIO_HAS_MULTIDRIVER 1 + #define PIO_HAS_PULLUP 1 + #define PIO_HAS_PERIPHERALSELECT 1 + #define PIO_HAS_OUTPUTWRITEENABLE 1 + + #define DBGU_HAS_PDC 1 + #define SPI_HAS_PDC 1 + #define SSC_HAS_PDC 1 + #define USART_HAS_PDC 1 + +#else + #error No base addrese register definition for selected ARM CPU + +#endif + +#include "at91_aic.h" +#include "at91_pit.h" +#include "at91_pmc.h" +#include "at91_mc.h" +#include "at91_wdt.h" +#include "at91_rstc.h" +#include "at91_pio.h" +#include "at91_us.h" +#include "at91_dbgu.h" +#include "at91_tc.h" +#include "at91_adc.h" +#include "at91_pwm.h" +#include "at91_spi.h" +#include "at91_twi.h" +//TODO: add other peripherals + +/** + * Peripheral Identifiers and Interrupts + *\{ + */ +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X128 + #define FIQ_ID 0 ///< Fast interrupt ID. + #define SYSC_ID 1 ///< System controller interrupt. + #define US0_ID 6 ///< USART 0 ID. + #define US1_ID 7 ///< USART 1 ID. + #define SSC_ID 8 ///< Synchronous serial controller ID. + #define TWI_ID 9 ///< Two-wire interface ID. + #define PWMC_ID 10 ///< PWM controller ID. + #define UDP_ID 11 ///< USB device port ID. + #define TC0_ID 12 ///< Timer 0 ID. + #define TC1_ID 13 ///< Timer 1 ID. + #define TC2_ID 14 ///< Timer 2 ID. + + #define IRQ0_ID 30 ///< External interrupt 0 ID. + #define IRQ1_ID 31 ///< External interrupt 1 ID. + + #if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define PIOA_ID 2 ///< Parallel A I/O controller ID. + #define PIOB_ID 3 ///< Parallel B I/O controller ID. + #define SPI0_ID 4 ///< Serial peripheral interface 0 ID. + #define SPI1_ID 5 ///< Serial peripheral interface 1 ID. + #define CAN_ID 15 ///< CAN controller ID. + #define EMAC_ID 16 ///< Ethernet MAC ID. + #define ADC_ID 17 ///< Analog to digital converter ID. + /* 18-29 Reserved */ + + #endif + + #if CPU_ARM_AT91SAM7S256 + #define PIOA_ID 2 ///< Parallel I/O controller ID. + /* ID 3 is reserved */ + #define ADC_ID 4 ///< Analog to digital converter ID. + #define SPI_ID 5 ///< Serial peripheral interface ID. + #define SPI0_ID SPI_ID ///< Alias + #endif + +#else + #error No peripheral ID and interrupts definition for selected ARM CPU + +#endif +/*\}*/ + +/** + * USART & DEBUG pin names + *\{ + */ +#if CPU_ARM_AT91SAM7S256 + #define RXD0 5 + #define TXD0 6 + #define RXD1 21 + #define TXD1 22 + #define DTXD 10 + #define DRXD 9 +#elif CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define RXD0 0 // PA0 + #define TXD0 1 // PA1 + #define RXD1 5 // PA5 + #define TXD1 6 // PA6 + #define DTXD 28 // PA28 + #define DRXD 27 // PA27 +#else + #error No USART & debug pin names definition for selected ARM CPU +#endif +/*\}*/ + +/** + * SPI pins name + *\{ + */ +#if CPU_ARM_AT91SAM7S256 + #define SPI0_NPCS0 11 // Same as NSS pin. + #define SPI0_MISO 12 + #define SPI0_MOSI 13 + #define SPI0_SPCK 14 + +#elif CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define SPI0_NPCS0 12 // Same as NSS pin. PA12 + #define SPI0_NPCS1 13 // PA13 + #define SPI0_NPCS2 14 // PA14 + #define SPI0_NPCS3 15 // PA15 + #define SPI0_MISO 16 // PA16 + #define SPI0_MOSI 17 // PA17 + #define SPI0_SPCK 18 // PA18 + + #define SPI1_NPCS0 21 // Same as NSS pin. PA21 + #define SPI1_NPCS1 25 // PA25 + #define SPI1_NPCS2 26 // PA26 + #define SPI1_NPCS3 29 // PA29 + #define SPI1_MISO 24 // PA24 + #define SPI1_MOSI 23 // PA23 + #define SPI1_SPCK 22 // PA22 + +#else + #error No SPI pins name definition for selected ARM CPU + +#endif +/*\}*/ + +/** + * Timer counter pins definition. + *\{ + */ +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define TIOA0 23 // PB23 + #define TIOB0 24 // PB24 + #define TIOA1 25 // PB25 + #define TIOB1 26 // PB26 + #define TIOA2 27 // PB27 + #define TIOB2 28 // PB28 + +#elif CPU_ARM_AT91SAM7S256 + #define TIOA0 0 // PA0 + #define TIOB0 1 // PA1 + #define TIOA1 15 // PA15 + #define TIOB1 16 // PA16 + #define TIOA2 26 // PA26 + #define TIOB2 27 // PA27 + +#else + #error No Timer Conter pins name definition for selected ARM CPU + +#endif +/*\}*/ + +/** + * PWM pins definition. + *\{ + */ +#define PWM_PIO_FUNCTION_A 1 + +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #if PWM_PIO_FUNCTION_A + #define PWM0 19 // PB19 + #define PWM1 20 // PB20 + #define PWM2 21 // PB21 + #define PWM3 22 // PB22 + #else + #define PWM0 27 // PB27 + #define PWM1 28 // PB28 + #define PWM2 29 // PB29 + #define PWM3 30 // PB30 + #endif + + +#elif CPU_ARM_AT91SAM7S256 + #define PWM0 11 // PA11 + #define PWM1 12 // PA12 + #define PWM2 13 // PA13 + #define PWM3 14 // PA14 + +#else + #error No PWM pins name definition for selected ARM CPU + +#endif +/*\}*/ + +/** + * TWI pins definition. + *\{ + */ +#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 + #define TWD 10 + #define TWCK 11 +#else + #error No TWI pin names definition for selected ARM CPU +#endif + +/** + * ADC pins definition. + *\{ + */ +#if CPU_ARM_AT91SAM7X256 + #define ADTRG 18 // PB18 + #define AD0 23 // PB27 + #define AD1 24 // PB28 + #define AD2 25 // PB29 + #define AD3 26 // PB30 + +#elif CPU_ARM_AT91SAM7S256 + #define ADTRG 18 // PA8 + #define AD0 0 // PA17 + #define AD1 1 // PA18 + #define AD2 15 // PA19 + #define AD3 16 // PA20 + +#else + #error No Timer Conter pin names definition for selected ARM CPU + +#endif +/*\}*/ + +#endif /* AT91SAM7_H */ diff --git a/bertos/cpu/arm/scripts/at91sam7_256_ram.ld b/bertos/cpu/arm/scripts/at91sam7_256_ram.ld new file mode 100644 index 00000000..40c07c95 --- /dev/null +++ b/bertos/cpu/arm/scripts/at91sam7_256_ram.ld @@ -0,0 +1,143 @@ +/** + * \file + * + * + * \version $Id: sysirq_at91.c 18273 2007-10-11 14:53:02Z batt $ + * + * \author Daniele Basile + * + * \brief Script linker for Atmel AT91SAM7_256 family processors. + * + */ + + +ENTRY(_init) +SEARCH_DIR(.) +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +/* + * Define memory configuration for AT91SAM7_256 family + */ +MEMORY +{ + rom(rx) : org = 0x00100000, len = 256k + ram(rwx) : org = 0x00200000, len = 64k +} + + +/* + * Define stack size here + */ +FIQ_STACK_SIZE = 0x0100; +IRQ_STACK_SIZE = 0x0100; +ABT_STACK_SIZE = 0x0100; +UND_STACK_SIZE = 0x0100; +SVC_STACK_SIZE = 0x0400; + +/* + * Allocate section memory + */ +SECTIONS +{ + .text : + { + KEEP(*(.vectors)); + . = ALIGN (4); + KEEP(*(.init)); + . = ALIGN (4); + *(.rodata .rodata.*); + . = ALIGN (4); + *(.text .text.*); + . = ALIGN (4); + *(.glue_7t); + . = ALIGN(4); + *(.glue_7); + . = ALIGN(4); + } > ram + + _etext = .; + PROVIDE (__etext = .); + + .data : AT (__etext) + { + PROVIDE (__data_start = .); + *(.data .data.*) + . = ALIGN (4); + _edata = .; + PROVIDE (__data_end = .); + } > ram + + .bss : + { + PROVIDE (__bss_start = .); + *(.bss .bss.*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + PROVIDE (__bss_end = .); + } > ram + + /* + * Allocated stack at the end of bss section. + * Data heap is allocate at end of stack. + */ + PROVIDE (__stack_start = .); + + PROVIDE (__stack_fiq_start = .); + . += FIQ_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_fiq_end = .); + + PROVIDE (__stack_irq_start = .); + . += IRQ_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_irq_end = .); + + PROVIDE (__stack_abt_start = .); + . += ABT_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_abt_end = .); + + PROVIDE (__stack_und_start = .); + . += UND_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_und_end = .); + + PROVIDE (__stack_svc_start = .); + . += SVC_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_svc_end = .); + + PROVIDE (__stack_end = .); + + PROVIDE (__heap_start = .); +} diff --git a/bertos/cpu/arm/scripts/at91sam7_256_rom.ld b/bertos/cpu/arm/scripts/at91sam7_256_rom.ld new file mode 100644 index 00000000..815aa423 --- /dev/null +++ b/bertos/cpu/arm/scripts/at91sam7_256_rom.ld @@ -0,0 +1,143 @@ +/** + * \file + * + * + * \version $Id: sysirq_at91.c 18273 2007-10-11 14:53:02Z batt $ + * + * \author Daniele Basile + * + * \brief Script linker for Atmel AT91SAM7_256 family processors. + * + */ + + +ENTRY(_init) +SEARCH_DIR(.) +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +/* + * Define memory configuration for AT91SAM7_256 family + */ +MEMORY +{ + rom(rx) : org = 0x00100000, len = 256k + ram(rwx) : org = 0x00200000, len = 64k +} + + +/* + * Define stack size here + */ +FIQ_STACK_SIZE = 0x0100; +IRQ_STACK_SIZE = 0x0100; +ABT_STACK_SIZE = 0x0100; +UND_STACK_SIZE = 0x0100; +SVC_STACK_SIZE = 0x0400; + +/* + * Allocate section memory + */ +SECTIONS +{ + .text : + { + KEEP(*(.vectors)); + . = ALIGN (4); + KEEP(*(.init)); + . = ALIGN (4); + *(.rodata .rodata.*); + . = ALIGN (4); + *(.text .text.*); + . = ALIGN (4); + *(.glue_7t); + . = ALIGN(4); + *(.glue_7); + . = ALIGN(4); + } > rom + + _etext = .; + PROVIDE (__etext = .); + + .data : AT (__etext) + { + PROVIDE (__data_start = .); + *(.data .data.*) + . = ALIGN (4); + _edata = .; + PROVIDE (__data_end = .); + } > ram + + .bss : + { + PROVIDE (__bss_start = .); + *(.bss .bss.*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + PROVIDE (__bss_end = .); + } > ram + + /* + * Allocated stack at the end of bss section. + * Data heap is allocate at end of stack. + */ + PROVIDE (__stack_start = .); + + PROVIDE (__stack_fiq_start = .); + . += FIQ_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_fiq_end = .); + + PROVIDE (__stack_irq_start = .); + . += IRQ_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_irq_end = .); + + PROVIDE (__stack_abt_start = .); + . += ABT_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_abt_end = .); + + PROVIDE (__stack_und_start = .); + . += UND_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_und_end = .); + + PROVIDE (__stack_svc_start = .); + . += SVC_STACK_SIZE; + . = ALIGN(4); + PROVIDE (__stack_svc_end = .); + + PROVIDE (__stack_end = .); + + PROVIDE (__heap_start = .); +} diff --git a/bertos/cpu/arm/scripts/at91sam7_ram.gdb b/bertos/cpu/arm/scripts/at91sam7_ram.gdb new file mode 100644 index 00000000..a5006bd9 --- /dev/null +++ b/bertos/cpu/arm/scripts/at91sam7_ram.gdb @@ -0,0 +1,36 @@ +target remote localhost:3333 +monitor reset +monitor sleep 500 +monitor poll +monitor soft_reset_halt +monitor arm7_9 sw_bkpts enable +#monitor arm7_9 force_hw_bkpts enable +# WDT_MR, disable watchdog +monitor mww 0xFFFFFD44 0x00008000 + +# RSTC_MR, enable user reset +monitor mww 0xfffffd08 0xa5000001 + +# CKGR_MOR +monitor mww 0xFFFFFC20 0x00000601 +monitor sleep 10 + +# CKGR_PLLR +monitor mww 0xFFFFFC2C 0x00481c0e +monitor sleep 10 + +# PMC_MCKR +monitor mww 0xFFFFFC30 0x00000007 +monitor sleep 10 + +# PMC_IER +monitor mww 0xFFFFFF60 0x00480100 +monitor sleep 100 + +#Remap RAM to address 0 +monitor mww 0xFFFFFF00 0x00000001 +monitor sleep 100 + +break main +load +continue diff --git a/bertos/cpu/arm/scripts/at91sam7_rom.gdb b/bertos/cpu/arm/scripts/at91sam7_rom.gdb new file mode 100644 index 00000000..dcecec96 --- /dev/null +++ b/bertos/cpu/arm/scripts/at91sam7_rom.gdb @@ -0,0 +1,36 @@ +target remote localhost:3333 +monitor reset +monitor sleep 500 +monitor poll +monitor soft_reset_halt +#monitor arm7_9 sw_bkpts enable +monitor arm7_9 force_hw_bkpts enable +# WDT_MR, disable watchdog +monitor mww 0xFFFFFD44 0x00008000 + +# RSTC_MR, enable user reset +monitor mww 0xfffffd08 0xa5000001 + +# CKGR_MOR +monitor mww 0xFFFFFC20 0x00000601 +monitor sleep 10 + +# CKGR_PLLR +monitor mww 0xFFFFFC2C 0x00481c0e +monitor sleep 10 + +# PMC_MCKR +monitor mww 0xFFFFFC30 0x00000007 +monitor sleep 10 + +# PMC_IER +monitor mww 0xFFFFFF60 0x00480100 +monitor sleep 100 + +#Remap RAM to address 0 +#monitor mww 0xFFFFFF00 0x00000001 +#monitor sleep 100 + +break main +load +continue diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_flash.script b/bertos/cpu/arm/scripts/openocd_at91sam7_flash.script new file mode 100644 index 00000000..98e93821 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_flash.script @@ -0,0 +1,38 @@ +# +# The following command wills be executed on +# reset (because of run_and_init in the config-file) +# - halt target +# - init ecr +# - flash content of file main.bin into target-memory +# - shutdown openocd +# +# created by Martin Thomas +# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects +# based on information from Dominic Rath +# + +halt +sleep 10 + +# Init - taken form the script openocd_at91sam7_ecr.script +mww 0xfffffd44 0x00008000 # disable watchdog +mww 0xfffffd08 0xa5000001 # enable user reset +mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator +sleep 10 +mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz +sleep 10 +mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz +sleep 10 +mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) +# arm7_9 force_hw_bkpts enable # program resides in flash + +# AT91SAM7 flash command-"batch" +# adapted by Martin Thomas based on information from Dominic Rath - Thanks +arm7_9 dcc_downloads enable +sleep 10 +poll +flash probe 0 +flash write 0 ../../../images/at91sam7.bin 0x0 +reset run +sleep 10 +#shutdown diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg new file mode 100644 index 00000000..b8f7ba16 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg @@ -0,0 +1,52 @@ +# +# Flash AT91SAM7S memory using openocd +# and a FTDI FT2232-based JTAG-interface +# +# created by Martin Thomas +# based on information from Dominic Rath +# + +#daemon configuration +telnet_port 4444 +gdb_port 3333 + +#interface +interface ft2232 +ft2232_device_desc "Amontec JTAGkey" +ft2232_layout jtagkey +ft2232_vid_pid 0x0403 0xcff8 +jtag_speed 0 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only srst_pulls_trst + +#jtag scan chain +#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) +jtag_device 4 0x1 0xf 0xe + +#target configuration +daemon_startup reset + +#target +#target arm7tdmi +target arm7tdmi little run_and_init 0 arm7tdmi +run_and_halt_time 0 30 + +# flash-options AT91 +target_script 0 reset openocd_at91sam7_reset.script +working_area 0 0x00200000 0x10000 nobackup +flash bank at91sam7 0 0 0 0 0 + +# Information: +# erase command (telnet-interface) for complete flash: +# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) +# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 +# set/clear NVM-Bits: +# at91sam7 gpnvm +# disable locking from SAM-BA +# flash protect 0 0 1 off + +# For more information about the configuration files, take a look at: +# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg new file mode 100755 index 00000000..2c52f8ef --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg @@ -0,0 +1,52 @@ +# +# Flash AT91SAM7S memory using openocd +# and a FTDI FT2232-based JTAG-interface +# +# created by Martin Thomas +# based on information from Dominic Rath +# + +#daemon configuration +telnet_port 4444 +gdb_port 3333 + +#interface +interface ft2232 +ft2232_device_desc "Amontec JTAGkey A" +ft2232_layout jtagkey +ft2232_vid_pid 0x0403 0xcff8 +jtag_speed 0 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only srst_pulls_trst + +#jtag scan chain +#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) +jtag_device 4 0x1 0xf 0xe + +#target configuration +daemon_startup reset + +#target +#target arm7tdmi +target arm7tdmi little run_and_init 0 arm7tdmi +run_and_halt_time 0 30 + +# flash-options AT91 +target_script 0 reset openocd_at91sam7_reset.script +working_area 0 0x00200000 0x10000 nobackup +flash bank at91sam7 0 0 0 0 0 + +# Information: +# erase command (telnet-interface) for complete flash: +# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) +# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 +# set/clear NVM-Bits: +# at91sam7 gpnvm +# disable locking from SAM-BA +# flash protect 0 0 1 off + +# For more information about the configuration files, take a look at: +# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg new file mode 100644 index 00000000..bb0602a1 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg @@ -0,0 +1,52 @@ +# +# Flash AT91SAM7S memory using openocd +# and a FTDI FT2232-based JTAG-interface +# +# created by Martin Thomas +# based on information from Dominic Rath +# + +#daemon configuration +telnet_port 4444 +gdb_port 3333 + +#interface +interface ft2232 +ft2232_device_desc "Amontec JTAGkey" +ft2232_layout jtagkey +ft2232_vid_pid 0x0403 0xcff8 +jtag_speed 0 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only srst_pulls_trst + +#jtag scan chain +#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) +jtag_device 4 0x1 0xf 0xe + +#target configuration +daemon_startup reset + +#target +#target arm7tdmi +target arm7tdmi little run_and_init 0 arm7tdmi +run_and_halt_time 0 30 + +# flash-options AT91 +target_script 0 reset openocd_at91sam7_flash.script +working_area 0 0x00100000 0x40000 nobackup +flash bank at91sam7 0 0 0 0 0 + +# Information: +# erase command (telnet-interface) for complete flash: +# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) +# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 +# set/clear NVM-Bits: +# at91sam7 gpnvm +# disable locking from SAM-BA +# flash protect 0 0 1 off + +# For more information about the configuration files, take a look at: +# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg new file mode 100755 index 00000000..31ad4c86 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg @@ -0,0 +1,52 @@ +# +# Flash AT91SAM7S memory using openocd +# and a FTDI FT2232-based JTAG-interface +# +# created by Martin Thomas +# based on information from Dominic Rath +# + +#daemon configuration +telnet_port 4444 +gdb_port 3333 + +#interface +interface ft2232 +ft2232_device_desc "Amontec JTAGkey A" +ft2232_layout jtagkey +ft2232_vid_pid 0x0403 0xcff8 +jtag_speed 0 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only srst_pulls_trst + +#jtag scan chain +#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) +jtag_device 4 0x1 0xf 0xe + +#target configuration +daemon_startup reset + +#target +#target arm7tdmi +target arm7tdmi little run_and_init 0 arm7tdmi +run_and_halt_time 0 30 + +# flash-options AT91 +target_script 0 reset openocd_at91sam7_flash.script +working_area 0 0x00100000 0x40000 nobackup +flash bank at91sam7 0 0 0 0 0 + +# Information: +# erase command (telnet-interface) for complete flash: +# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) +# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 +# set/clear NVM-Bits: +# at91sam7 gpnvm +# disable locking from SAM-BA +# flash protect 0 0 1 off + +# For more information about the configuration files, take a look at: +# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/bertos/cpu/arm/scripts/openocd_at91sam7_reset.script b/bertos/cpu/arm/scripts/openocd_at91sam7_reset.script new file mode 100644 index 00000000..ff609b01 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_at91sam7_reset.script @@ -0,0 +1,17 @@ +# +# Init - taken form the script openocd_at91sam7_ecr.script +# +# I take this script from the following page: +# +# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html +# +mww 0xfffffd44 0x00008000 # disable watchdog +mww 0xfffffd08 0xa5000001 # enable user reset +mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator +sleep 10 +mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz +sleep 10 +mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz +sleep 10 +mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) +sleep 100 diff --git a/bertos/cpu/arm/scripts/openocd_ram.bat b/bertos/cpu/arm/scripts/openocd_ram.bat new file mode 100755 index 00000000..d17124f7 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_ram.bat @@ -0,0 +1 @@ +openocd-ftd2xx.exe -f openocd_at91sam7_ftdi_ram_win.cfg diff --git a/bertos/cpu/arm/scripts/openocd_rom.bat b/bertos/cpu/arm/scripts/openocd_rom.bat new file mode 100755 index 00000000..d9e6b251 --- /dev/null +++ b/bertos/cpu/arm/scripts/openocd_rom.bat @@ -0,0 +1 @@ +openocd-ftd2xx.exe -f openocd_at91sam7_ftdi_rom_win.cfg diff --git a/bertos/cpu/attr.h b/bertos/cpu/attr.h new file mode 100644 index 00000000..ce6e4ae3 --- /dev/null +++ b/bertos/cpu/attr.h @@ -0,0 +1,350 @@ +/** + * \file + * + * + * \brief CPU-specific attributes. + * + * \author Giovanni Bajo + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * \author Francesco Sacchi + */ +#ifndef CPU_ATTR_H +#define CPU_ATTR_H + +#include "detect.h" +#include /* for uintXX_t */ +#include /* ARCH_EMUL */ + +#include "appconfig.h" // CONFIG_FAST_MEM + +/** + * \name Macros for determining CPU endianness. + * \{ + */ +#define CPU_BIG_ENDIAN 0x1234 +#define CPU_LITTLE_ENDIAN 0x3412 /* Look twice, pal. This is not a bug. */ +/*\}*/ + +/** Macro to include cpu-specific versions of the headers. */ +#define CPU_HEADER(module) PP_STRINGIZE(drv/PP_CAT3(module, _, CPU_ID).h) + +/** Macro to include cpu-specific versions of implementation files. */ +#define CPU_CSOURCE(module) PP_STRINGIZE(drv/PP_CAT3(module, _, CPU_ID).c) + + +#if CPU_I196 + + #define NOP nop_instruction() + + #define CPU_REG_BITS 16 + #define CPU_REGS_CNT 16 + #define CPU_STACK_GROWS_UPWARD 0 + #define CPU_SP_ON_EMPTY_SLOT 0 + #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN + #define CPU_HARVARD 0 + +#elif CPU_X86 + + #define NOP asm volatile ("nop") + + #define CPU_REGS_CNT 7 + #define CPU_SAVED_REGS_CNT 7 + #define CPU_STACK_GROWS_UPWARD 0 + #define CPU_SP_ON_EMPTY_SLOT 0 + #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN + #define CPU_HARVARD 0 + + #if CPU_X86_64 + #define CPU_REG_BITS 64 + + #ifdef __WIN64__ + /* WIN64 is an IL32-P64 weirdo. */ + #define SIZEOF_LONG 4 + #endif + #else + #define CPU_REG_BITS 32 + #endif + +#elif CPU_ARM + + /* Register counts include SREG too */ + #define CPU_REG_BITS 32 + #define CPU_REGS_CNT 16 + #define CPU_SAVED_REGS_CNT 9 + #define CPU_STACK_GROWS_UPWARD 0 + #define CPU_SP_ON_EMPTY_SLOT 0 + #define CPU_HARVARD 0 + + #ifdef __IAR_SYSTEMS_ICC__ + #warning Check CPU_BYTE_ORDER + #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN) + + #define NOP __no_operation() + + #else /* GCC and compatibles */ + + #if defined(__ARMEB__) + #define CPU_BYTE_ORDER CPU_BIG_ENDIAN + #elif defined(__ARMEL__) + #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN + #else + #error Unable to detect ARM endianness! + #endif + + #define NOP asm volatile ("mov r0,r0" ::) + + /** + * Initialization value for registers in stack frame. + * The register index is not directly corrispondent to CPU + * register numbers, but is related to how are pushed to + * stack (\see asm_switch_context). + * Index (CPU_SAVED_REGS_CNT - 1) is the CPSR register, + * the initial value is set to: + * - All flags (N, Z, C, V) set to 0. + * - IRQ and FIQ enabled. + * - ARM state. + * - CPU in Supervisor Mode (SVC). + */ + #define CPU_REG_INIT_VALUE(reg) (reg == (CPU_SAVED_REGS_CNT - 1) ? 0x13 : 0) + + #if CONFIG_FAST_MEM + /** + * Function attribute for use with performance critical code. + * + * On the AT91 family, code residing in flash has wait states. + * Moving functions to the data section is a quick & dirty way + * to get them transparently copied to SRAM for zero-wait-state + * operation. + */ + #define FAST_FUNC __attribute__((section(".data"))) + + /** + * Data attribute to move constant data to fast memory storage. + * + * \see FAST_FUNC + */ + #define FAST_RODATA __attribute__((section(".data"))) + + #else // !CONFIG_FAST_MEM + #define FAST_RODATA /**/ + #define FAST_FUNC /**/ + #endif + + /** + * Function attribute to declare an interrupt service routine. + */ + #define ISR_FUNC __attribute__((interrupt)) + + #endif /* !__IAR_SYSTEMS_ICC_ */ + +#elif CPU_PPC + #define NOP asm volatile ("nop" ::) + + /* Register counts include SREG too */ + #define CPU_REG_BITS (CPU_PPC32 ? 32 : 64) + #define CPU_REGS_CNT FIXME + #define CPU_SAVED_REGS_CNT FIXME + #define CPU_STACK_GROWS_UPWARD 0 //FIXME + #define CPU_SP_ON_EMPTY_SLOT 0 //FIXME + #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN) + #define CPU_HARVARD 0 + +#elif CPU_DSP56K + + #define NOP asm(nop) + + #define CPU_REG_BITS 16 + #define CPU_REGS_CNT FIXME + #define CPU_SAVED_REGS_CNT 8 + #define CPU_STACK_GROWS_UPWARD 1 + #define CPU_SP_ON_EMPTY_SLOT 0 + #define CPU_BYTE_ORDER CPU_BIG_ENDIAN + #define CPU_HARVARD 1 + + /* Memory is word-addessed in the DSP56K */ + #define CPU_BITS_PER_CHAR 16 + #define SIZEOF_SHORT 1 + #define SIZEOF_INT 1 + #define SIZEOF_LONG 2 + #define SIZEOF_PTR 1 + +#elif CPU_AVR + + #define NOP asm volatile ("nop" ::) + + /* Register counts include SREG too */ + #define CPU_REG_BITS 8 + #define CPU_REGS_CNT 33 + #define CPU_SAVED_REGS_CNT 19 + #define CPU_STACK_GROWS_UPWARD 0 + #define CPU_SP_ON_EMPTY_SLOT 1 + #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN + #define CPU_HARVARD 1 + + /** + * Initialization value for registers in stack frame. + * The register index is not directly corrispondent to CPU + * register numbers. Index 0 is the SREG register: the initial + * value is all 0 but the interrupt bit (bit 7). + */ + #define CPU_REG_INIT_VALUE(reg) (reg == 0 ? 0x80 : 0) + +#else + #error No CPU_... defined. +#endif + +/// Default for macro not defined in the right arch section +#ifndef CPU_REG_INIT_VALUE + #define CPU_REG_INIT_VALUE(reg) 0 +#endif + + +#ifndef CPU_STACK_GROWS_UPWARD + #error CPU_STACK_GROWS_UPWARD should have been defined to either 0 or 1 +#endif + +#ifndef CPU_SP_ON_EMPTY_SLOT + #error CPU_SP_ON_EMPTY_SLOT should have been defined to either 0 or 1 +#endif + +/* + * Support stack handling peculiarities of a few CPUs. + * + * Most processors let their stack grow downward and + * keep SP pointing at the last pushed value. + */ +#if !CPU_STACK_GROWS_UPWARD + #if !CPU_SP_ON_EMPTY_SLOT + /* Most microprocessors (x86, m68k...) */ + #define CPU_PUSH_WORD(sp, data) \ + do { *--(sp) = (data); } while (0) + #define CPU_POP_WORD(sp) \ + (*(sp)++) + #else + /* AVR insanity */ + #define CPU_PUSH_WORD(sp, data) \ + do { *(sp)-- = (data); } while (0) + #define CPU_POP_WORD(sp) \ + (*++(sp)) + #endif + +#else /* CPU_STACK_GROWS_UPWARD */ + + #if !CPU_SP_ON_EMPTY_SLOT + /* DSP56K and other weirdos */ + #define CPU_PUSH_WORD(sp, data) \ + do { *++(sp) = (cpustack_t)(data); } while (0) + #define CPU_POP_WORD(sp) \ + (*(sp)--) + #else + #error I bet you cannot find a CPU like this + #endif +#endif + + +#if CPU_DSP56K + /* + * DSP56k pushes both PC and SR to the stack in the JSR instruction, but + * RTS discards SR while returning (it does not restore it). So we push + * 0 to fake the same context. + */ + #define CPU_PUSH_CALL_CONTEXT(sp, func) \ + do { \ + CPU_PUSH_WORD((sp), (func)); \ + CPU_PUSH_WORD((sp), 0x100); \ + } while (0); + +#elif CPU_AVR + /* + * In AVR, the addresses are pushed into the stack as little-endian, while + * memory accesses are big-endian (actually, it's a 8-bit CPU, so there is + * no natural endianess). + */ + #define CPU_PUSH_CALL_CONTEXT(sp, func) \ + do { \ + uint16_t funcaddr = (uint16_t)(func); \ + CPU_PUSH_WORD((sp), funcaddr); \ + CPU_PUSH_WORD((sp), funcaddr>>8); \ + } while (0) + + /* + * If the kernel is in idle-spinning, the processor executes: + * + * IRQ_ENABLE; + * CPU_IDLE; + * IRQ_DISABLE; + * + * IRQ_ENABLE is translated in asm as "sei" and IRQ_DISABLE as "cli". + * We could define CPU_IDLE to expand to none, so the resulting + * asm code would be: + * + * sei; + * cli; + * + * But Atmel datasheet states: + * "When using the SEI instruction to enable interrupts, + * the instruction following SEI will be executed *before* + * any pending interrupts", so "cli" is executed before any + * pending interrupt with the result that IRQs will *NOT* + * be enabled! + * To ensure that IRQ will run a NOP is required. + */ + #define CPU_IDLE NOP + +#else + #define CPU_PUSH_CALL_CONTEXT(sp, func) \ + CPU_PUSH_WORD((sp), (cpustack_t)(func)) +#endif + +/** + * \def CPU_IDLE + * + * \brief Invoked by the scheduler to stop the CPU when idle. + * + * This hook can be redefined to put the CPU in low-power mode, or to + * profile system load with an external strobe, or to save CPU cycles + * in hosted environments such as emulators. + */ +#ifndef CPU_IDLE + #if defined(ARCH_EMUL) && (ARCH & ARCH_EMUL) + /* This emulator hook should yield the CPU to the host. */ + EXTERN_C_BEGIN + void emul_idle(void); + EXTERN_C_END + #define CPU_IDLE emul_idle() + #else /* !ARCH_EMUL */ + #define CPU_IDLE do { /* nothing */ } while (0) + #endif /* !ARCH_EMUL */ +#endif /* !CPU_IDLE */ + +#endif /* CPU_ATTR_H */ diff --git a/bertos/cpu/avr/drv/adc_avr.c b/bertos/cpu/avr/drv/adc_avr.c new file mode 100644 index 00000000..e57b04bf --- /dev/null +++ b/bertos/cpu/avr/drv/adc_avr.c @@ -0,0 +1,153 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief ADC hardware-specific definition + * + * \version $Id$ + * \author Francesco Sacchi + */ + +#include "adc_avr.h" + +#include +#include + +#include +#include + +#include +#include + +#define ADC_AVR_AREF 0 +#define ADC_AVR_AVCC 1 +#define ADC_AVR_INT256 2 + +#if CONFIG_KERNEL + #include + #include + #include + #include + + + #if !CONFIG_KERN_SIGNALS + #error Signals must be active to use ADC with kernel + #endif + + /* Signal adc convertion end */ + #define SIG_ADC_COMPLETE SIG_SINGLE + + /* ADC waiting process */ + static struct Process *adc_process; + + /** + * ADC ISR. + * Simply signal the adc process that convertion is complete. + */ + ISR(ADC_vect) + { + sig_signal(adc_process, SIG_ADC_COMPLETE); + } +#endif /* CONFIG_KERNEL */ + +/** + * Select mux channel \a ch. + * \todo only first 8 channels are selectable! + */ +INLINE void adc_hw_select_ch(uint8_t ch) +{ + /* Set to 0 all mux registers */ + ADMUX &= ~(BV(MUX3) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0)); + + /* Select channel, only first 8 channel modes are supported for now */ + ADMUX |= (ch & 0x07); +} + + +/** + * Start an ADC convertion. + * If a kernel is present, preempt until convertion is complete, otherwise + * a busy wait on ADCS bit is done. + */ +INLINE uint16_t adc_hw_read(void) +{ + // Ensure another convertion is not running. + ASSERT(!(ADCSRA & BV(ADSC))); + + // Start convertion + ADCSRA |= BV(ADSC); + + #if CONFIG_KERNEL + // Ensure IRQs enabled. + ASSERT(IRQ_ENABLED()); + adc_process = proc_current(); + sig_wait(SIG_ADC_COMPLETE); + #else + //Wait in polling until is done + while (ADCSRA & BV(ADSC)) ; + #endif + + return(ADC); +} + +/** + * Init ADC hardware. + */ +INLINE void adc_hw_init(void) +{ + /* + * Select channel 0 as default, + * result right adjusted. + */ + ADMUX = 0; + + #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF + /* External voltage at AREF as analog ref source */ + /* None */ + #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC + /* AVCC as analog ref source */ + ADMUX |= BV(REFS0); + #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256 + /* Internal 2.56V as ref source */ + ADMUX |= BV(REFS1) | BV(REFS0); + #else + #error Unsupported ADC ref value. + #endif + + /* Disable Auto trigger source: ADC in Free running mode. */ + ADCSRB = 0; + + /* Enable ADC, disable autotrigger mode. */ + ADCSRA = BV(ADEN); + + #if CONFIG_KERNEL + MOD_CHECK(proc); + ADCSRA |= BV(ADIE); + #endif + + /* Set convertion frequency */ + #if CONFIG_ADC_AVR_DIVISOR == 2 + ADCSRA |= BV(ADPS0); + #elif CONFIG_ADC_AVR_DIVISOR == 4 + ADCSRA |= BV(ADPS1); + #elif CONFIG_ADC_AVR_DIVISOR == 8 + ADCSRA |= BV(ADPS1) | BV(ADPS0); + #elif CONFIG_ADC_AVR_DIVISOR == 16 + ADCSRA |= BV(ADPS2); + #elif CONFIG_ADC_AVR_DIVISOR == 32 + ADCSRA |= BV(ADPS2) | BV(ADPS0); + #elif CONFIG_ADC_AVR_DIVISOR == 64 + ADCSRA |= BV(ADPS2) | BV(ADPS1); + #elif CONFIG_ADC_AVR_DIVISOR == 128 + ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0); + #else + #error Unsupported ADC prescaler value. + #endif + + /* Start a convertion to init ADC hw */ + adc_hw_read(); +} diff --git a/bertos/cpu/avr/drv/adc_avr.h b/bertos/cpu/avr/drv/adc_avr.h new file mode 100644 index 00000000..ddd2ce72 --- /dev/null +++ b/bertos/cpu/avr/drv/adc_avr.h @@ -0,0 +1,21 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief ADC hardware-specific definition + * + * \version $Id$ + * \author Francesco Sacchi + */ + +#ifndef DRV_ADC_AVR_H +#define DRV_ADC_AVR_H + +#define ADC_MUX_MAXCH 7 +#define ADC_BITS 10 + +#endif /* DRV_ADC_AVR_H */ diff --git a/bertos/cpu/avr/drv/flash_avr.c b/bertos/cpu/avr/drv/flash_avr.c new file mode 100644 index 00000000..b461d95d --- /dev/null +++ b/bertos/cpu/avr/drv/flash_avr.c @@ -0,0 +1,296 @@ +/** + * \file + * + * + * \brief Self programming routines. + * + * \version $Id$ + * \author Francesco Sacchi + * \author Daniele Basile + * + * This module implements a kfile-like access for Atmel avr + * internal flash. + * Internal flash writing access is controlled by BOOTSZ fuses, check + * datasheet for details. + */ + +#include "flash_avr.h" + +#include +#include +#include + +#include // MIN() +#include +#include +#include + +#include + +#include + +#include + +/** + * Definition of type for avr flash module. + */ +typedef uint16_t avr_page_addr_t; +typedef uint16_t avr_page_t; + +/** + * Temporary buffer cointaing data block to + * write on flash. + */ +static uint8_t page_buf[SPM_PAGESIZE]; + +/** + * Flag for checking if current page is modified. + */ +bool page_modified; + +/** + * Current buffered page. + */ +static avr_page_t curr_page = 0; + +/* + * Private avr flush funtion. + * + * Write current buffered page in flash memory (if modified). + * This function erase flash memory page before writing. + * + * This function is only use internaly in this module. + */ +static void flash_avr_flush(void) +{ + if (page_modified) + { + kprintf("Flushing page %d\n", curr_page); + + // Wait while the SPM instruction is busy. + boot_spm_busy_wait(); + + kprintf("Filling temparary page buffer..."); + + // Fill the temporary buffer of the AVR + for (avr_page_addr_t page_addr = 0; page_addr < SPM_PAGESIZE; page_addr += 2) + { + uint16_t word = ((uint16_t)page_buf[page_addr + 1] << 8) | page_buf[page_addr]; + + ATOMIC(boot_page_fill(page_addr, word)); + } + kprintf("Done.\n"); + + wdt_reset(); + + kprintf("Erasing page, addr %u...", curr_page * SPM_PAGESIZE); + + /* Page erase */ + ATOMIC(boot_page_erase(curr_page * SPM_PAGESIZE)); + + /* Wait until the memory is erased. */ + boot_spm_busy_wait(); + + kprintf("Done.\n"); + kprintf("Writing page, addr %u...", curr_page * SPM_PAGESIZE); + + /* Store buffer in flash page. */ + ATOMIC(boot_page_write(curr_page * SPM_PAGESIZE)); + boot_spm_busy_wait(); // Wait while the SPM instruction is busy. + + /* + * Reenable RWW-section again. We need this if we want to jump back + * to the application after bootloading. + */ + ATOMIC(boot_rww_enable()); + + page_modified = false; + kprintf("Done.\n"); + } +} + + +/** + * Flush avr flash function. + * + * Write current buffered page in flash memory (if modified). + * This function erase flash memory page before writing. + */ +static int flash_avr_kfileFlush(struct KFile * fd) +{ + KFILE_ASSERT_GENERIC(fd); + (void)fd; + flash_avr_flush(); + return 0; +} + + +/** + * Check current page and if \a page is different, load it in + * temporary buffer. + */ +static void flash_avr_loadPage(avr_page_t page) +{ + if (page != curr_page) + { + flash_avr_flush(); + // Load page + memcpy_P(page_buf, (const char *)(page * SPM_PAGESIZE), SPM_PAGESIZE); + curr_page = page; + kprintf("Loaded page %d\n", curr_page); + } +} + +/** + * Write program memory. + * Write \a size bytes from buffer \a _buf to file \a fd + * \note Write operations are buffered. + */ +static size_t flash_avr_write(struct KFile *fd, const void *_buf, size_t size) +{ + KFILE_ASSERT_GENERIC(fd); + const uint8_t *buf =(const uint8_t *)_buf; + + avr_page_t page; + avr_page_addr_t page_addr; + size_t total_write = 0; + + ASSERT(fd->seek_pos + size <= fd->size); + size = MIN((uint32_t)size, fd->size - fd->seek_pos); + + kprintf("Writing at pos[%u]\n", fd->seek_pos); + while (size) + { + page = fd->seek_pos / SPM_PAGESIZE; + page_addr = fd->seek_pos % SPM_PAGESIZE; + + flash_avr_loadPage(page); + + size_t wr_len = MIN(size, SPM_PAGESIZE - page_addr); + memcpy(page_buf + page_addr, buf, wr_len); + page_modified = true; + + buf += wr_len; + fd->seek_pos += wr_len; + size -= wr_len; + total_write += wr_len; + } + kprintf("written %u bytes\n", total_write); + return total_write; +} + +/** + * Open flash file \a fd + * \a name and \a mode are unused, cause flash memory is + * threated like one file. + */ +static void flash_avr_open(struct KFile *fd) +{ + KFILE_ASSERT_GENERIC(fd); + curr_page = 0; + memcpy_P(page_buf, (const char *)(curr_page * SPM_PAGESIZE), SPM_PAGESIZE); + + fd->seek_pos = 0; + fd->size = (uint16_t)(FLASHEND - CONFIG_BOOT_SIZE + 1); + page_modified = false; + + kprintf("Flash file opened\n"); +} + +/** + * Close file \a fd + */ +static int flash_avr_close(UNUSED_ARG(struct KFile *,fd)) +{ + KFILE_ASSERT_GENERIC(fd); + flash_avr_flush(); + kprintf("Flash file closed\n"); + return 0; +} + +/** + * Reopen file \a fd + */ +static struct KFile *flash_avr_reopen(struct KFile *fd) +{ + KFILE_ASSERT_GENERIC(fd); + flash_avr_close(fd); + flash_avr_open(fd); + return fd; +} + + +/** + * Read from file \a fd \a size bytes and put it in buffer \a buf + * \return the number of bytes read. + */ +static size_t flash_avr_read(struct KFile *fd, void *buf, size_t size) +{ + KFILE_ASSERT_GENERIC(fd); + ASSERT(fd->seek_pos + size <= fd->size); + size = MIN((uint32_t)size, fd->size - fd->seek_pos); + + kprintf("Reading at pos[%u]\n", fd->seek_pos); + // Flush current buffered page (if modified). + flash_avr_flush(); + + /* + * AVR pointers are 16 bits wide, this hack is needed to avoid + * compiler warning, cause fd->seek_pos is a 32bit offset. + */ + const uint8_t *pgm_addr = (const uint8_t *)0; + pgm_addr += fd->seek_pos; + + memcpy_P(buf, pgm_addr, size); + fd->seek_pos += size; + kprintf("Read %u bytes\n", size); + return size; +} + +/** + * Init AVR flash read/write file. + */ +void flash_avr_init(struct KFile *fd) +{ + memset(fd, 0, sizeof(*fd)); + DB(fd->_type = KFT_GENERIC); + + // Set up flash programming functions. + fd->reopen = flash_avr_reopen; + fd->close = flash_avr_close; + fd->read = flash_avr_read; + fd->write = flash_avr_write; + fd->seek = kfile_genericSeek; + fd->flush = flash_avr_kfileFlush; + + flash_avr_open(fd); +} + diff --git a/bertos/cpu/avr/drv/flash_avr.h b/bertos/cpu/avr/drv/flash_avr.h new file mode 100644 index 00000000..7b4317d9 --- /dev/null +++ b/bertos/cpu/avr/drv/flash_avr.h @@ -0,0 +1,50 @@ +/** + * \file + * + * + * \brief Self programming routines (interface). + * + * \version $Id$ + * \author Francesco Sacchi + * \author Daniele Basile + */ + +#ifndef DRV_FLASH_AVR_H +#define DRV_FLASH_AVR_H + +#include +#include + +bool flash_avr_test(void); +void flash_avr_init(struct KFile *fd); + + +#endif /* DRV_FLASH_AVR_H */ diff --git a/bertos/cpu/avr/drv/kdebug_avr.c b/bertos/cpu/avr/drv/kdebug_avr.c new file mode 100644 index 00000000..35d0645d --- /dev/null +++ b/bertos/cpu/avr/drv/kdebug_avr.c @@ -0,0 +1,255 @@ +/** + * \file + * + * + * \brief AVR debug support (implementation). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * \author Francesco Sacchi + */ + +#include +#include +#include /* for BV(), DIV_ROUND */ +#include +#include /* for CLOCK_FREQ */ +#include /* Required for bus macros overrides */ + +#include + +#if CONFIG_KDEBUG_PORT == 0 + + /* + * Support for special bus policies or external transceivers + * on UART0 (to be overridden in "hw_ser.h"). + * + * HACK: if we don't set TXEN, kdbg disables the transmitter + * after each output statement until the serial driver + * is initialized. These glitches confuse the debug + * terminal that ends up printing some trash. + */ + #ifndef KDBG_UART0_BUS_INIT + #define KDBG_UART0_BUS_INIT do { \ + UCSR0B = BV(TXEN0); \ + } while (0) + #endif + #ifndef KDBG_UART0_BUS_RX + #define KDBG_UART0_BUS_RX do {} while (0) + #endif + #ifndef KDBG_UART0_BUS_TX + #define KDBG_UART0_BUS_TX do {} while (0) + #endif + + #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA168 + #define UCR UCSR0B + #define UDR UDR0 + #define USR UCSR0A + #elif CPU_AVR_ATMEGA8 + #define UCR UCSRB + #define USR UCSRA + #else + #error Unknown CPU + #endif + + #define KDBG_WAIT_READY() do { loop_until_bit_is_set(USR, UDRE0); } while(0) + #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(USR, TXC0); } while(0) + + /* + * We must clear the TXC flag before sending a new character to allow + * KDBG_WAIT_TXDONE() to work properly. + * + * BUG: if KDBG_WRITE_CHAR() is called after the TXC flag is set by hardware, + * a new TXC could be generated after we've cleared it and before the new + * character is written to UDR. On a 485 bus, the transceiver will be put + * in RX mode while still transmitting the last char. + */ + #define KDBG_WRITE_CHAR(c) do { USR |= BV(TXC0); UDR = (c); } while(0) + + #define KDBG_MASK_IRQ(old) do { \ + (old) = UCR; \ + UCR |= BV(TXEN0); \ + UCR &= ~(BV(TXCIE0) | BV(UDRIE0)); \ + KDBG_UART0_BUS_TX; \ + } while(0) + + #define KDBG_RESTORE_IRQ(old) do { \ + KDBG_WAIT_TXDONE(); \ + KDBG_UART0_BUS_RX; \ + UCR = (old); \ + } while(0) + + typedef uint8_t kdbg_irqsave_t; + +#elif CONFIG_KDEBUG_PORT == 1 + + /* + * Support for special bus policies or external transceivers + * on UART1 (to be overridden in "hw_ser.h"). + * + * HACK: if we don't set TXEN, kdbg disables the transmitter + * after each output statement until the serial driver + * is initialized. These glitches confuse the debug + * terminal that ends up printing some trash. + */ + #ifndef KDBG_UART1_BUS_INIT + #define KDBG_UART1_BUS_INIT do { \ + UCSR1B = BV(TXEN1); \ + } while (0) + #endif + #ifndef KDBG_UART1_BUS_RX + #define KDBG_UART1_BUS_RX do {} while (0) + #endif + #ifndef KDBG_UART1_BUS_TX + #define KDBG_UART1_BUS_TX do {} while (0) + #endif + + #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR1A, UDRE1); } while(0) + #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR1A, TXC1); } while(0) + #define KDBG_WRITE_CHAR(c) do { UCSR1A |= BV(TXC1); UDR1 = (c); } while(0) + + #define KDBG_MASK_IRQ(old) do { \ + (old) = UCSR1B; \ + UCSR1B |= BV(TXEN1); \ + UCSR1B &= ~(BV(TXCIE1) | BV(UDRIE1)); \ + KDBG_UART1_BUS_TX; \ + } while(0) + + #define KDBG_RESTORE_IRQ(old) do { \ + KDBG_WAIT_TXDONE(); \ + KDBG_UART1_BUS_RX; \ + UCSR1B = (old); \ + } while(0) + + typedef uint8_t kdbg_irqsave_t; + +/* + * Special debug port for BitBanged Serial see below for details... + */ +#elif CONFIG_KDEBUG_PORT == 666 + #include "hw_ser.h" + #define KDBG_WAIT_READY() do { /*nop*/ } while(0) + #define KDBG_WRITE_CHAR(c) _kdebug_bitbang_putchar((c)) + #define KDBG_MASK_IRQ(old) do { IRQ_SAVE_DISABLE((old)); } while(0) + #define KDBG_RESTORE_IRQ(old) do { IRQ_RESTORE((old)); } while(0) + typedef cpuflags_t kdbg_irqsave_t; + + #define KDBG_DELAY (((CLOCK_FREQ + CONFIG_KDEBUG_BAUDRATE / 2) / CONFIG_KDEBUG_BAUDRATE) + 7) / 14 + + static void _kdebug_bitbang_delay(void) + { + unsigned long i; + + for (i = 0; i < KDBG_DELAY; i++) + { + NOP; + NOP; + NOP; + NOP; + NOP; + } + } + + /** + * Putchar for BITBANG serial debug console. + * Sometimes, we can't permit to use a whole serial for debugging purpose. + * Since debug console is in output only it is usefull to use a single generic I/O pin for debug. + * This is achieved by this simple function, that shift out the data like a UART, but + * in software :) + * The only requirement is that SER_BITBANG_* macros will be defined somewhere (usually hw_ser.h) + * \note All interrupts are disabled during debug prints! + */ + static void _kdebug_bitbang_putchar(char c) + { + int i; + uint16_t data = c; + + /* Add stop bit */ + data |= 0x0100; + + /* Add start bit*/ + data <<= 1; + + /* Shift out data */ + uint16_t shift = 1; + for (i = 0; i < 10; i++) + { + if (data & shift) + SER_BITBANG_HIGH; + else + SER_BITBANG_LOW; + _kdebug_bitbang_delay(); + shift <<= 1; + } + } +#else + #error CONFIG_KDEBUG_PORT should be either 0, 1 or 666 +#endif + + +INLINE void kdbg_hw_init(void) +{ + #if CONFIG_KDEBUG_PORT == 666 + SER_BITBANG_INIT; + #else /* CONFIG_KDEBUG_PORT != 666 */ + /* Compute the baud rate */ + uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1; + + #if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128) + #if CONFIG_KDEBUG_PORT == 0 + UBRR0H = (uint8_t)(period>>8); + UBRR0L = (uint8_t)period; + KDBG_UART0_BUS_INIT; + #elif CONFIG_KDEBUG_PORT == 1 + UBRR1H = (uint8_t)(period>>8); + UBRR1L = (uint8_t)period; + KDBG_UART1_BUS_INIT; + #else + #error CONFIG_KDEBUG_PORT must be either 0 or 1 + #endif + + #elif CPU_AVR_ATMEGA168 + UBRR0H = (uint8_t)(period>>8); + UBRR0L = (uint8_t)period; + KDBG_UART0_BUS_INIT; + #elif CPU_AVR_ATMEGA8 + UBRRH = (uint8_t)(period>>8); + UBRRL = (uint8_t)period; + #elif CPU_AVR_ATMEGA103 + UBRR = (uint8_t)period; + KDBG_UART0_BUS_INIT; + #else + #error Unknown CPU + #endif + #endif /* CONFIG_KDEBUG_PORT == 666 */ +} diff --git a/bertos/cpu/avr/drv/lcd_32122a_avr.c b/bertos/cpu/avr/drv/lcd_32122a_avr.c new file mode 100644 index 00000000..f635d414 --- /dev/null +++ b/bertos/cpu/avr/drv/lcd_32122a_avr.c @@ -0,0 +1,522 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * + * \brief Displaytech 32122A LCD driver + */ + +#include "lcd_32122a_avr.h" +#include +#include + +#include +#include +#include +#include /* BV() */ +#include + +#include +#include +#include + +/* Configuration sanity checks */ +#if !defined(CONFIG_LCD_SOFTINT_REFRESH) || (CONFIG_LCD_SOFTINT_REFRESH != 0 && CONFIG_LCD_SOFTINT_REFRESH != 1) + #error CONFIG_LCD_SOFTINT_REFRESH must be defined to either 0 or 1 +#endif +#if !defined(CONFIG_LCD_SOFTINT_REFRESH) || (CONFIG_LCD_SOFTINT_REFRESH != 0 && CONFIG_LCD_SOFTINT_REFRESH != 1) + #error CONFIG_LCD_SOFTINT_REFRESH must be defined to either 0 or 1 +#endif + + +#if CONFIG_LCD_SOFTINT_REFRESH + + /** Interval between softint driven lcd refresh */ +# define LCD_REFRESH_INTERVAL 20 /* 20ms -> 50fps */ + +#endif /* CONFIG_LCD_SOFTINT_REFRESH */ + +/** Number of LCD pages */ +#define LCD_PAGES 4 + +/** Width of an LCD page */ +#define LCD_PAGESIZE (LCD_WIDTH / 2) + +/** + * \name LCD I/O pins/ports + * @{ + */ +#define LCD_PF_DB0 PF4 +#define LCD_PF_DB1 PF5 +#define LCD_PF_DB2 PF6 +#define LCD_PF_DB3 PF7 +#define LCD_PD_DB4 PD4 +#define LCD_PD_DB5 PD5 +#define LCD_PD_DB6 PD6 +#define LCD_PD_DB7 PD7 +#define LCD_PB_A0 PB0 +#define LCD_PE_RW PE7 +#define LCD_PE_E1 PE2 +#define LCD_PE_E2 PE6 +/*@}*/ + +/** + * \name DB high nibble (DB[4-7]) + * @{ + */ +#define LCD_DATA_HI_PORT PORTD +#define LCD_DATA_HI_PIN PIND +#define LCD_DATA_HI_DDR DDRD +#define LCD_DATA_HI_SHIFT 0 +#define LCD_DATA_HI_MASK 0xF0 +/*@}*/ + +/** + * \name DB low nibble (DB[0-3]) + * @{ + */ +#define LCD_DATA_LO_PORT PORTF +#define LCD_DATA_LO_PIN PINF +#define LCD_DATA_LO_DDR DDRF +#define LCD_DATA_LO_SHIFT 4 +#define LCD_DATA_LO_MASK 0xF0 +/*@}*/ + +/** + * \name LCD bus control macros + * @{ + */ +#define LCD_CLR_A0 (PORTB &= ~BV(LCD_PB_A0)) +#define LCD_SET_A0 (PORTB |= BV(LCD_PB_A0)) +#define LCD_CLR_RD (PORTE &= ~BV(LCD_PE_RW)) +#define LCD_SET_RD (PORTE |= BV(LCD_PE_RW)) +#define LCD_CLR_E1 (PORTE &= ~BV(LCD_PE_E1)) +#define LCD_SET_E1 (PORTE |= BV(LCD_PE_E1)) +#define LCD_CLR_E2 (PORTE &= ~BV(LCD_PE_E2)) +#define LCD_SET_E2 (PORTE |= BV(LCD_PE_E2)) +#define LCD_SET_E(x) (PORTE |= (x)) +#define LCD_CLR_E(x) (PORTE &= ~(x)) +/*@}*/ + +/** + * \name Chip select bits for LCD_SET_E() + * @{ + */ +#define LCDF_E1 (BV(LCD_PE_E1)) +#define LCDF_E2 (BV(LCD_PE_E2)) +/*@}*/ + +/** Read from the LCD data bus (DB[0-7]) */ +#define LCD_READ ( \ + ((LCD_DATA_LO_PIN & LCD_DATA_LO_MASK) >> LCD_DATA_LO_SHIFT) | \ + ((LCD_DATA_HI_PIN & LCD_DATA_HI_MASK) >> LCD_DATA_HI_SHIFT) \ + ) + +/** Write to the LCD data bus (DB[0-7]) */ +#define LCD_WRITE(d) \ + do { \ + LCD_DATA_LO_PORT = (LCD_DATA_LO_PORT & ~LCD_DATA_LO_MASK) | (((d)<-- + */ + LCD_WRITE(cmd); + //LCD_DB_OUT; + LCD_CLR_A0; + LCD_SET_E(chip); + LCD_DELAY_WRITE; + LCD_CLR_E(chip); + LCD_SET_A0; + //LCD_DB_IN; +} + + +static inline uint8_t lcd_read(uint8_t chip) +{ + uint8_t data; + + WAIT_LCD; + + /** + * \code + * __________________ + * A0 __/ \__ + * ____________ + * R/W __/ \__ + * _______ + * E1 _____/ \____ + * + * DATA -------<=====>---- + * + * \endcode + */ + LCD_DB_IN; + //LCD_SET_A0; + LCD_SET_RD; + LCD_SET_E(chip); + LCD_DELAY_READ; + data = LCD_READ; + LCD_CLR_E(chip); + LCD_CLR_RD; + //LCD_CLR_A0; + LCD_DB_OUT; + + return data; +} + + +static inline void lcd_write(uint8_t c, uint8_t chip) +{ + WAIT_LCD; + + /** + * \code + * __________________ + * A0 ___/ \___ + * + * R/W __________________ + * ______ + * E1 _____/ \_____ + * + * DATA -<==============>- + * + * \endcode + */ + LCD_WRITE(c); + //LCD_DB_OUT; + //LCD_SET_A0; + LCD_SET_E(chip); + LCD_DELAY_WRITE; + LCD_CLR_E(chip); + //LCD_CLR_A0; + //LCD_DB_IN; +} + + +/** + * Set LCD contrast PWM. + */ +void lcd_setPwm(int duty) +{ + ASSERT(duty >= LCD_MIN_PWM); + ASSERT(duty <= LCD_MAX_PWM); + + OCR3C = duty; +} + + +static void lcd_clear(void) +{ + uint8_t page, j; + + for (page = 0; page < LCD_PAGES; ++page) + { + lcd_cmd(LCD_CMD_COLADDR | 0, LCDF_E1 | LCDF_E2); + lcd_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); + for (j = 0; j < LCD_PAGESIZE; j++) + lcd_write(0, LCDF_E1 | LCDF_E2); + } +} + + +static void lcd_writeRaster(const uint8_t *raster) +{ + uint8_t page, rows; + const uint8_t *right_raster; + + CHECK_WALL(wall_before_raster); + CHECK_WALL(wall_after_raster); + + for (page = 0; page < LCD_PAGES; ++page) + { + lcd_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); + lcd_cmd(LCD_CMD_COLADDR | 0, LCDF_E1 | LCDF_E2); + + /* Super optimized lamer loop */ + right_raster = raster + LCD_PAGESIZE; + rows = LCD_PAGESIZE; + do + { + lcd_write(*raster++, LCDF_E1); + lcd_write(*right_raster++, LCDF_E2); + } + while (--rows); + raster = right_raster; + } +} + +/** + * Update the LCD display with data from the provided bitmap. + */ +void lcd_blitBitmap(Bitmap *bm) +{ + MOD_CHECK(lcd); + lcd_writeRaster(bm->raster); +} + + +#if CONFIG_LCD_SOFTINT_REFRESH + +static void lcd_refreshSoftint(void) +{ + lcd_blit_bitmap(&lcd_bitmap); + timer_add(lcd_refresh_timer); +} + +#endif /* CONFIG_LCD_SOFTINT_REFRESH */ + + +/** + * Initialize LCD subsystem. + * + * \note The PWM used for LCD contrast is initialized in drv/pwm.c + * because it is the same PWM used for output attenuation. + */ +void lcd_init(void) +{ + MOD_CHECK(timer); + + // FIXME: interrupts are already disabled when we get here?!? + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + PORTB |= BV(LCD_PB_A0); + DDRB |= BV(LCD_PB_A0); + + PORTE &= ~(BV(LCD_PE_RW) | BV(LCD_PE_E1) | BV(LCD_PE_E2)); + DDRE |= BV(LCD_PE_RW) | BV(LCD_PE_E1) | BV(LCD_PE_E2); + +/* LCD hw reset + LCD_RESET_PORT |= BV(LCD_RESET_BIT); + LCD_RESET_DDR |= BV(LCD_RESET_BIT); + LCD_DELAY_WRITE; + LCD_DELAY_WRITE; + LCD_RESET_PORT &= ~BV(LCD_RESET_BIT); + LCD_DELAY_WRITE; + LCD_DELAY_WRITE; + LCD_RESET_PORT |= BV(LCD_RESET_BIT); +*/ + /* + * Data bus is in output state most of the time: + * LCD r/w functions assume it is left in output state + */ + LCD_DB_OUT; + + // Wait for RST line to stabilize at Vcc. + IRQ_ENABLE; + timer_delay(20); + IRQ_SAVE_DISABLE(flags); + + lcd_cmd(LCD_CMD_RESET, LCDF_E1 | LCDF_E2); + lcd_cmd(LCD_CMD_DISPLAY_ON, LCDF_E1 | LCDF_E2); + lcd_cmd(LCD_CMD_STARTLINE | 0, LCDF_E1 | LCDF_E2); + + /* Initialize anti-corruption walls for raster */ + INIT_WALL(wall_before_raster); + INIT_WALL(wall_after_raster); + + IRQ_RESTORE(flags); + + lcd_clear(); + lcd_setpwm(LCD_DEF_PWM); + + gfx_bitmapInit(&lcd_bitmap, lcd_raster, LCD_WIDTH, LCD_HEIGHT); + gfx_bitmapClear(&lcd_bitmap); + +#if CONFIG_LCD_SOFTINT_REFRESH + + /* Init IRQ driven LCD refresh */ + lcd_refresh_timer = timer_new(); + ASSERT(lcd_refresh_timer != NULL); + INITEVENT_INT(&lcd_refresh_timer->expire, (Hook)lcd_refresh_softint, 0); + lcd_refresh_timer->delay = LCD_REFRESH_INTERVAL; + timer_add(lcd_refresh_timer); + +#endif /* CONFIG_LCD_SOFTINT_REFRESH */ + + MOD_INIT(lcd); +} diff --git a/bertos/cpu/avr/drv/lcd_32122a_avr.h b/bertos/cpu/avr/drv/lcd_32122a_avr.h new file mode 100644 index 00000000..1d23b190 --- /dev/null +++ b/bertos/cpu/avr/drv/lcd_32122a_avr.h @@ -0,0 +1,84 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * + * \brief Displaytech 32122A LCD driver + */ + +/*#* + *#* $Log$ + *#* Revision 1.6 2006/07/19 12:56:25 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.5 2006/04/27 05:40:11 bernie + *#* Naming convention fixes; Partial merge from project_grl. + *#* + *#* Revision 1.4 2006/02/15 09:13:16 bernie + *#* Switch to BITMAP_FMT_PLANAR_V_LSB. + *#* + *#* Revision 1.3 2006/02/10 12:33:51 bernie + *#* Make emulator display a bit larger. + *#* + *#* Revision 1.2 2006/01/17 22:59:48 bernie + *#* Hardcode a different display size. + *#* + *#* Revision 1.1 2006/01/16 03:50:57 bernie + *#* Import into DevLib. + *#*/ + +#ifndef LCD_32122A_AVR_H +#define LCD_32122A_AVR_H + +/* Predefined LCD PWM contrast values */ +#define LCD_DEF_PWM 145 +#define LCD_MAX_PWM 505 +#define LCD_MIN_PWM 130 + +/* Display bitmap dims */ +#define LCD_WIDTH 122 +#define LCD_HEIGHT 32 + +/* fwd decl */ +struct Bitmap; + +extern struct Bitmap lcd_bitmap; + +void lcd_init(void); +void lcd_setPwm(int duty); +void lcd_blitBitmap(struct Bitmap *bm); + +#endif /* LCD_32122A_AVR_H */ diff --git a/bertos/cpu/avr/drv/ser_avr.c b/bertos/cpu/avr/drv/ser_avr.c new file mode 100644 index 00000000..e9e1f5ec --- /dev/null +++ b/bertos/cpu/avr/drv/ser_avr.c @@ -0,0 +1,965 @@ +/** + * \file + * + * + * \brief AVR UART and SPI I/O driver + * + * Rationale for project_ks hardware. + * + * The serial 0 on the board_kf board is used to communicate with the + * smart card, which has the TX and RX lines connected together. To + * allow the smart card to drive the RX line of the CPU the CPU TX has + * to be in a high impedance state. + * Whenever a transmission is done and there is nothing more to send + * the transmitter is turn off. The output pin is held in input with + * pull-up enabled, to avoid capturing noise from the nearby RX line. + * + * The line on the KBus port must keep sending data, even when + * there is nothing to transmit, because a burst data transfer + * generates noise on the audio channels. + * This is accomplished using the multiprocessor mode of the + * ATmega64/128 serial. + * + * The receiver keeps the MPCM bit always on. When useful data + * is trasmitted the address bit is set. The receiver hardware + * consider the frame as address info and receive it. + * When useless fill bytes are sent the address bit is cleared + * and the receiver will ignore them, avoiding useless triggering + * of RXC interrupt. + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Stefano Fedrigo + */ + +#include +#include + +#include /* Required for bus macros overrides */ +#include /* CLOCK_FREQ */ +#include + +#include /* DIV_ROUND */ +#include +#include +#include + +#include +#if defined(__AVR_LIBC_VERSION__) && (__AVR_LIBC_VERSION__ >= 10400UL) + #include +#else + #include +#endif + + +#if !CONFIG_SER_HWHANDSHAKE + /** + * \name Hardware handshake (RTS/CTS). + * \{ + */ + #define RTS_ON do {} while (0) + #define RTS_OFF do {} while (0) + #define IS_CTS_ON true + #define EIMSKF_CTS 0 /**< Dummy value, must be overridden */ + /*\}*/ +#endif + +#if CPU_AVR_ATMEGA1281 + #define BIT_RXCIE0 RXCIE0 + #define BIT_RXEN0 RXEN0 + #define BIT_TXEN0 TXEN0 + #define BIT_UDRIE0 UDRIE0 + + #define BIT_RXCIE1 RXCIE1 + #define BIT_RXEN1 RXEN1 + #define BIT_TXEN1 TXEN1 + #define BIT_UDRIE1 UDRIE1 +#else + #define BIT_RXCIE0 RXCIE + #define BIT_RXEN0 RXEN + #define BIT_TXEN0 TXEN + #define BIT_UDRIE0 UDRIE + + #define BIT_RXCIE1 RXCIE + #define BIT_RXEN1 RXEN + #define BIT_TXEN1 TXEN + #define BIT_UDRIE1 UDRIE +#endif + + +/** + * \name Overridable serial bus hooks + * + * These can be redefined in hw.h to implement + * special bus policies such as half-duplex, 485, etc. + * + * + * \code + * TXBEGIN TXCHAR TXEND TXOFF + * | __________|__________ | | + * | | | | | | | | | + * v v v v v v v v v + * ______ __ __ __ __ __ __ ________________ + * \/ \/ \/ \/ \/ \/ \/ + * ______/\__/\__/\__/\__/\__/\__/ + * + * \endcode + * + * \{ + */ +#ifndef SER_UART0_BUS_TXINIT + /** + * Default TXINIT macro - invoked in uart0_init() + * + * - Enable both the receiver and the transmitter + * - Enable only the RX complete interrupt + */ + #define SER_UART0_BUS_TXINIT do { \ + UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ + } while (0) +#endif + +#ifndef SER_UART0_BUS_TXBEGIN + /** + * Invoked before starting a transmission + * + * - Enable both the receiver and the transmitter + * - Enable both the RX complete and UDR empty interrupts + */ + #define SER_UART0_BUS_TXBEGIN do { \ + UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ + } while (0) +#endif + +#ifndef SER_UART0_BUS_TXCHAR + /** + * Invoked to send one character. + */ + #define SER_UART0_BUS_TXCHAR(c) do { \ + UDR0 = (c); \ + } while (0) +#endif + +#ifndef SER_UART0_BUS_TXEND + /** + * Invoked as soon as the txfifo becomes empty + * + * - Keep both the receiver and the transmitter enabled + * - Keep the RX complete interrupt enabled + * - Disable the UDR empty interrupt + */ + #define SER_UART0_BUS_TXEND do { \ + UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ + } while (0) +#endif + +#ifndef SER_UART0_BUS_TXOFF + /** + * \def SER_UART0_BUS_TXOFF + * + * Invoked after the last character has been transmitted + * + * The default is no action. + */ + #ifdef __doxygen__ + #define SER_UART0_BUS_TXOFF + #endif +#endif + +#ifndef SER_UART1_BUS_TXINIT + /** \sa SER_UART0_BUS_TXINIT */ + #define SER_UART1_BUS_TXINIT do { \ + UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ + } while (0) +#endif +#ifndef SER_UART1_BUS_TXBEGIN + /** \sa SER_UART0_BUS_TXBEGIN */ + #define SER_UART1_BUS_TXBEGIN do { \ + UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ + } while (0) +#endif +#ifndef SER_UART1_BUS_TXCHAR + /** \sa SER_UART0_BUS_TXCHAR */ + #define SER_UART1_BUS_TXCHAR(c) do { \ + UDR1 = (c); \ + } while (0) +#endif +#ifndef SER_UART1_BUS_TXEND + /** \sa SER_UART0_BUS_TXEND */ + #define SER_UART1_BUS_TXEND do { \ + UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ + } while (0) +#endif +#ifndef SER_UART1_BUS_TXOFF + /** + * \def SER_UART1_BUS_TXOFF + * + * \see SER_UART0_BUS_TXOFF + */ + #ifdef __doxygen__ + #define SER_UART1_BUS_TXOFF + #endif +#endif +/*\}*/ + + +/** + * \name Overridable SPI hooks + * + * These can be redefined in hw.h to implement + * special bus policies such as slave select pin handling, etc. + * + * \{ + */ +#ifndef SER_SPI_BUS_TXINIT + /** + * Default TXINIT macro - invoked in spi_init() + * The default is no action. + */ + #define SER_SPI_BUS_TXINIT +#endif + +#ifndef SER_SPI_BUS_TXCLOSE + /** + * Invoked after the last character has been transmitted. + * The default is no action. + */ + #define SER_SPI_BUS_TXCLOSE +#endif +/*\}*/ + + +/* SPI port and pin configuration */ +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281 + #define SPI_PORT PORTB + #define SPI_DDR DDRB + #define SPI_SS_BIT PB0 + #define SPI_SCK_BIT PB1 + #define SPI_MOSI_BIT PB2 + #define SPI_MISO_BIT PB3 +#elif CPU_AVR_ATMEGA8 + #define SPI_PORT PORTB + #define SPI_DDR DDRB + #define SPI_SS_BIT PB2 + #define SPI_SCK_BIT PB5 + #define SPI_MOSI_BIT PB3 + #define SPI_MISO_BIT PB4 +#else + #error Unknown architecture +#endif + +/* USART register definitions */ +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 + #define AVR_HAS_UART1 1 +#elif CPU_AVR_ATMEGA8 + #define AVR_HAS_UART1 0 + #define UCSR0A UCSRA + #define UCSR0B UCSRB + #define UCSR0C UCSRC + #define UDR0 UDR + #define UBRR0L UBRRL + #define UBRR0H UBRRH + #define SIG_UART0_DATA SIG_UART_DATA + #define SIG_UART0_RECV SIG_UART_RECV + #define SIG_UART0_TRANS SIG_UART_TRANS +#elif CPU_AVR_ATMEGA103 + #define AVR_HAS_UART1 0 + #define UCSR0B UCR + #define UDR0 UDR + #define UCSR0A USR + #define UBRR0L UBRR + #define SIG_UART0_DATA SIG_UART_DATA + #define SIG_UART0_RECV SIG_UART_RECV + #define SIG_UART0_TRANS SIG_UART_TRANS +#else + #error Unknown architecture +#endif + + +/** + * \def CONFIG_SER_STROBE + * + * This is a debug facility that can be used to + * monitor SER interrupt activity on an external pin. + * + * To use strobes, redefine the macros SER_STROBE_ON, + * SER_STROBE_OFF and SER_STROBE_INIT and set + * CONFIG_SER_STROBE to 1. + */ +#if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE + #define SER_STROBE_ON do {/*nop*/} while(0) + #define SER_STROBE_OFF do {/*nop*/} while(0) + #define SER_STROBE_INIT do {/*nop*/} while(0) +#endif + + +/* From the high-level serial driver */ +extern struct Serial ser_handles[SER_CNT]; + +/* TX and RX buffers */ +static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; +static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; +#if AVR_HAS_UART1 + static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; + static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; +#endif +static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE]; +static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE]; + + +/** + * Internal hardware state structure + * + * The \a sending variable is true while the transmission + * interrupt is retriggering itself. + * + * For the USARTs the \a sending flag is useful for taking specific + * actions before sending a burst of data, at the start of a trasmission + * but not before every char sent. + * + * For the SPI, this flag is necessary because the SPI sends and receives + * bytes at the same time and the SPI IRQ is unique for send/receive. + * The only way to start transmission is to write data in SPDR (this + * is done by spi_starttx()). We do this *only* if a transfer is + * not already started. + */ +struct AvrSerial +{ + struct SerialHardware hw; + volatile bool sending; +}; + + +/* + * These are to trick GCC into *not* using absolute addressing mode + * when accessing ser_handles, which is very expensive. + * + * Accessing through these pointers generates much shorter + * (and hopefully faster) code. + */ +struct Serial *ser_uart0 = &ser_handles[SER_UART0]; +#if AVR_HAS_UART1 +struct Serial *ser_uart1 = &ser_handles[SER_UART1]; +#endif +struct Serial *ser_spi = &ser_handles[SER_SPI]; + + + +/* + * Callbacks + */ +static void uart0_init( + UNUSED_ARG(struct SerialHardware *, _hw), + UNUSED_ARG(struct Serial *, ser)) +{ + SER_UART0_BUS_TXINIT; + RTS_ON; + SER_STROBE_INIT; +} + +static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + UCSR0B = 0; +} + +static void uart0_enabletxirq(struct SerialHardware *_hw) +{ + struct AvrSerial *hw = (struct AvrSerial *)_hw; + + /* + * WARNING: racy code here! The tx interrupt sets hw->sending to false + * when it runs with an empty fifo. The order of statements in the + * if-block matters. + */ + if (!hw->sending) + { + hw->sending = true; + SER_UART0_BUS_TXBEGIN; + } +} + +static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + /* Compute baud-rate period */ + uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; + +#if !CPU_AVR_ATMEGA103 + UBRR0H = (period) >> 8; +#endif + UBRR0L = (period); + + //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) +} + +static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) +{ +#if !CPU_AVR_ATMEGA103 + UCSR0C = (UCSR0C & ~(BV(UPM01) | BV(UPM00))) | ((parity) << UPM00); +#endif +} + +#if AVR_HAS_UART1 + +static void uart1_init( + UNUSED_ARG(struct SerialHardware *, _hw), + UNUSED_ARG(struct Serial *, ser)) +{ + SER_UART1_BUS_TXINIT; + RTS_ON; + SER_STROBE_INIT; +} + +static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + UCSR1B = 0; +} + +static void uart1_enabletxirq(struct SerialHardware *_hw) +{ + struct AvrSerial *hw = (struct AvrSerial *)_hw; + + /* + * WARNING: racy code here! The tx interrupt + * sets hw->sending to false when it runs with + * an empty fifo. The order of the statements + * in the if-block matters. + */ + if (!hw->sending) + { + hw->sending = true; + SER_UART1_BUS_TXBEGIN; + } +} + +static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) +{ + /* Compute baud-rate period */ + uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; + + UBRR1H = (period) >> 8; + UBRR1L = (period); + + //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);) +} + +static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) +{ + UCSR1C = (UCSR1C & ~(BV(UPM11) | BV(UPM10))) | ((parity) << UPM10); +} + +#endif // AVR_HAS_UART1 + +static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) +{ + /* + * Set MOSI and SCK ports out, MISO in. + * + * The ATmega64/128 datasheet explicitly states that the input/output + * state of the SPI pins is not significant, as when the SPI is + * active the I/O port are overrided. + * This is *blatantly FALSE*. + * + * Moreover, the MISO pin on the board_kc *must* be in high impedance + * state even when the SPI is off, because the line is wired together + * with the KBus serial RX, and the transmitter of the slave boards + * would be unable to drive the line. + */ + ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT))); + + /* + * If the SPI master mode is activated and the SS pin is in input and tied low, + * the SPI hardware will automatically switch to slave mode! + * For proper communication this pins should therefore be: + * - as output + * - as input but tied high forever! + * This driver set the pin as output. + */ + #warning SPI SS pin set as output for proper operation, check schematics for possible conflicts. + ATOMIC(SPI_DDR |= BV(SPI_SS_BIT)); + + ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT)); + /* Enable SPI, IRQ on, Master */ + SPCR = BV(SPE) | BV(SPIE) | BV(MSTR); + + /* Set data order */ + #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST + SPCR |= BV(DORD); + #endif + + /* Set SPI clock rate */ + #if CONFIG_SPI_CLOCK_DIV == 128 + SPCR |= (BV(SPR1) | BV(SPR0)); + #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32) + SPCR |= BV(SPR1); + #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8) + SPCR |= BV(SPR0); + #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2) + // SPR0 & SDPR1 both at 0 + #else + #error Unsupported SPI clock division factor. + #endif + + /* Set SPI2X bit (spi double frequency) */ + #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \ + || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4) + SPSR &= ~BV(SPI2X); + #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2) + SPSR |= BV(SPI2X); + #else + #error Unsupported SPI clock division factor. + #endif + + /* Set clock polarity */ + #if CONFIG_SPI_CLOCK_POL == 1 + SPCR |= BV(CPOL); + #endif + + /* Set clock phase */ + #if CONFIG_SPI_CLOCK_PHASE == 1 + SPCR |= BV(CPHA); + #endif + SER_SPI_BUS_TXINIT; + + SER_STROBE_INIT; +} + +static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) +{ + SPCR = 0; + + SER_SPI_BUS_TXCLOSE; + + /* Set all pins as inputs */ + ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT))); +} + +static void spi_starttx(struct SerialHardware *_hw) +{ + struct AvrSerial *hw = (struct AvrSerial *)_hw; + + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Send data only if the SPI is not already transmitting */ + if (!hw->sending && !fifo_isempty(&ser_spi->txfifo)) + { + hw->sending = true; + SPDR = fifo_pop(&ser_spi->txfifo); + } + + IRQ_RESTORE(flags); +} + +static void spi_setbaudrate( + UNUSED_ARG(struct SerialHardware *, _hw), + UNUSED_ARG(unsigned long, rate)) +{ + // nop +} + +static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity)) +{ + // nop +} + +static bool tx_sending(struct SerialHardware* _hw) +{ + struct AvrSerial *hw = (struct AvrSerial *)_hw; + return hw->sending; +} + + + +// FIXME: move into compiler.h? Ditch? +#if COMPILER_C99 + #define C99INIT(name,val) .name = val +#elif defined(__GNUC__) + #define C99INIT(name,val) name: val +#else + #warning No designated initializers, double check your code + #define C99INIT(name,val) (val) +#endif + +/* + * High-level interface data structures + */ +static const struct SerialHardwareVT UART0_VT = +{ + C99INIT(init, uart0_init), + C99INIT(cleanup, uart0_cleanup), + C99INIT(setBaudrate, uart0_setbaudrate), + C99INIT(setParity, uart0_setparity), + C99INIT(txStart, uart0_enabletxirq), + C99INIT(txSending, tx_sending), +}; + +#if AVR_HAS_UART1 +static const struct SerialHardwareVT UART1_VT = +{ + C99INIT(init, uart1_init), + C99INIT(cleanup, uart1_cleanup), + C99INIT(setBaudrate, uart1_setbaudrate), + C99INIT(setParity, uart1_setparity), + C99INIT(txStart, uart1_enabletxirq), + C99INIT(txSending, tx_sending), +}; +#endif // AVR_HAS_UART1 + +static const struct SerialHardwareVT SPI_VT = +{ + C99INIT(init, spi_init), + C99INIT(cleanup, spi_cleanup), + C99INIT(setBaudrate, spi_setbaudrate), + C99INIT(setParity, spi_setparity), + C99INIT(txStart, spi_starttx), + C99INIT(txSending, tx_sending), +}; + +static struct AvrSerial UARTDescs[SER_CNT] = +{ + { + C99INIT(hw, /**/) { + C99INIT(table, &UART0_VT), + C99INIT(txbuffer, uart0_txbuffer), + C99INIT(rxbuffer, uart0_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart0_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)), + }, + C99INIT(sending, false), + }, +#if AVR_HAS_UART1 + { + C99INIT(hw, /**/) { + C99INIT(table, &UART1_VT), + C99INIT(txbuffer, uart1_txbuffer), + C99INIT(rxbuffer, uart1_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart1_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)), + }, + C99INIT(sending, false), + }, +#endif + { + C99INIT(hw, /**/) { + C99INIT(table, &SPI_VT), + C99INIT(txbuffer, spi_txbuffer), + C99INIT(rxbuffer, spi_rxbuffer), + C99INIT(txbuffer_size, sizeof(spi_txbuffer)), + C99INIT(rxbuffer_size, sizeof(spi_rxbuffer)), + }, + C99INIT(sending, false), + } +}; + +struct SerialHardware *ser_hw_getdesc(int unit) +{ + ASSERT(unit < SER_CNT); + return &UARTDescs[unit].hw; +} + + +/* + * Interrupt handlers + */ + +#if CONFIG_SER_HWHANDSHAKE + +/// This interrupt is triggered when the CTS line goes high +SIGNAL(SIG_CTS) +{ + // Re-enable UDR empty interrupt and TX, then disable CTS interrupt + UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); + EIMSK &= ~EIMSKF_CTS; +} + +#endif // CONFIG_SER_HWHANDSHAKE + + +/** + * Serial 0 TX interrupt handler + */ +SIGNAL(USART0_UDRE_vect) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; + + if (fifo_isempty(txfifo)) + { + SER_UART0_BUS_TXEND; +#ifndef SER_UART0_BUS_TXOFF + UARTDescs[SER_UART0].sending = false; +#endif + } +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 + else if (!IS_CTS_ON) + { + // Disable rx interrupt and tx, enable CTS interrupt + // UNTESTED + UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN); + EIFR |= EIMSKF_CTS; + EIMSK |= EIMSKF_CTS; + } +#endif + else + { + char c = fifo_pop(txfifo); + SER_UART0_BUS_TXCHAR(c); + } + + SER_STROBE_OFF; +} + +#ifdef SER_UART0_BUS_TXOFF +/** + * Serial port 0 TX complete interrupt handler. + * + * This IRQ is usually disabled. The UDR-empty interrupt + * enables it when there's no more data to transmit. + * We need to wait until the last character has been + * transmitted before switching the 485 transceiver to + * receive mode. + * + * The txfifo might have been refilled by putchar() while + * we were waiting for the transmission complete interrupt. + * In this case, we must restart the UDR empty interrupt, + * otherwise we'd stop the serial port with some data + * still pending in the buffer. + */ +SIGNAL(SIG_UART0_TRANS) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; + if (fifo_isempty(txfifo)) + { + SER_UART0_BUS_TXOFF; + UARTDescs[SER_UART0].sending = false; + } + else + UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); + + SER_STROBE_OFF; +} +#endif /* SER_UART0_BUS_TXOFF */ + + +#if AVR_HAS_UART1 + +/** + * Serial 1 TX interrupt handler + */ +SIGNAL(USART1_UDRE_vect) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; + + if (fifo_isempty(txfifo)) + { + SER_UART1_BUS_TXEND; +#ifndef SER_UART1_BUS_TXOFF + UARTDescs[SER_UART1].sending = false; +#endif + } +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 + else if (!IS_CTS_ON) + { + // Disable rx interrupt and tx, enable CTS interrupt + // UNTESTED + UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN); + EIFR |= EIMSKF_CTS; + EIMSK |= EIMSKF_CTS; + } +#endif + else + { + char c = fifo_pop(txfifo); + SER_UART1_BUS_TXCHAR(c); + } + + SER_STROBE_OFF; +} + +#ifdef SER_UART1_BUS_TXOFF +/** + * Serial port 1 TX complete interrupt handler. + * + * \sa port 0 TX complete handler. + */ +SIGNAL(SIG_UART1_TRANS) +{ + SER_STROBE_ON; + + struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; + if (fifo_isempty(txfifo)) + { + SER_UART1_BUS_TXOFF; + UARTDescs[SER_UART1].sending = false; + } + else + UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); + + SER_STROBE_OFF; +} +#endif /* SER_UART1_BUS_TXOFF */ + +#endif // AVR_HAS_UART1 + + +/** + * Serial 0 RX complete interrupt handler. + * + * This handler is interruptible. + * Interrupt are reenabled as soon as recv complete interrupt is + * disabled. Using INTERRUPT() is troublesome when the serial + * is heavily loaded, because an interrupt could be retriggered + * when executing the handler prologue before RXCIE is disabled. + * + * \note The code that re-enables interrupts is commented out + * because in some nasty cases the interrupt is retriggered. + * This is probably due to the RXC flag being set before + * RXCIE is cleared. Unfortunately the RXC flag is read-only + * and can't be cleared by code. + */ +SIGNAL(USART0_RX_vect) +{ + SER_STROBE_ON; + + /* Disable Recv complete IRQ */ + //UCSR0B &= ~BV(RXCIE); + //IRQ_ENABLE; + + /* Should be read before UDR */ + ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); + + /* To clear the RXC flag we must _always_ read the UDR even when we're + * not going to accept the incoming data, otherwise a new interrupt + * will occur once the handler terminates. + */ + char c = UDR0; + struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo; + + if (fifo_isfull(rxfifo)) + ser_uart0->status |= SERRF_RXFIFOOVERRUN; + else + { + fifo_push(rxfifo, c); +#if CONFIG_SER_HWHANDSHAKE + if (fifo_isfull(rxfifo)) + RTS_OFF; +#endif + } + + /* Reenable receive complete int */ + //IRQ_DISABLE; + //UCSR0B |= BV(RXCIE); + + SER_STROBE_OFF; +} + + +#if AVR_HAS_UART1 + +/** + * Serial 1 RX complete interrupt handler. + * + * This handler is interruptible. + * Interrupt are reenabled as soon as recv complete interrupt is + * disabled. Using INTERRUPT() is troublesome when the serial + * is heavily loaded, because an interrupt could be retriggered + * when executing the handler prologue before RXCIE is disabled. + * + * \see SIGNAL(USART1_RX_vect) + */ +SIGNAL(USART1_RX_vect) +{ + SER_STROBE_ON; + + /* Disable Recv complete IRQ */ + //UCSR1B &= ~BV(RXCIE); + //IRQ_ENABLE; + + /* Should be read before UDR */ + ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); + + /* To avoid an IRQ storm, we must _always_ read the UDR even when we're + * not going to accept the incoming data + */ + char c = UDR1; + struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo; + //ASSERT_VALID_FIFO(rxfifo); + + if (UNLIKELY(fifo_isfull(rxfifo))) + ser_uart1->status |= SERRF_RXFIFOOVERRUN; + else + { + fifo_push(rxfifo, c); +#if CONFIG_SER_HWHANDSHAKE + if (fifo_isfull(rxfifo)) + RTS_OFF; +#endif + } + /* Re-enable receive complete int */ + //IRQ_DISABLE; + //UCSR1B |= BV(RXCIE); + + SER_STROBE_OFF; +} + +#endif // AVR_HAS_UART1 + + +/** + * SPI interrupt handler + */ +SIGNAL(SIG_SPI) +{ + SER_STROBE_ON; + + /* Read incoming byte. */ + if (!fifo_isfull(&ser_spi->rxfifo)) + fifo_push(&ser_spi->rxfifo, SPDR); + /* + * FIXME + else + ser_spi->status |= SERRF_RXFIFOOVERRUN; + */ + + /* Send */ + if (!fifo_isempty(&ser_spi->txfifo)) + SPDR = fifo_pop(&ser_spi->txfifo); + else + UARTDescs[SER_SPI].sending = false; + + SER_STROBE_OFF; +} diff --git a/bertos/cpu/avr/drv/ser_avr.h b/bertos/cpu/avr/drv/ser_avr.h new file mode 100644 index 00000000..4b5518b4 --- /dev/null +++ b/bertos/cpu/avr/drv/ser_avr.h @@ -0,0 +1,84 @@ +/** + * \file + * + * + * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ + * + * \author Daniele Basile + * + * \brief Low-level serial module for AVR (interface). + */ + +#ifndef DRV_SER_AVR_H +#define DRV_SER_AVR_H + +#include /* BV() */ +#include /* uint32_t */ + +typedef uint8_t serstatus_t; + +/* Software errors */ +#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ +#define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */ +#define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */ + +/* +* Hardware errors. +* These flags map directly to the AVR UART Status Register (USR). +*/ +#define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */ +#define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */ +#define SERRF_PARITYERROR BV(7) /**< Parity error */ +#define SERRF_NOISEERROR 0 /**< Unsupported */ + + +/** + * \name Serial hw numbers + * + * \{ + */ +enum +{ +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 + SER_UART0, + SER_UART1, + SER_SPI, +#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8 + SER_UART0, + SER_SPI, +#else + #error unknown architecture +#endif + SER_CNT /**< Number of serial ports */ +}; +/*\}*/ + +#endif /* DRV_SER_AVR_H */ diff --git a/bertos/cpu/avr/drv/ser_simple_avr.c b/bertos/cpu/avr/drv/ser_simple_avr.c new file mode 100644 index 00000000..d71ce585 --- /dev/null +++ b/bertos/cpu/avr/drv/ser_simple_avr.c @@ -0,0 +1,194 @@ +/** + * \file + * + * + * \brief Simple serial I/O driver + * + * \version $Id$ + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.2 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.1 2005/04/12 01:37:50 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.7 2005/01/23 12:24:27 bernie + *#* Include macros.h for BV(). + *#* + *#* Revision 1.6 2004/10/20 13:40:54 batt + *#* Put {} instead of ; after while loop. + *#* + *#* Revision 1.5 2004/10/20 13:39:40 batt + *#* Reformat. + *#* + *#* Revision 1.4 2004/10/20 13:30:02 batt + *#* Optimization of UCSR0C writing + *#* + *#* Revision 1.3 2004/10/14 15:55:32 batt + *#* Add ser_purge. + *#* + *#* Revision 1.2 2004/10/14 14:46:59 batt + *#* Change baudrate calculation. + *#* + *#* Revision 1.1 2004/10/13 16:35:36 batt + *#* New (simple) serial driver. + *#*/ +#include "ser_simple.h" + +#include +#include +#include /* BV() */ +#include + +#include + +/** + * Send a character over the serial line. + * + * \return the character sent. + */ +int _ser_putchar(int c) +{ + /* Disable Rx to avoid echo*/ + UCSR0B &= ~BV(RXEN); + /* Enable tx*/ + UCSR0B |= BV(TXEN); + /* Prepare transmission */ + UDR0 = c; + /* Wait until byte sent */ + while (!(UCSR0A & BV(TXC))) {} + /* Disable tx to avoid short circuit when tx and rx share the same wire. */ + UCSR0B &= ~BV(TXEN); + /* Enable Rx */ + UCSR0B |= BV(RXEN); + /* Delete TRANSMIT_COMPLETE_BIT flag */ + UCSR0A |= BV(TXC); + return c; +} + + +/** + * Get a character from the serial line. + * If ther is no character in the buffer this function wait until + * one is received (no timeout). + * + * \return the character received. + */ +int _ser_getchar(void) +{ + /* Wait for data */ + while (!(UCSR0A & BV(RXC))) {} + return UDR0; + +} + + +/** + * Get a character from the receiver buffer + * If the buffer is empty, ser_getchar_nowait() returns + * immediatly EOF. + */ +int _ser_getchar_nowait(void) +{ + if (!(UCSR0A & BV(RXC))) return EOF; + else return UDR0; +} + +void _ser_settimeouts(void) +{ +} + +/** + * Set the baudrate. + */ +void _ser_setbaudrate(unsigned long rate) +{ + /* Compute baud-rate period */ + uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; + + UBRR0H = (period) >> 8; + UBRR0L = (period); +} + +/** + * Send a string. + */ +int _ser_print(const char *s) +{ + while(*s) _ser_putchar(*s++); + return 0; +} + + +void _ser_setparity(int parity) +{ + /* Set the new parity */ + UCSR0C |= (UCSR0C & ~(BV(UPM1) | BV(UPM0))) | (parity << UPM0); +} + +/** + * Dummy functions. + */ +void _ser_purge(void) +{ + while (_ser_getchar_nowait() != EOF) {} +} + +/** + * Initialize serial. + */ +struct Serial * _ser_open(void) +{ + /* + * Set Rx and Tx pins as input to avoid short + * circuit when serial is disabled. + */ + DDRE &= ~(BV(PE0)|BV(PE1)); + PORTE &= ~BV(PE0); + PORTE |= BV(PE1); + /* Enable only Rx section */ + UCSR0B = BV(RXEN); + return NULL; +} + + +/** + * Clean up serial port, disabling the associated hardware. + */ +void _ser_close(void) +{ + /* Disable Rx & Tx. */ + UCSR0B &= ~(BV(RXEN) | BV(TXEN)); +} diff --git a/bertos/cpu/avr/drv/ser_simple_avr.h b/bertos/cpu/avr/drv/ser_simple_avr.h new file mode 100644 index 00000000..ec4cf604 --- /dev/null +++ b/bertos/cpu/avr/drv/ser_simple_avr.h @@ -0,0 +1,171 @@ +/** + * \file + * + * + * \brief Simple serial I/O driver + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.2 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.1 2005/04/12 01:37:50 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.5 2004/10/20 13:37:49 batt + *#* Change testing of simple serial instead of ARCH_BOOT in sc driver. + *#* + *#* Revision 1.4 2004/10/15 12:22:04 batt + *#* Readd ';' in setstatus macro. + *#* + *#* Revision 1.3 2004/10/15 12:13:57 batt + *#* Correct \brief header. + *#* + *#* Revision 1.2 2004/10/15 11:54:21 batt + *#* Reformat. + *#* + *#* Revision 1.1 2004/10/13 16:35:36 batt + *#* New (simple) serial driver. + *#* + *#* + */ +#ifndef SER_SIMPLE_H +#define SER_SIMPLE_H + +/* For checking which serial driver is linked */ +#define SER_SIMPLE + +#include +#include + + +#if 0 +#if CPU_AVR + typedef uint8_t serstatus_t; + + /* Software errors */ + #define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ + #define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */ + #define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */ + + /* Hardware errors */ + #define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */ + #define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */ + #define SERRF_PARITYERROR BV(7) /**< Parity error */ +#else + #error unknown architecture +#endif +/*\}*/ + +/** + * \name Serial hw numbers + * + * \{ + */ +enum +{ +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 + SER_UART0, + SER_UART1, + SER_SPI, +#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8 + SER_UART0, + SER_SPI, +#else + #error unknown architecture +#endif + SER_CNT /**< Number of serial ports */ +}; +/*\}*/ +#endif + +/** \name Parity settings for ser_setparity() */ +/*\{*/ +#define SER_PARITY_NONE 0 +#define SER_PARITY_EVEN 2 +#define SER_PARITY_ODD 3 +/*\}*/ + + +/** Serial handle structure */ +struct Serial; + +/* Function prototypes */ +extern int _ser_putchar(int c); +extern int _ser_getchar(void); +extern int _ser_getchar_nowait(void); +/* +extern int ser_write(struct Serial *port, const void *buf, size_t len); +extern int ser_read(struct Serial *port, void *buf, size_t size); + +extern int ser_printf(struct Serial *port, const char *format, ...) FORMAT(__printf__, 2, 3); + +extern int ser_gets(struct Serial *port, char *buf, int size); +extern int ser_gets_echo(struct Serial *port, char *buf, int size, bool echo); +*/ +extern int _ser_print(const char *s); + +extern void _ser_setbaudrate(unsigned long rate); +extern void _ser_setparity(int parity); +extern void _ser_settimeouts(void); +extern void _ser_setstatus(void); +/* +extern void ser_resync(struct Serial *port, time_t delay); +extern void ser_drain(struct Serial *port); +*/ +extern void _ser_purge(void); +extern struct Serial *_ser_open(void); +extern void _ser_close(void); + +/** + * \name Functions implemented as macros + * + * \{ + */ +#define ser_putchar(c, port) _ser_putchar(c) +#define ser_getchar(port) _ser_getchar() +#define ser_getchar_nowait(port) _ser_getchar_nowait() +#define ser_print(port, s) _ser_print(s) +#define ser_setbaudrate(port, y) _ser_setbaudrate(y) +#define ser_setparity(port, par) _ser_setparity(par) +#define ser_settimeouts(port, y, z) _ser_settimeouts() +#define ser_purge(port) _ser_purge() +#define ser_open(port) _ser_open() +#define ser_getstatus(h) 0 +#define ser_setstatus(h, x) do {(void)(x);} while(0) +/* \} */ + +#endif /* SER_SIMPLE_H */ diff --git a/bertos/cpu/avr/drv/sipo.c b/bertos/cpu/avr/drv/sipo.c new file mode 100644 index 00000000..014f9463 --- /dev/null +++ b/bertos/cpu/avr/drv/sipo.c @@ -0,0 +1,80 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Andrea Grandi + * + * \brief SIPO Module + * + * The SIPO module trasform a serial input in + * a parallel output. Please check hw_sipo.h + * file to customize hardware relative parameters. + * + */ + +#include +#include "sipo.h" + +Serial *sipo_port; + +/** Initialize the SIPO port */ +void sipo_init(void) +{ + CLOCK_LOW; + SET_SOUT_LOW; + LOAD_LOW; + SET_SCK_OUT; + SET_SOUT_OUT; + LOAD_INIT; + sipo_putchar(0x0); + OE_OUT; + OE_LOW; +} + +/** Write a char in the SIPO port and manage the LOAD pin */ +void sipo_putchar(uint8_t c) +{ + for(int i = 0; i <= 7; i++) + { + if((c & BV(i)) == 0) + SET_SOUT_LOW; + else + SET_SOUT_HIGH; + + CLOCK_PULSE; + } + + LOAD_HIGH; + LOAD_LOW; +} + diff --git a/bertos/cpu/avr/drv/sipo.h b/bertos/cpu/avr/drv/sipo.h new file mode 100644 index 00000000..15df226a --- /dev/null +++ b/bertos/cpu/avr/drv/sipo.h @@ -0,0 +1,51 @@ +/** + * \file + * + * + * \brief Macro for SIPO_H + * + * + * \version $Id$ + * + * \author Andrea Grandi + */ + +#ifndef SIPO_H +#define SIPO_H + +#include +#include + +void sipo_init(void); +void sipo_putchar(uint8_t c); + +#endif // SIPO_H + diff --git a/bertos/cpu/avr/drv/timer_avr.c b/bertos/cpu/avr/drv/timer_avr.c new file mode 100644 index 00000000..4fd82f53 --- /dev/null +++ b/bertos/cpu/avr/drv/timer_avr.c @@ -0,0 +1,245 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * \author Francesco Sacchi + * + * \brief Low-level timer module for AVR (implementation). + */ + +#include +#include // BV() + +#include +#include + +#include +#include + +#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 + #define REG_TIFR0 TIFR0 + #define REG_TIFR2 TIFR2 + + #define REG_TIMSK0 TIMSK0 + #define REG_TIMSK2 TIMSK2 + + #define REG_TCCR2A TCCR2A + #define REG_TCCR2B TCCR2B + + #define REG_OCR2A OCR2A + + #define BIT_OCF0A OCF0A + #define BIT_OCF2A OCF2A + + #define BIT_OCIE0A OCIE0A + #define BIT_OCIE2A OCIE2A +#else + #define REG_TIFR0 TIFR + #define REG_TIFR2 TIFR + + #define REG_TIMSK0 TIMSK + #define REG_TIMSK2 TIMSK + + #define REG_TCCR2A TCCR2 + #define REG_TCCR2B TCCR2 + + #define REG_OCR2A OCR2 + + #define BIT_OCF0A OCF0 + #define BIT_OCF2A OCF2 + + #define BIT_OCIE0A OCIE0 + #define BIT_OCIE2A OCIE2 +#endif + + +/** HW dependent timer initialization */ +#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0) + + static void timer_hw_init(void) + { + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Reset Timer flags */ + REG_TIFR0 = BV(BIT_OCF0A) | BV(TOV0); + + /* Setup Timer/Counter interrupt */ + ASSR = 0x00; /* Internal system clock */ + TCCR0 = BV(WGM01) /* Clear on Compare match */ + #if TIMER_PRESCALER == 64 + | BV(CS02) + #else + #error Unsupported value of TIMER_PRESCALER + #endif + ; + TCNT0 = 0x00; /* Initialization of Timer/Counter */ + OCR0 = OCR_DIVISOR; /* Timer/Counter Output Compare Register */ + + /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */ + REG_TIMSK0 &= ~BV(TOIE0); + REG_TIMSK0 |= BV(OCIE0); + + IRQ_RESTORE(flags); + } + + INLINE hptime_t timer_hw_hpread(void) + { + return TCNT0; + } + +#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1) + + static void timer_hw_init(void) + { + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Reset Timer overflow flag */ + TIFR |= BV(TOV1); + + /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */ + #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9) + TCCR1A |= BV(WGM11); + TCCR1A &= ~BV(WGM10); + TCCR1B |= BV(WGM12) | BV(CS10); + TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12)); + /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */ + #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8) + TCCR1A |= BV(WGM10); + TCCR1A &= ~BV(WGM11); + TCCR1B |= BV(WGM12) | BV(CS10); + TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12)); + #else + #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS + #endif + + TCNT1 = 0x00; /* initialization of Timer/Counter */ + + /* Enable timer interrupt: Timer/Counter1 Overflow */ + TIMSK |= BV(TOIE1); + + IRQ_RESTORE(flags); + } + + INLINE hptime_t timer_hw_hpread(void) + { + return TCNT1; + } + +#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2) + static void timer_hw_init(void) + { + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Reset Timer flags */ + REG_TIFR2 = BV(BIT_OCF2A) | BV(TOV2); + + /* Setup Timer/Counter interrupt */ + REG_TCCR2A = 0; // TCCR2 reg could be separate or a unique register with both A & B values, this is needed to + REG_TCCR2B = 0; // ensure correct initialization. + + REG_TCCR2A = BV(WGM21); + #if TIMER_PRESCALER == 64 + #if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 + // ATMega1281 & ATMega168 have undocumented differences in timer2 prescaler! + REG_TCCR2B |= BV(CS22); + #else + REG_TCCR2B |= BV(CS21) | BV(CS20); + #endif + #else + #error Unsupported value of TIMER_PRESCALER + #endif + + /* Clear on Compare match & prescaler = 64, internal sys clock. + When changing prescaler change TIMER_HW_HPTICKS_PER_SEC too */ + TCNT2 = 0x00; /* initialization of Timer/Counter */ + REG_OCR2A = OCR_DIVISOR; /* Timer/Counter Output Compare Register */ + + /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */ + REG_TIMSK2 &= ~BV(TOIE2); + REG_TIMSK2 |= BV(BIT_OCIE2A); + + IRQ_RESTORE(flags); + } + + INLINE hptime_t timer_hw_hpread(void) + { + return TCNT2; + } +#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3) + + static void timer_hw_init(void) + { + cpuflags_t flags; + IRQ_SAVE_DISABLE(flags); + + /* Reset Timer overflow flag */ + TIFR |= BV(TOV3); + + /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */ + #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9) + TCCR3A |= BV(WGM31); + TCCR3A &= ~BV(WGM30); + TCCR3B |= BV(WGM32) | BV(CS30); + TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32)); + /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */ + #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8) + TCCR3A |= BV(WGM30); + TCCR3A &= ~BV(WGM31); + TCCR3B |= BV(WGM32) | BV(CS30); + TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32)); + #else + #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS + #endif + + TCNT3 = 0x00; /* initialization of Timer/Counter */ + + /* Enable timer interrupt: Timer/Counter3 Overflow */ + /* ATTENTION! TOIE3 is only on ETIMSK, not TIMSK */ + ETIMSK |= BV(TOIE3); + + IRQ_RESTORE(flags); + } + + INLINE hptime_t timer_hw_hpread(void) + { + return TCNT3; + } + +#else + #error Unimplemented value for CONFIG_TIMER +#endif /* CONFIG_TIMER */ + diff --git a/bertos/cpu/avr/drv/timer_avr.h b/bertos/cpu/avr/drv/timer_avr.h new file mode 100644 index 00000000..74414263 --- /dev/null +++ b/bertos/cpu/avr/drv/timer_avr.h @@ -0,0 +1,186 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * \author Francesco Sacchi + * + * \brief Low-level timer module for AVR (interface). + */ + +/*#* + *#* $Log$ + *#* Revision 1.32 2007/10/08 12:14:32 batt + *#* Fix some review issues. + *#* + *#* Revision 1.31 2007/10/07 12:30:55 batt + *#* Add default timer for AVR. + *#* + *#* Revision 1.30 2007/06/07 14:35:12 batt + *#* Merge from project_ks. + *#* + *#* Revision 1.29 2007/03/21 11:01:36 batt + *#* Add missing support for ATMega1281. + *#* + *#* Revision 1.28 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.27 2006/05/18 00:38:24 bernie + *#* Use hw_cpu.h instead of ubiquitous hw.h. + *#* + *#* Revision 1.26 2006/02/21 21:28:02 bernie + *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. + *#* + *#* Revision 1.25 2005/07/19 07:26:37 bernie + *#* Refactor to decouple timer ticks from milliseconds. + *#* + *#* Revision 1.24 2005/04/11 19:10:28 bernie + *#* Include top-level headers from cfg/ subdir. + *#* + *#* Revision 1.23 2005/03/01 23:24:51 bernie + *#* Tweaks for avr-libc 1.2.x. + *#* + *#* Revision 1.21 2004/12/13 12:07:06 bernie + *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE. + *#* + *#* Revision 1.20 2004/11/16 20:59:46 bernie + *#* Include explicitly. + *#* + *#* Revision 1.19 2004/10/19 08:56:41 bernie + *#* TIMER_STROBE_ON, TIMER_STROBE_OFF, TIMER_STROBE_INIT: Move from timer_avr.h to timer.h, where they really belong. + *#* + *#* Revision 1.18 2004/09/20 03:31:03 bernie + *#* Fix racy racy code. + *#*/ +#ifndef DRV_TIMER_AVR_H +#define DRV_TIMER_AVR_H + +#include /* CONFIG_TIMER */ +#include /* uint8_t */ +#include /* DIV_ROUND */ +#include /* CLOCK_FREQ */ + +/** + * \name Values for CONFIG_TIMER. + * + * Select which hardware timer interrupt to use for system clock and softtimers. + * \note The timer 1 overflow mode set the timer as a 24 kHz PWM. + * + * \{ + */ +#define TIMER_ON_OUTPUT_COMPARE0 1 +#define TIMER_ON_OVERFLOW1 2 +#define TIMER_ON_OUTPUT_COMPARE2 3 +#define TIMER_ON_OVERFLOW3 4 + +#define TIMER_DEFAULT TIMER_ON_OUTPUT_COMPARE0 ///< Default system timer +/* \} */ + +/* + * Hardware dependent timer initialization. + */ +#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0) + + #define TIMER_PRESCALER 64 + #define TIMER_HW_BITS 8 + #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE0) + #define TIMER_TICKS_PER_SEC 1000 + #define TIMER_HW_CNT OCR_DIVISOR + + /// Type of time expressed in ticks of the hardware high-precision timer + typedef uint8_t hptime_t; + +#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1) + + #define TIMER_PRESCALER 1 + #define TIMER_HW_BITS 8 + /** This value is the maximum in overflow based timers. */ + #define TIMER_HW_CNT (1 << TIMER_HW_BITS) + #define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW1) + #define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT) + + /// Type of time expressed in ticks of the hardware high precision timer + typedef uint16_t hptime_t; + +#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2) + + #define TIMER_PRESCALER 64 + #define TIMER_HW_BITS 8 + #if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 + #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE2A) + #else + #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE2) + #endif + #define TIMER_TICKS_PER_SEC 1000 + /** Value for OCR register in output-compare based timers. */ + #define TIMER_HW_CNT OCR_DIVISOR + + + /// Type of time expressed in ticks of the hardware high precision timer + typedef uint8_t hptime_t; + +#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3) + + #define TIMER_PRESCALER 1 + #define TIMER_HW_BITS 8 + /** This value is the maximum in overflow based timers. */ + #define TIMER_HW_CNT (1 << TIMER_HW_BITS) + #define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW3) + #define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT) + + /// Type of time expressed in ticks of the hardware high precision timer + typedef uint16_t hptime_t; +#else + + #error Unimplemented value for CONFIG_TIMER +#endif /* CONFIG_TIMER */ + + +/** Frequency of the hardware high precision timer. */ +#define TIMER_HW_HPTICKS_PER_SEC DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER) + +/** + * System timer: additional division after the prescaler + * 12288000 / 64 / 192 (0..191) = 1 ms + */ +#define OCR_DIVISOR (DIV_ROUND(DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC) - 1) + +/** Not needed, IRQ timer flag cleared automatically */ +#define timer_hw_irq() do {} while (0) + +/** Not needed, timer IRQ handler called only for timer source */ +#define timer_hw_triggered() (true) + + +#endif /* DRV_TIMER_AVR_H */ diff --git a/bertos/cpu/avr/drv/timer_simple_avr.c b/bertos/cpu/avr/drv/timer_simple_avr.c new file mode 100644 index 00000000..2c076414 --- /dev/null +++ b/bertos/cpu/avr/drv/timer_simple_avr.c @@ -0,0 +1,108 @@ +/** + * \file + * + * + * \brief Some simple delay routines. + * + * Simple serial driver + * \version $Id$ + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.2 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.1 2005/04/12 01:37:50 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.8 2005/04/12 01:18:09 bernie + *#* time_t -> mtime_t. + *#* + *#* Revision 1.7 2005/03/20 04:18:41 bernie + *#* Fixes for CONFIG_WATCHDOG == 0. + *#* + *#* Revision 1.6 2004/10/27 09:38:07 aleph + *#* Bootloader working with watchdog enabled + *#* + *#* Revision 1.5 2004/10/20 10:00:37 customer_pw + *#* Add newline at eof + *#* + *#* Revision 1.4 2004/10/14 14:13:09 batt + *#* Add comment. + *#* + *#* Revision 1.3 2004/10/14 13:29:20 batt + *#* Fix 0ms delay bug. + *#* + *#* Revision 1.2 2004/10/13 17:53:05 batt + *#* Delay with hw timer. + *#* + *#* Revision 1.1 2004/10/13 16:36:32 batt + *#* Simplified timer delay routines. + *#* + *#*/ +#include "hw.h" +#include "timer_simple.h" +#include +#include +#include +#include /* BV() */ + +#include + + +#define MS_PER_SEC 1000UL +#define TIMER_PRESCALER 64UL +#define TIMER_DELAY_1MS (255 - CLOCK_FREQ / TIMER_PRESCALER / MS_PER_SEC) + +/** + * Wait \a time ms using timer 0. + * + */ +void timer_delay(mtime_t time) +{ + /* Set timer clock to clock_freq/64 */ + TCCR0 = BV(CS02); + + while (time--) + { + /* Initialize timer counter register */ + TCNT0 = TIMER_DELAY_1MS; + /* Clear overflow bit. */ + TIFR |= BV(TOV0); + /* Wait overflow. */ + while (!(TIFR & BV(TOV0))); +#if CONFIG_WATCHDOG + wdt_reset(); +#endif + } +} diff --git a/bertos/cpu/avr/drv/timer_simple_avr.h b/bertos/cpu/avr/drv/timer_simple_avr.h new file mode 100644 index 00000000..4815389e --- /dev/null +++ b/bertos/cpu/avr/drv/timer_simple_avr.h @@ -0,0 +1,60 @@ +/** + * \file + * + * + * \brief Simple delay routine + * + * \version $Id$ + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.2 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.1 2005/04/12 01:37:50 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.2 2005/04/12 01:18:09 bernie + *#* time_t -> mtime_t. + *#* + *#* Revision 1.1 2004/10/13 16:36:32 batt + *#* Simplified timer delay routines. + *#* + *#* + */ +#ifndef TIMER_SIMPLE_H +#include + +extern void timer_delay(mtime_t time); +#define TIMER_SIMPLE_H + +#endif /* TIMER_SIMPLE_H */ diff --git a/bertos/cpu/avr/drv/twi_avr.c b/bertos/cpu/avr/drv/twi_avr.c new file mode 100644 index 00000000..bd4fcfd7 --- /dev/null +++ b/bertos/cpu/avr/drv/twi_avr.c @@ -0,0 +1,266 @@ +/** + * \file + * + * + * \brief Driver for the AVR ATMega TWI (implementation) + * + * \version $Id$ + * + * \author Stefano Fedrigo + * \author Bernardo Innocenti + */ + +#include "twi.h" + +#include +#include +#include +#include // BV() +#include /* CLOCK_FREQ */ +#include + +#include + + +/* Wait for TWINT flag set: bus is ready */ +#define WAIT_TWI_READY do {} while (!(TWCR & BV(TWINT))) + +#define READ_BIT BV(0) + + +/** + * Send START condition on the bus. + * + * \return true on success, false otherwise. + */ +static bool twi_start(void) +{ + TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN); + WAIT_TWI_READY; + + if (TW_STATUS == TW_START || TW_STATUS == TW_REP_START) + return true; + + kprintf("!TW_(REP)START: %x\n", TWSR); + return false; +} + + +/** + * Send START condition and select slave for write. + * \c id is the device id comprehensive of address left shifted by 1. + * The LSB of \c id is ignored and reset to 0 for write operation. + * + * \return true on success, false otherwise. + */ +bool twi_start_w(uint8_t id) +{ + /* + * Loop on the select write sequence: when the eeprom is busy + * writing previously sent data it will reply to the SLA_W + * control byte with a NACK. In this case, we must + * keep trying until the eeprom responds with an ACK. + */ + while (twi_start()) + { + TWDR = id & ~READ_BIT; + TWCR = BV(TWINT) | BV(TWEN); + WAIT_TWI_READY; + + if (TW_STATUS == TW_MT_SLA_ACK) + return true; + else if (TW_STATUS != TW_MT_SLA_NACK) + { + kprintf("!TW_MT_SLA_(N)ACK: %x\n", TWSR); + break; + } + } + + return false; +} + + +/** + * Send START condition and select slave for read. + * \c id is the device id comprehensive of address left shifted by 1. + * The LSB of \c id is ignored and set to 1 for read operation. + * + * \return true on success, false otherwise. + */ +bool twi_start_r(uint8_t id) +{ + if (twi_start()) + { + TWDR = id | READ_BIT; + TWCR = BV(TWINT) | BV(TWEN); + WAIT_TWI_READY; + + if (TW_STATUS == TW_MR_SLA_ACK) + return true; + + kprintf("!TW_MR_SLA_ACK: %x\n", TWSR); + } + + return false; +} + + +/** + * Send STOP condition. + */ +void twi_stop(void) +{ + TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO); +} + + +/** + * Put a single byte in master transmitter mode + * to the selected slave device through the TWI bus. + * + * \return true on success, false on error. + */ +bool twi_put(const uint8_t data) +{ + TWDR = data; + TWCR = BV(TWINT) | BV(TWEN); + WAIT_TWI_READY; + if (TW_STATUS != TW_MT_DATA_ACK) + { + kprintf("!TW_MT_DATA_ACK: %x\n", TWSR); + return false; + } + return true; +} + + +/** + * Send a sequence of bytes in master transmitter mode + * to the selected slave device through the TWI bus. + * + * \return true on success, false on error. + */ +bool twi_send(const void *_buf, size_t count) +{ + const uint8_t *buf = (const uint8_t *)_buf; + + while (count--) + { + if (!twi_put(*buf++)) + return false; + } + return true; +} + + +/** + * Receive a sequence of one or more bytes from the + * selected slave device in master receive mode through + * the TWI bus. + * + * Received data is placed in \c buf. + * + * \return true on success, false on error + */ +bool twi_recv(void *_buf, size_t count) +{ + uint8_t *buf = (uint8_t *)_buf; + + /* + * When reading the last byte the TWEA bit is not + * set, and the eeprom should answer with NACK + */ + while (count--) + { + TWCR = BV(TWINT) | BV(TWEN) | (count ? BV(TWEA) : 0); + WAIT_TWI_READY; + + if (count) + { + if (TW_STATUS != TW_MR_DATA_ACK) + { + kprintf("!TW_MR_DATA_ACK: %x\n", TWSR); + return false; + } + } + else + { + if (TW_STATUS != TW_MR_DATA_NACK) + { + kprintf("!TW_MR_DATA_NACK: %x\n", TWSR); + return false; + } + } + *buf++ = TWDR; + } + + return true; +} + + +/** + * Initialize TWI module. + */ +void twi_init(void) +{ + ATOMIC( + /* + * This is pretty useless according to AVR's datasheet, + * but it helps us driving the TWI data lines on boards + * where the bus pull-up resistors are missing. This is + * probably due to some unwanted interaction between the + * port pin and the TWI lines. + */ +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 + PORTD |= BV(PD0) | BV(PD1); + DDRD |= BV(PD0) | BV(PD1); +#elif CPU_AVR_ATMEGA8 + PORTC |= BV(PC4) | BV(PC5); + DDRC |= BV(PC4) | BV(PC5); +#else + #error Unsupported architecture +#endif + + /* + * Set speed: + * F = CLOCK_FREQ / (16 + 2*TWBR * 4^TWPS) + */ + #ifndef CONFIG_TWI_FREQ + #warning Using default value of 300000L for CONFIG_TWI_FREQ + #define CONFIG_TWI_FREQ 300000L /* ~300 kHz */ + #endif + #define TWI_PRESC 1 /* 4 ^ TWPS */ + + TWBR = (CLOCK_FREQ / (2 * CONFIG_TWI_FREQ * TWI_PRESC)) - (8 / TWI_PRESC); + TWSR = 0; + TWCR = BV(TWEN); + ); +} diff --git a/bertos/cpu/avr/drv/twi_avr.h b/bertos/cpu/avr/drv/twi_avr.h new file mode 100644 index 00000000..a55cf64b --- /dev/null +++ b/bertos/cpu/avr/drv/twi_avr.h @@ -0,0 +1,69 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Stefano Fedrigo + * \author Bernardo Innocenti + * + * \brief Driver for the AVR ATMega TWI (interface) + */ + +/*#* + *#* $Log$ + *#* Revision 1.5 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.4 2006/03/20 17:49:49 bernie + *#* Make the TWI driver more generic to work with devices other than EEPROMS. + *#* + *#* Revision 1.3 2005/04/11 19:10:28 bernie + *#* Include top-level headers from cfg/ subdir. + *#* + *#* Revision 1.2 2005/02/18 11:19:52 bernie + *#* Update copyright info. + *#* + *#*/ +#ifndef DRV_TWI_H +#define DRV_TWI_H + +#include + +bool twi_start_w(uint8_t id); +bool twi_start_r(uint8_t id); +void twi_stop(void); +bool twi_put(const uint8_t data); +bool twi_send(const void *_buf, size_t count); +bool twi_recv(void *_buf, size_t count); +void twi_init(void); + +#endif /* DRV_EEPROM_H */ diff --git a/bertos/cpu/detect.h b/bertos/cpu/detect.h new file mode 100644 index 00000000..af2ecd07 --- /dev/null +++ b/bertos/cpu/detect.h @@ -0,0 +1,238 @@ +/** + * \file + * + * + * \brief CPU detection through special preprocessor macros + */ +#ifndef CPU_DETECT_H +#define CPU_DETECT_H + +#if defined(__arm__) /* GCC */ \ + || defined(__ARM4TM__) /* IAR: defined for all cores >= 4tm */ + #define CPU_ARM 1 + #define CPU_ID arm + + // AT91SAM7S core family + #if defined(__ARM_AT91SAM7S32__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7S32 1 + #else + #define CPU_ARM_AT91SAM7S32 0 + #endif + + #if defined(__ARM_AT91SAM7S64__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7S64 1 + #else + #define CPU_ARM_AT91SAM7S64 0 + #endif + + #if defined(__ARM_AT91SAM7S128__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7S128 1 + #else + #define CPU_ARM_AT91SAM7S128 0 + #endif + + #if defined(__ARM_AT91SAM7S256__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7S256 1 + #else + #define CPU_ARM_AT91SAM7S256 0 + #endif + + // AT91SAM7X core family + #if defined(__ARM_AT91SAM7X128__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7X128 1 + #else + #define CPU_ARM_AT91SAM7X128 0 + #endif + + #if defined(__ARM_AT91SAM7X256__) + #define CPU_ARM_AT91 1 + #define CPU_ARM_AT91SAM7X256 1 + #else + #define CPU_ARM_AT91SAM7X256 0 + #endif + + + #if defined(CPU_ARM_AT91) + #if CPU_ARM_AT91SAM7S32 + CPU_ARM_AT91SAM7S64 \ + + CPU_ARM_AT91SAM7S128 + CPU_ARM_AT91SAM7S256 \ + + CPU_ARM_AT91SAM7X128 + CPU_ARM_AT91SAM7X256 != 1 + #error ARM CPU configuration error + #endif + + /* #elif Add other ARM families here */ + #else + #define CPU_ATM_AT91 0 + #endif + + + #if CPU_ARM_AT91 + 0 /* Add other ARM families here */ != 1 + #error ARM CPU configuration error + #endif +#else + #define CPU_ARM 0 + + /* ARM Families */ + #define CPU_ARM_AT91 0 + + /* ARM CPUs */ + #define CPU_ARM_AT91SAM7S32 0 + #define CPU_ARM_AT91SAM7S64 0 + #define CPU_ARM_AT91SAM7S128 0 + #define CPU_ARM_AT91SAM7S256 0 + #define CPU_ARM_AT91SAM7X128 0 + #define CPU_ARM_AT91SAM7X256 0 +#endif + +#if (defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)) \ + && !defined(__ARM4TM__) /* IAR: if not ARM assume I196 */ + #warning Assuming CPU is I196 + #define CPU_I196 1 + #define CPU_ID i196 +#else + #define CPU_I196 0 +#endif + +#if defined(__i386__) /* GCC */ \ + || (defined(_M_IX86) && !defined(_WIN64)) /* MSVC */ + #define CPU_X86 1 + #define CPU_X86_32 1 + #define CPU_X86_64 0 + #define CPU_ID x86 +#elif defined(__x86_64__) /* GCC */ \ + || (defined(_M_IX86) && defined(_WIN64)) /* MSVC */ + #define CPU_X86 1 + #define CPU_X86_32 0 + #define CPU_X86_64 1 + #define CPU_ID x86 +#else + #define CPU_X86 0 + #define CPU_I386 0 + #define CPU_X86_64 0 +#endif + +#if defined (_ARCH_PPC) || defined(_ARCH_PPC64) + #define CPU_PPC 1 + #define CPU_ID ppc + #if defined(_ARCH_PPC) + #define CPU_PPC32 1 + #else + #define CPU_PPC32 0 + #endif + #if defined(_ARCH_PPC64) + #define CPU_PPC64 1 + #else + #define CPU_PPC64 0 + #endif +#else + #define CPU_PPC 0 + #define CPU_PPC32 0 + #define CPU_PPC64 0 +#endif + +#if defined(__m56800E__) || defined(__m56800__) + #define CPU_DSP56K 1 + #define CPU_ID dsp56k +#else + #define CPU_DSP56K 0 +#endif + +#if defined (__AVR__) + #define CPU_AVR 1 + #define CPU_ID avr + + #if defined(__AVR_ATmega64__) + #define CPU_AVR_ATMEGA64 1 + #else + #define CPU_AVR_ATMEGA64 0 + #endif + + #if defined(__AVR_ATmega103__) + #define CPU_AVR_ATMEGA103 1 + #else + #define CPU_AVR_ATMEGA103 0 + #endif + + #if defined(__AVR_ATmega128__) + #define CPU_AVR_ATMEGA128 1 + #else + #define CPU_AVR_ATMEGA128 0 + #endif + + #if defined(__AVR_ATmega8__) + #define CPU_AVR_ATMEGA8 1 + #else + #define CPU_AVR_ATMEGA8 0 + #endif + + #if defined(__AVR_ATmega168__) + #define CPU_AVR_ATMEGA168 1 + #else + #define CPU_AVR_ATMEGA168 0 + #endif + + #if defined(__AVR_ATmega1281__) + #define CPU_AVR_ATMEGA1281 1 + #else + #define CPU_AVR_ATMEGA1281 0 + #endif + + #if CPU_AVR_ATMEGA64 + CPU_AVR_ATMEGA103 + CPU_AVR_ATMEGA128 \ + + CPU_AVR_ATMEGA8 + CPU_AVR_ATMEGA168 + CPU_AVR_ATMEGA1281 != 1 + #error AVR CPU configuration error + #endif +#else + #define CPU_AVR 0 + #define CPU_AVR_ATMEGA8 0 + #define CPU_AVR_ATMEGA168 0 + #define CPU_AVR_ATMEGA64 0 + #define CPU_AVR_ATMEGA103 0 + #define CPU_AVR_ATMEGA128 0 + #define CPU_AVR_ATMEGA1281 0 +#endif + + +/* Self-check for the detection: only one CPU must be detected */ +#if CPU_ARM + CPU_I196 + CPU_X86 + CPU_PPC + CPU_DSP56K + CPU_AVR == 0 + #error Unknown CPU +#elif !defined(CPU_ID) + #error CPU_ID not defined +#elif CPU_ARM + CPU_I196 + CPU_X86 + CPU_PPC + CPU_DSP56K + CPU_AVR != 1 + #error Internal CPU configuration error +#endif + + +#endif /* CPU_DETECT_H */ diff --git a/bertos/cpu/dsp56k/drv/buzzerled_dsp56k.h b/bertos/cpu/dsp56k/drv/buzzerled_dsp56k.h new file mode 100644 index 00000000..4eafa57b --- /dev/null +++ b/bertos/cpu/dsp56k/drv/buzzerled_dsp56k.h @@ -0,0 +1,178 @@ +/** + * \file + * + * + * \brief Hardware support for buzzers and leds in DSP56K-based boards + * + * \version $Id$ + * + * \author Giovanni Bajo + */ + +/*#* + *#* $Log$ + *#* Revision 1.7 2006/07/19 12:56:25 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.6 2005/11/04 16:20:02 bernie + *#* Fix reference to README.devlib in header. + *#* + *#* Revision 1.5 2005/04/11 19:10:27 bernie + *#* Include top-level headers from cfg/ subdir. + *#* + *#* Revision 1.4 2004/11/16 21:54:43 bernie + *#* Changes for SC Monoboard support. + *#* + *#* Revision 1.3 2004/08/25 14:12:08 rasky + *#* Aggiornato il comment block dei log RCS + *#* + *#* Revision 1.2 2004/06/03 11:27:09 bernie + *#* Add dual-license information. + *#* + *#* Revision 1.1 2004/05/23 18:36:05 bernie + *#* Import buzzerled driver. + *#* + *#*/ + +#ifndef DRV_BUZZERLED_DSP56K_H +#define DRV_BUZZERLED_DSP56K_H + +#include +#include +#include "pwm.h" + +#if ARCH & ARCH_HECO + +/** + * \name Connection of the leds to the DSP: + *
+ *   Led       Line    DSP Pin
+ *   ---------------------------
+ *   YELLOW    T2      HOME1/TB3
+ *   GREEN     T3      INDX1/TB2
+ *   RED       T4      PHB1/TB1
+ * 
+ */ + +INLINE bool bld_is_inverted_intensity(enum BLD_DEVICE device) +{ + return (device == BLD_GREEN_LED + || device == BLD_YELLOW_LED + || device == BLD_RED_LED); +} + +INLINE bool bld_is_pwm(enum BLD_DEVICE device) +{ + // Only the buzzer is connected to a PWM + return (device == BLD_BUZZER || device == BLD_READY_LED); +} + +INLINE bool bld_is_timer(enum BLD_DEVICE device) +{ + // LEDs are connected to timers + return (device == BLD_GREEN_LED || device == BLD_YELLOW_LED || device == BLD_RED_LED); +} + +INLINE uint16_t bld_get_pwm(enum BLD_DEVICE device) +{ + switch (device) + { + default: ASSERT(0); + case BLD_BUZZER: return 5; // PWMA5 + case BLD_READY_LED: return 9; // PWMB3 + } +} + + +INLINE struct REG_TIMER_STRUCT* bld_get_timer(enum BLD_DEVICE device) +{ + switch (device) + { + default: ASSERT(0); + case BLD_GREEN_LED: return ®_TIMER_B[2]; + case BLD_RED_LED: return ®_TIMER_B[1]; + case BLD_YELLOW_LED: return ®_TIMER_B[3]; + } +} + +INLINE void bld_hw_init(void) +{ +} + +INLINE void bld_hw_set(enum BLD_DEVICE device, bool enable) +{ + if (bld_is_inverted_intensity(device)) + enable = !enable; + + // Handle a BLD connected to a PWM + if (bld_is_pwm(device)) + { + struct PWM* pwm = pwm_get_handle(bld_get_pwm(device)); + + pwm_set_enable(pwm, false); + pwm_set_dutycycle_percent(pwm, (enable ? 50 : 0)); + pwm_set_enable(pwm, true); + } + else if (bld_is_timer(device)) + { + struct REG_TIMER_STRUCT* timer = bld_get_timer(device); + + // Check that the timer is currently stopped, and the OFLAG is not + // controlled by another timer. Otherwise, the led is already + // controlled by the timer, and we cannot correctly set it + // on/off without reprogramming the timer. + ASSERT((timer->CTRL & REG_TIMER_CTRL_MODE_MASK) == REG_TIMER_CTRL_MODE_STOP); + ASSERT(!(timer->SCR & REG_TIMER_SCR_EEOF)); + + // Check also that polarity is correct + ASSERT(!(timer->SCR & REG_TIMER_SCR_OPS)); + + // Without programming the timer, we have a way to manually force a certain + // value on the external pin. We also need to enable the output pin. + timer->SCR &= ~REG_TIMER_SCR_VAL_1; + timer->SCR |= REG_TIMER_SCR_OEN | + REG_TIMER_SCR_FORCE | + (!enable ? REG_TIMER_SCR_VAL_0 : REG_TIMER_SCR_VAL_1); + } + else + ASSERT(0); +} + +#elif ARCH & ARCH_SC + +// We do not need inline functions here, because constant propagation is not big deal here +void bld_hw_init(void); +void bld_hw_set(enum BLD_DEVICE device, bool enable); + +#endif + +#endif /* DRV_BUZZERLED_DSP56K_H */ diff --git a/bertos/cpu/dsp56k/drv/kdebug_dsp56k.c b/bertos/cpu/dsp56k/drv/kdebug_dsp56k.c new file mode 100644 index 00000000..67c9a9db --- /dev/null +++ b/bertos/cpu/dsp56k/drv/kdebug_dsp56k.c @@ -0,0 +1,54 @@ +/** + * \file + * + * + * \brief General pourpose debug support for embedded systems (implementation). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Stefano Fedrigo + */ + +#error Revise me! + +/* Debugging go through the JTAG interface. The MSL library already + implements the console I/O correctly. */ +#include +#define KDBG_WAIT_READY() do { } while (0) +#define KDBG_WRITE_CHAR(c) __put_char(c, stdout) +#define KDBG_MASK_IRQ(old) do { (void)(old); } while (0) +#define KDBG_RESTORE_IRQ(old) do { (void)(old); } while (0) +typedef uint8_t kdbg_irqsave_t; /* unused */ +#if CONFIG_KDEBUG_PORT == 666 + #error BITBANG debug console missing for this platform + +#define kdbg_hw_init() do {} while (0) ///< Not needed diff --git a/bertos/cpu/dsp56k/drv/ser_dsp56k.c b/bertos/cpu/dsp56k/drv/ser_dsp56k.c new file mode 100644 index 00000000..d69e0c57 --- /dev/null +++ b/bertos/cpu/dsp56k/drv/ser_dsp56k.c @@ -0,0 +1,367 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Stefano Fedrigo + * \author Giovanni Bajo + * + * \brief DSP5680x CPU specific serial I/O driver + */ + + +#include +#include +#include +#include +#include +#include + +// GPIO E is shared with SPI (in DSP56807). Pins 0&1 are TXD0 and RXD0. To use +// the serial, we need to disable the GPIO functions on them. +#define REG_GPIO_SERIAL_0 REG_GPIO_E +#define REG_GPIO_SERIAL_MASK_0 0x03 + +#define REG_GPIO_SERIAL_1 REG_GPIO_D +#define REG_GPIO_SERIAL_MASK_1 0xC0 + + +// Check flag consistency +#if (SERRF_PARITYERROR != REG_SCI_SR_PF) || \ + (SERRF_RXSROVERRUN != REG_SCI_SR_OR) || \ + (SERRF_FRAMEERROR != REG_SCI_SR_FE) || \ + (SERRF_NOISEERROR != REG_SCI_SR_NF) + #error error flags do not match with register bits +#endif + +static unsigned char ser0_fifo_rx[CONFIG_SER0_FIFOSIZE_RX]; +static unsigned char ser0_fifo_tx[CONFIG_SER0_FIFOSIZE_TX]; +static unsigned char ser1_fifo_rx[CONFIG_SER1_FIFOSIZE_RX]; +static unsigned char ser1_fifo_tx[CONFIG_SER1_FIFOSIZE_TX]; + +#if CONFIG_SER_MULTI + #include + + #define MAX_MULTI_GROUPS 1 + + struct Semaphore multi_sems[MAX_MULTI_GROUPS]; +#endif + + +struct SCI +{ + struct SerialHardware hw; + struct Serial* serial; + volatile struct REG_SCI_STRUCT* regs; + IRQ_VECTOR irq_tx; + IRQ_VECTOR irq_rx; + int num_group; + int id; +}; + +static inline void enable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs) +{ + regs->CR |= REG_SCI_CR_TEIE | REG_SCI_CR_TIIE; +} + +static inline void enable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs) +{ + regs->CR |= REG_SCI_CR_RIE; +} + +static inline void disable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs) +{ + regs->CR &= ~(REG_SCI_CR_TEIE | REG_SCI_CR_TIIE); +} + +static inline void disable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs) +{ + regs->CR &= ~(REG_SCI_CR_RIE | REG_SCI_CR_REIE); +} + +static inline void disable_tx_irq(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + disable_tx_irq_bare(hw->regs); +} + +static inline void disable_rx_irq(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + disable_rx_irq_bare(hw->regs); +} + +static inline void enable_tx_irq(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + enable_tx_irq_bare(hw->regs); +} + +static inline void enable_rx_irq(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + enable_rx_irq_bare(hw->regs); +} + +static inline bool tx_irq_enabled(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + return (hw->regs->CR & REG_SCI_CR_TEIE); +} + +static void tx_isr(const struct SCI *hw) +{ +#pragma interrupt warn + volatile struct REG_SCI_STRUCT* regs = hw->regs; + + if (fifo_isempty(&hw->serial->txfifo)) + disable_tx_irq_bare(regs); + else + { + // Clear transmitter flags before sending data + (void)regs->SR; + regs->DR = fifo_pop(&hw->serial->txfifo); + } +} + +static void rx_isr(const struct SCI *hw) +{ +#pragma interrupt warn + volatile struct REG_SCI_STRUCT* regs = hw->regs; + + // Propagate errors + hw->serial->status |= regs->SR & (SERRF_PARITYERROR | + SERRF_RXSROVERRUN | + SERRF_FRAMEERROR | + SERRF_NOISEERROR); + + /* + * Serial IRQ can happen for two reason: data ready (RDRF) or overrun (OR) + * If the data is ready, we need to fetch it from the data register or + * the interrupt will retrigger immediatly. In case of overrun, instead, + * the value of the data register is meaningless. + */ + if (regs->SR & REG_SCI_SR_RDRF) + { + unsigned char data = regs->DR; + + if (fifo_isfull(&hw->serial->rxfifo)) + hw->serial->status |= SERRF_RXFIFOOVERRUN; + else + fifo_push(&hw->serial->rxfifo, data); + } + + // Writing anything to the status register clear the error bits. + regs->SR = 0; +} + +static void init(struct SerialHardware* _hw, struct Serial* ser) +{ + struct SCI* hw = (struct SCI*)_hw; + volatile struct REG_SCI_STRUCT* regs = hw->regs; + + // Clear status register (IRQ/status flags) + (void)regs->SR; + regs->SR = 0; + + // Clear data register + (void)regs->DR; + + // Install the handlers and set priorities for both IRQs + irq_install(hw->irq_tx, (isr_t)tx_isr, hw); + irq_install(hw->irq_rx, (isr_t)rx_isr, hw); + irq_setpriority(hw->irq_tx, IRQ_PRIORITY_SCI_TX); + irq_setpriority(hw->irq_rx, IRQ_PRIORITY_SCI_RX); + + // Activate the RX error interrupts, and RX/TX transmissions + regs->CR = REG_SCI_CR_TE | REG_SCI_CR_RE; + enable_rx_irq_bare(regs); + + // Disable GPIO pins for TX and RX lines + // \todo this should be divided into serial 0 and 1 + REG_GPIO_SERIAL_0->PER |= REG_GPIO_SERIAL_MASK_0; + REG_GPIO_SERIAL_1->PER |= REG_GPIO_SERIAL_MASK_1; + + hw->serial = ser; +} + +static void cleanup(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + // Uninstall the ISRs + disable_rx_irq(_hw); + disable_tx_irq(_hw); + irq_uninstall(hw->irq_tx); + irq_uninstall(hw->irq_rx); +} + +static void setbaudrate(struct SerialHardware* _hw, unsigned long rate) +{ + struct SCI* hw = (struct SCI*)_hw; + + // SCI has an internal 16x divider on the input clock, which comes + // from the IPbus (see the scheme in user manual, 12.7.3). We apply + // it to calculate the period to store in the register. + hw->regs->BR = (IPBUS_FREQ + rate * 8ul) / (rate * 16ul); +} + +static void setparity(struct SerialHardware* _hw, int parity) +{ + // ??? + ASSERT(0); +} + + +#if CONFIG_SER_MULTI + +static void multi_init(void) +{ + static bool flag = false; + int i; + + if (flag) + return; + + for (i = 0; i < MAX_MULTI_GROUPS; ++i) + sem_init(&multi_sems[i]); + flag = true; +} + +static void init_lock(struct SerialHardware* _hw, struct Serial *ser) +{ + struct SCI* hw = (struct SCI*)_hw; + + // Initialize the multi engine (if needed) + multi_init(); + + // Acquire the lock of the semaphore for this group + ASSERT(hw->num_group >= 0); + ASSERT(hw->num_group < MAX_MULTI_GROUPS); + sem_obtain(&multi_sems[hw->num_group]); + + // Do a hardware switch to the given serial + ser_hw_switch(hw->num_group, hw->id); + + init(_hw, ser); +} + +static void cleanup_unlock(struct SerialHardware* _hw) +{ + struct SCI* hw = (struct SCI*)_hw; + + cleanup(_hw); + + sem_release(&multi_sems[hw->num_group]); +} + +#endif /* CONFIG_SER_MULTI */ + + +static const struct SerialHardwareVT SCI_VT = +{ + .init = init, + .cleanup = cleanup, + .setBaudrate = setbaudrate, + .setParity = setparity, + .txStart = enable_tx_irq, + .txSending = tx_irq_enabled, +}; + +#if CONFIG_SER_MULTI +static const struct SerialHardwareVT SCI_MULTI_VT = +{ + .init = init_lock, + .cleanup = cleanup_unlock, + .setBaudrate = setbaudrate, + .setParity = setparity, + .txStart = enable_tx_irq, + .txSending = tx_irq_enabled, +}; +#endif /* CONFIG_SER_MULTI */ + +#define SCI_DESC_NORMAL(hwch) \ + { \ + .hw = \ + { \ + .table = &SCI_VT, \ + .rxbuffer = ser ## hwch ## _fifo_rx, \ + .txbuffer = ser ## hwch ## _fifo_tx, \ + .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \ + .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \ + }, \ + .regs = ®_SCI[hwch], \ + .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \ + .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \ + .num_group = -1, \ + .id = -1, \ + } \ + /**/ + +#if CONFIG_SER_MULTI +#define SCI_DESC_MULTI(hwch, group_, id_) \ + { \ + .hw = \ + { \ + .table = &SCI_MULTI_VT, \ + .rxbuffer = ser ## hwch ## _fifo_rx, \ + .txbuffer = ser ## hwch ## _fifo_tx, \ + .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \ + .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \ + }, \ + .regs = ®_SCI[hwch], \ + .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \ + .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \ + .num_group = group_, \ + .id = id_, \ + } \ + /**/ +#endif /* CONFIG_SER_MULTI */ + +// \todo Move this into hw.h, with a little preprocessor magic +static struct SCI SCIDescs[] = +{ + SCI_DESC_NORMAL(0), + SCI_DESC_MULTI(1, 0, 0), + SCI_DESC_MULTI(1, 0, 1), +}; + +struct SerialHardware* ser_hw_getdesc(int unit) +{ + ASSERT(unit < countof(SCIDescs)); + return &SCIDescs[unit].hw; +} diff --git a/bertos/cpu/dsp56k/drv/ser_dsp56k.h b/bertos/cpu/dsp56k/drv/ser_dsp56k.h new file mode 100644 index 00000000..d035df67 --- /dev/null +++ b/bertos/cpu/dsp56k/drv/ser_dsp56k.h @@ -0,0 +1,72 @@ +/** + * \file + * + * + * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ + * + * \author Daniele Basile + * + * \brief Low-level serial module for ARM (interface). + */ + +#include /* BV() */ +#include /* uint32_t */ + +typedef uint16_t serstatus_t; + +/* Software errors */ +#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ +#define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */ +#define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */ + +/* + * Hardware errors. + * These flags map directly to the SCI Control Register. + */ +#define SERRF_PARITYERROR BV(8) /**< Parity error */ +#define SERRF_FRAMEERROR BV(9) /**< Stop bit missing */ +#define SERRF_NOISEERROR BV(10) /**< Noise error */ +#define SERRF_RXSROVERRUN BV(11) /**< Rx shift register overrun */ + +/** + * \name Serial hw numbers + * + * \{ + */ +enum +{ +// \todo since we now support "fake" multiplexed serials, this should be moved to hw.h +SER_UART0, +SER_PUNTALI, +SER_BARCODE, +SER_CNT /**< Number of serial ports */ +}; +/*\}*/ diff --git a/bertos/cpu/dsp56k/drv/timer_dsp56k.h b/bertos/cpu/dsp56k/drv/timer_dsp56k.h new file mode 100644 index 00000000..f86cb50b --- /dev/null +++ b/bertos/cpu/dsp56k/drv/timer_dsp56k.h @@ -0,0 +1,148 @@ +#error This code must be revised for the new timer API +/** + * \file + * + * + * \version $Id$ + * + * \author Giovanni Bajo + * + * \brief Driver module for DSP56K + */ + +/*#* + *#* $Log$ + *#* Revision 1.10 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.9 2006/02/21 21:28:02 bernie + *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. + *#* + *#* Revision 1.8 2005/11/04 16:20:02 bernie + *#* Fix reference to README.devlib in header. + *#* + *#* Revision 1.7 2005/04/11 19:10:28 bernie + *#* Include top-level headers from cfg/ subdir. + *#* + *#* Revision 1.6 2004/11/16 22:37:14 bernie + *#* Replace IPTR with iptr_t. + *#* + *#* Revision 1.5 2004/08/25 14:12:08 rasky + *#* Aggiornato il comment block dei log RCS + *#* + *#* Revision 1.4 2004/07/30 14:27:49 rasky + *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management + *#* + *#* Revision 1.3 2004/06/06 18:30:34 bernie + *#* Import DSP56800 changes from SC. + *#* + *#* Revision 1.2 2004/06/03 11:27:09 bernie + *#* Add dual-license information. + *#* + *#* Revision 1.1 2004/05/23 18:23:30 bernie + *#* Import drv/timer module. + *#* + *#*/ + +#ifndef DRV_TIMER_DSP56K_H +#define DRV_TIMER_DSP56K_H + +#include "timer.h" +#include +#include +#include +#include + +// Calculate register pointer and irq vector from hw.h setting +#define REG_SYSTEM_TIMER PP_CAT(REG_TIMER_, SYSTEM_TIMER) +#define SYSTEM_TIMER_IRQ_VECTOR PP_CAT(IRQ_TIMER_, SYSTEM_TIMER) + +/// Prescaler for the system timer +#define TIMER_PRESCALER 16 + +/// Frequency of the hardware high precision timer +#define TIMER_HW_HPTICKS_PER_SEC (IPBUS_FREQ / TIMER_PRESCALER) + +/// Type of time expressed in ticks of the hardware high precision timer +typedef uint16_t hptime_t; + +static void system_timer_isr(UNUSED(iptr_t, arg)); + +static void timer_hw_init(void) +{ + uint16_t compare; + + // Clear compare flag status and enable interrupt on compare + REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF; + REG_SYSTEM_TIMER->SCR |= REG_TIMER_SCR_TCFIE; + + // Calculate the compare value needed to generate an interrupt exactly + // TICKS_PER_SEC times each second (usually, every millisecond). Check that + // the calculation is accurate, otherwise there is a precision error + // (probably the prescaler is too big or too small). + compare = TIMER_HW_HPTICKS_PER_SEC / TICKS_PER_SEC; + ASSERT((uint32_t)compare * TICKS_PER_SEC == IPBUS_FREQ / TIMER_PRESCALER); + REG_SYSTEM_TIMER->CMP1 = compare; + + // The value for reload (at initializationa and after compare is met) is zero + REG_SYSTEM_TIMER->LOAD = 0; + + // Set the interrupt handler and priority + irq_install(SYSTEM_TIMER_IRQ_VECTOR, &system_timer_isr, NULL); + irq_setpriority(SYSTEM_TIMER_IRQ_VECTOR, IRQ_PRIORITY_SYSTEM_TIMER); + + // Small preprocessor trick to generate the REG_TIMER_CTRL_PRIMARY_IPBYNN macro + // needed to set the prescaler + #define REG_CONTROL_PRESCALER PP_CAT(REG_TIMER_CTRL_PRIMARY_IPBY, TIMER_PRESCALER) + + // Setup the counter and start counting + REG_SYSTEM_TIMER->CTRL = + REG_TIMER_CTRL_MODE_RISING | // count rising edges (normal) + REG_CONTROL_PRESCALER | // frequency (IPbus / TIMER_PRESCALER) + REG_TIMER_CTRL_LENGTH; // up to CMP1, then reload +} + +INLINE void timer_hw_irq(void) +{ + // Clear the overflow flag so that we are ready for another interrupt + REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF; +} + +INLINE hptime_t timer_hw_hpread(void) +{ + return REG_SYSTEM_TIMER->CNTR; +} + +#define DEFINE_TIMER_ISR \ + static void system_timer_isr(UNUSED(iptr_t, arg)) + +#endif /* DRV_TIMER_DSP56_H */ diff --git a/bertos/cpu/i196/drv/kdebug_i196.c b/bertos/cpu/i196/drv/kdebug_i196.c new file mode 100644 index 00000000..2f72e519 --- /dev/null +++ b/bertos/cpu/i196/drv/kdebug_i196.c @@ -0,0 +1,75 @@ +/** + * \file + * + * + * \brief General pourpose debug support for embedded systems (implementation). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Stefano Fedrigo + */ + +#error Revise me! + +#include +#include /* for BV() */ +#include +#include /* for CLOCK_FREQ */ +#include /* Required for bus macros overrides */ + + +#include "Util196.h" +#define KDBG_WAIT_READY() do {} while (!(SP_STAT & (SPSF_TX_EMPTY | SPSF_TX_INT))) +#define KDBG_WRITE_CHAR(c) do { SBUF = (c); } while(0) +#define KDBG_MASK_IRQ(old) \ + do { \ + (old) = INT_MASK1 & INT1F_TI; \ + INT_MASK1 &= ~INT1F_TI; \ + } while(0) +#define KDBG_RESTORE_IRQ(old) do { INT_MASK1 |= (old); } +typedef uint16_t kdbg_irqsave_t; /* FIXME: unconfirmed */ + +#if CONFIG_KDEBUG_PORT == 666 + #error BITBANG debug console missing for this platform +#endif + + +INLINE void kdbg_hw_init(void) +{ + /* Set serial port for 19200bps 8N1 */ + INT_MASK1 &= ~(INT1F_TI | INT1F_RI); + SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1; + ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC; + IOC1 = ioc1_img; + BAUD_RATE = 0x33; + BAUD_RATE = 0x80; +} diff --git a/bertos/cpu/i196/drv/ser_i196.c b/bertos/cpu/i196/drv/ser_i196.c new file mode 100644 index 00000000..a87de6fa --- /dev/null +++ b/bertos/cpu/i196/drv/ser_i196.c @@ -0,0 +1,134 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief CPU specific serial I/O driver + */ + +/*#* + *#* $Log$ + *#* Revision 1.7 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.6 2005/11/04 16:20:02 bernie + *#* Fix reference to README.devlib in header. + *#* + *#* Revision 1.5 2004/12/13 11:51:08 bernie + *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE. + *#* + *#* Revision 1.4 2004/08/25 14:12:08 rasky + *#* Aggiornato il comment block dei log RCS + *#* + *#* Revision 1.3 2004/06/03 11:27:09 bernie + *#* Add dual-license information. + *#* + *#* Revision 1.2 2004/05/23 18:21:53 bernie + *#* Trim CVS logs and cleanup header info. + *#* + *#*/ + +#include "hw.h" +#include "serhw.h" + +#define SER_HW_ENABLE_TX \ + ATOMIC( \ + if (!ser_sending) \ + { \ + ser_sending = true; \ + (INT_PEND1 |= INT1F_TI) \ + } \ + ); + +static volatile bool ser_sending; + +// Serial TX intr +INTERRUPT(0x30) void TI_interrupt(void) +{ + if (CANT_SEND) + { + ser_sending = false; + return; + } + + /* Can we send two bytes at the same time? */ + if (SP_STAT & SPSF_TX_EMPTY) + { + SBUF = fifo_pop(&ser_txfifo); + + if (CANT_SEND) + { + ser_sending = false; + return; + } + } + + SBUF = fifo_pop(&ser_txfifo); +} + +INTERRUPT(0x32) void RI_interrupt(void) +{ + ser_status |= SP_STAT & + (SPSF_OVERRUN_ERROR | SPSF_PARITY_ERROR | SPSF_FRAMING_ERROR); + if (fifo_isfull(&ser_rxfifo)) + ser_status |= SERRF_RXFIFOOVERRUN; + else + fifo_push(&ser_rxfifo, SBUF); +} + +static void ser_setbaudrate(unsigned long rate) +{ + // Calcola il periodo per la generazione del baud rate richiesto + uint16_t baud = (uint16_t)(((CLOCK_FREQ / 16) / rate) - 1) | 0x8000; + BAUD_RATE = (uint8_t)baud; + BAUD_RATE = (uint8_t)(baud >> 8); +} + +static void ser_hw_init(void) +{ + // Inizializza la porta seriale + SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1; + ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC; + IOC1 = ioc1_img; + + // Svuota il buffer di ricezione + { + uint8_t dummy = SBUF; + } + + // Abilita gli interrupt + INT_MASK1 |= INT1F_TI | INT1F_RI; +} + diff --git a/bertos/cpu/i196/drv/timer_i196.h b/bertos/cpu/i196/drv/timer_i196.h new file mode 100644 index 00000000..5c4bc8bd --- /dev/null +++ b/bertos/cpu/i196/drv/timer_i196.h @@ -0,0 +1,89 @@ +#error This code must be revised for the new timer API +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief Low-level timer module for AVR + */ + +/*#* + *#* $Log$ + *#* Revision 1.7 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.6 2006/02/21 21:28:02 bernie + *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. + *#* + *#* Revision 1.5 2005/11/04 16:20:02 bernie + *#* Fix reference to README.devlib in header. + *#* + *#* Revision 1.4 2004/12/13 11:51:08 bernie + *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE. + *#* + *#* Revision 1.3 2004/08/25 14:12:08 rasky + *#* Aggiornato il comment block dei log RCS + *#* + *#* Revision 1.2 2004/06/03 11:27:09 bernie + *#* Add dual-license information. + *#* + *#* Revision 1.1 2004/05/23 18:23:30 bernie + *#* Import drv/timer module. + *#* + *#*/ + +#ifndef TIMER_I196_H +#define TIMER_I196_H + +/** + * Retrigger TIMER2, adjusting the time to account for + * the interrupt prologue latency. + */ +#define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE) + +#define TIMER_INIT \ + TIMER2 = (65535 - TICKS_RATE); \ + INT_MASK1 |= INT1F_T2OVF; \ + ATOMIC( \ + WSR = 1; \ + IOC3 |= IOC3F_T2_ENA; \ + WSR = 0; \ + ) + +#define DEFINE_TIMER_ISR \ + INTERRUPT(0x38) void TM2_OVFL_interrupt(void); \ + INTERRUPT(0x38) void TM2_OVFL_interrupt(void) + +#endif /* DRV_TIMER_I196_H */ diff --git a/bertos/cpu/irq.h b/bertos/cpu/irq.h new file mode 100644 index 00000000..15609d76 --- /dev/null +++ b/bertos/cpu/irq.h @@ -0,0 +1,251 @@ +/** + * \file + * + * + * \brief CPU-specific IRQ definitions. + * + * \author Giovanni Bajo + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * \author Francesco Sacchi + */ +#ifndef CPU_IRQ_H +#define CPU_IRQ_H + +#include "detect.h" +#include "types.h" + +#include /* for uintXX_t */ + +#if CPU_I196 + #define IRQ_DISABLE disable_interrupt() + #define IRQ_ENABLE enable_interrupt() +#elif CPU_X86 + + /* Get IRQ_* definitions from the hosting environment. */ + #include + #if OS_EMBEDDED + #define IRQ_DISABLE FIXME + #define IRQ_ENABLE FIXME + #define IRQ_SAVE_DISABLE(x) FIXME + #define IRQ_RESTORE(x) FIXME + #endif /* OS_EMBEDDED */ + +#elif CPU_ARM + + + #ifdef __IAR_SYSTEMS_ICC__ + + #include + + #if __CPU_MODE__ == 1 /* Thumb */ + /* Use stubs */ + extern cpuflags_t get_CPSR(void); + extern void set_CPSR(cpuflags_t flags); + #else + #define get_CPSR __get_CPSR + #define set_CPSR __set_CPSR + #endif + + #define IRQ_DISABLE __disable_interrupt() + #define IRQ_ENABLE __enable_interrupt() + + #define IRQ_SAVE_DISABLE(x) \ + do { \ + (x) = get_CPSR(); \ + __disable_interrupt(); \ + } while (0) + + #define IRQ_RESTORE(x) \ + do { \ + set_CPSR(x); \ + } while (0) + + #define IRQ_ENABLED() \ + ((bool)(get_CPSR() & 0xb0)) + + #define BREAKPOINT /* asm("bkpt 0") DOES NOT WORK */ + + #else /* !__IAR_SYSTEMS_ICC__ */ + + #define IRQ_DISABLE \ + do { \ + asm volatile ( \ + "mrs r0, cpsr\n\t" \ + "orr r0, r0, #0xc0\n\t" \ + "msr cpsr_c, r0" \ + ::: "r0" \ + ); \ + } while (0) + + #define IRQ_ENABLE \ + do { \ + asm volatile ( \ + "mrs r0, cpsr\n\t" \ + "bic r0, r0, #0xc0\n\t" \ + "msr cpsr_c, r0" \ + ::: "r0" \ + ); \ + } while (0) + + #define IRQ_SAVE_DISABLE(x) \ + do { \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + "orr r0, %0, #0xc0\n\t" \ + "msr cpsr_c, r0" \ + : "=r" (x) \ + : /* no inputs */ \ + : "r0" \ + ); \ + } while (0) + + #define IRQ_RESTORE(x) \ + do { \ + asm volatile ( \ + "msr cpsr_c, %0" \ + : /* no outputs */ \ + : "r" (x) \ + ); \ + } while (0) + + #define CPU_READ_FLAGS() \ + ({ \ + cpuflags_t sreg; \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + : "=r" (sreg) \ + : /* no inputs */ \ + ); \ + sreg; \ + }) + + #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0) + + #endif /* !__IAR_SYSTEMS_ICC_ */ + +#elif CPU_PPC + #define IRQ_DISABLE FIXME + #define IRQ_ENABLE FIXME + #define IRQ_SAVE_DISABLE(x) FIXME + #define IRQ_RESTORE(x) FIXME + #define IRQ_ENABLED() FIXME + +#elif CPU_DSP56K + + #define BREAKPOINT asm(debug) + #define IRQ_DISABLE do { asm(bfset #0x0200,SR); asm(nop); } while (0) + #define IRQ_ENABLE do { asm(bfclr #0x0200,SR); asm(nop); } while (0) + + #define IRQ_SAVE_DISABLE(x) \ + do { (void)x; asm(move SR,x); asm(bfset #0x0200,SR); } while (0) + #define IRQ_RESTORE(x) \ + do { (void)x; asm(move x,SR); } while (0) + + static inline bool irq_running(void) + { + extern void *user_sp; + return !!user_sp; + } + #define IRQ_RUNNING() irq_running() + + static inline bool irq_enabled(void) + { + uint16_t x; + asm(move SR,x); + return !(x & 0x0200); + } + #define IRQ_ENABLED() irq_enabled() + +#elif CPU_AVR + + #define IRQ_DISABLE asm volatile ("cli" ::) + #define IRQ_ENABLE asm volatile ("sei" ::) + + #define IRQ_SAVE_DISABLE(x) \ + do { \ + __asm__ __volatile__( \ + "in %0,__SREG__\n\t" \ + "cli" \ + : "=r" (x) : /* no inputs */ : "cc" \ + ); \ + } while (0) + + #define IRQ_RESTORE(x) \ + do { \ + __asm__ __volatile__( \ + "out __SREG__,%0" : /* no outputs */ : "r" (x) : "cc" \ + ); \ + } while (0) + + #define IRQ_ENABLED() \ + ({ \ + uint8_t sreg; \ + __asm__ __volatile__( \ + "in %0,__SREG__\n\t" \ + : "=r" (sreg) /* no inputs & no clobbers */ \ + ); \ + (bool)(sreg & 0x80); \ + }) +#else + #error No CPU_... defined. +#endif + +#ifndef IRQ_ENTRY + #define IRQ_ENTRY() /* NOP */ +#endif + +#ifndef IRQ_EXIT + #define IRQ_EXIT() /* NOP */ +#endif + + +/** + * Execute \a CODE atomically with respect to interrupts. + * + * \see IRQ_SAVE_DISABLE IRQ_RESTORE + */ +#define ATOMIC(CODE) \ + do { \ + cpuflags_t __flags; \ + IRQ_SAVE_DISABLE(__flags); \ + CODE; \ + IRQ_RESTORE(__flags); \ + } while (0) + + +#ifndef BREAKPOINT +#define BREAKPOINT /* nop */ +#endif + + +#endif /* CPU_IRQ_H */ diff --git a/bertos/cpu/newcore b/bertos/cpu/newcore new file mode 100755 index 00000000..043764c9 --- /dev/null +++ b/bertos/cpu/newcore @@ -0,0 +1,17 @@ +#!/bin/bash + +DIRS="drv hw io scripts" +if [ $# != 1 ]; then + echo "Create a new core tree with subdirs:" + echo $DIRS + echo "usage $0 " + exit 1 +fi +CORE=$1 +mkdir $CORE +cd $CORE +for dir in $DIRS +do + mkdir $dir +done +cd .. diff --git a/bertos/cpu/types.h b/bertos/cpu/types.h new file mode 100644 index 00000000..be9b5fd5 --- /dev/null +++ b/bertos/cpu/types.h @@ -0,0 +1,193 @@ +/** + * \file + * + * + * \brief CPU-specific type definitions. + * + * \author Giovanni Bajo + * \author Bernardo Innocenti + * \author Stefano Fedrigo + * \author Francesco Sacchi + */ +#ifndef CPU_TYPES_H +#define CPU_TYPES_H + +#include "detect.h" +#include "attr.h" +#include /* for uintXX_t */ + +#if CPU_I196 + + typedef uint16_t cpuflags_t; // FIXME + typedef unsigned int cpustack_t; + #warning Verify following constant + #define SIZEOF_CPUSTACK_T 2 + +#elif CPU_X86 + + /* Get IRQ_* definitions from the hosting environment. */ + #include + #if OS_EMBEDDED + typedef uint32_t cpuflags_t; // FIXME + #endif /* OS_EMBEDDED */ + + #if CPU_X86_64 + typedef uint64_t cpustack_t; + #define SIZEOF_CPUSTACK_T 8 + #else + typedef uint32_t cpustack_t; + #define SIZEOF_CPUSTACK_T 4 + #endif + +#elif CPU_ARM + + typedef uint32_t cpuflags_t; + typedef uint32_t cpustack_t; + #define SIZEOF_CPUSTACK_T 4 + +#elif CPU_PPC + + typedef uint32_t cpuflags_t; // FIXME + typedef uint32_t cpustack_t; // FIXME + #define SIZEOF_CPUSTACK_T 4 + +#elif CPU_DSP56K + + typedef uint16_t cpuflags_t; + typedef unsigned int cpustack_t; + #warning Verify following costant + #define SIZEOF_CPUSTACK_T 2 + +#elif CPU_AVR + + typedef uint8_t cpuflags_t; + typedef uint8_t cpustack_t; + #define SIZEOF_CPUSTACK_T 1 + +#else + #error No CPU_... defined. +#endif + +/** + * \name Default type sizes. + * + * These defaults are reasonable for most 16/32bit machines. + * Some of these macros may be overridden by CPU-specific code above. + * + * ANSI C requires that the following equations be true: + * \code + * sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) + * sizeof(float) <= sizeof(double) + * CPU_BITS_PER_CHAR >= 8 + * CPU_BITS_PER_SHORT >= 8 + * CPU_BITS_PER_INT >= 16 + * CPU_BITS_PER_LONG >= 32 + * \endcode + * \{ + */ +#ifndef SIZEOF_CHAR +#define SIZEOF_CHAR 1 +#endif + +#ifndef SIZEOF_SHORT +#define SIZEOF_SHORT 2 +#endif + +#ifndef SIZEOF_INT +#if CPU_REG_BITS < 32 + #define SIZEOF_INT 2 +#else + #define SIZEOF_INT 4 +#endif +#endif /* !SIZEOF_INT */ + +#ifndef SIZEOF_LONG +#if CPU_REG_BITS > 32 + #define SIZEOF_LONG 8 +#else + #define SIZEOF_LONG 4 +#endif +#endif + +#ifndef SIZEOF_PTR +#if CPU_REG_BITS < 32 + #define SIZEOF_PTR 2 +#elif CPU_REG_BITS == 32 + #define SIZEOF_PTR 4 +#else /* CPU_REG_BITS > 32 */ + #define SIZEOF_PTR 8 +#endif +#endif + +#ifndef CPU_BITS_PER_CHAR +#define CPU_BITS_PER_CHAR (SIZEOF_CHAR * 8) +#endif + +#ifndef CPU_BITS_PER_SHORT +#define CPU_BITS_PER_SHORT (SIZEOF_SHORT * CPU_BITS_PER_CHAR) +#endif + +#ifndef CPU_BITS_PER_INT +#define CPU_BITS_PER_INT (SIZEOF_INT * CPU_BITS_PER_CHAR) +#endif + +#ifndef CPU_BITS_PER_LONG +#define CPU_BITS_PER_LONG (SIZEOF_LONG * CPU_BITS_PER_CHAR) +#endif + +#ifndef CPU_BITS_PER_PTR +#define CPU_BITS_PER_PTR (SIZEOF_PTR * CPU_BITS_PER_CHAR) +#endif + + +/*\}*/ + +/* Sanity checks for the above definitions */ +STATIC_ASSERT(sizeof(char) == SIZEOF_CHAR); +STATIC_ASSERT(sizeof(short) == SIZEOF_SHORT); +STATIC_ASSERT(sizeof(long) == SIZEOF_LONG); +STATIC_ASSERT(sizeof(int) == SIZEOF_INT); +STATIC_ASSERT(sizeof(void *) == SIZEOF_PTR); +STATIC_ASSERT(sizeof(int8_t) * CPU_BITS_PER_CHAR == 8); +STATIC_ASSERT(sizeof(uint8_t) * CPU_BITS_PER_CHAR == 8); +STATIC_ASSERT(sizeof(int16_t) * CPU_BITS_PER_CHAR == 16); +STATIC_ASSERT(sizeof(uint16_t) * CPU_BITS_PER_CHAR == 16); +STATIC_ASSERT(sizeof(int32_t) * CPU_BITS_PER_CHAR == 32); +STATIC_ASSERT(sizeof(uint32_t) * CPU_BITS_PER_CHAR == 32); +#ifdef __HAS_INT64_T__ +STATIC_ASSERT(sizeof(int64_t) * CPU_BITS_PER_CHAR == 64); +STATIC_ASSERT(sizeof(uint64_t) * CPU_BITS_PER_CHAR == 64); +#endif +STATIC_ASSERT(sizeof(cpustack_t) == SIZEOF_CPUSTACK_T); + + +#endif /* CPU_TYPES_H */ diff --git a/cpu/arm/drv/kdebug_arm.c b/cpu/arm/drv/kdebug_arm.c deleted file mode 100644 index 9e16ba22..00000000 --- a/cpu/arm/drv/kdebug_arm.c +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief Low-level kdebug module for ARM (inplementation). - */ - -#include - -#if CPU_ARM_AT91 - #include "kdebug_at91.c" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif diff --git a/cpu/arm/drv/kdebug_at91.c b/cpu/arm/drv/kdebug_at91.c deleted file mode 100644 index b7e24cd3..00000000 --- a/cpu/arm/drv/kdebug_at91.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * \file - * - * - * \brief ARM debug support (implementation). - * - * \version $Id$ - * \author Francesco Sacchi - */ - -#include "kdebug_at91.h" -#include /* for BV(), DIV_ROUND */ -#include -#include /* for CLOCK_FREQ */ -#include /* Required for bus macros overrides */ - -#include - -#if CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU - #define KDBG_WAIT_READY() while (!(DBGU_SR & BV(US_TXRDY))) {} - #define KDBG_WAIT_TXDONE() while (!(DBGU_SR & BV(US_TXEMPTY))) {} - - #define KDBG_WRITE_CHAR(c) do { DBGU_THR = (c); } while(0) - - /* Debug unit is used only for debug purposes so does not generate interrupts. */ - #define KDBG_MASK_IRQ(old) do { (void)old; } while(0) - - /* Debug unit is used only for debug purposes so does not generate interrupts. */ - #define KDBG_RESTORE_IRQ(old) do { (void)old; } while(0) - - typedef uint32_t kdbg_irqsave_t; - -#else - #error CONFIG_KDEBUG_PORT should be KDEBUG_PORT_DBGU -#endif - - -INLINE void kdbg_hw_init(void) -{ - #if CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU - /* Disable all DBGU interrupts. */ - DBGU_IDR = 0xFFFFFFFF; - /* Reset DBGU */ - DBGU_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS); - /* Set baudrate */ - DBGU_BRGR = DIV_ROUND(CLOCK_FREQ, 16 * CONFIG_KDEBUG_BAUDRATE); - /* Set DBGU mode to 8 data bits, no parity and 1 stop bit. */ - DBGU_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1; - /* Enable DBGU transmitter. */ - DBGU_CR = BV(US_TXEN); - /* Disable PIO on DGBU tx pin. */ - PIOA_PDR = BV(DTXD); - PIOA_ASR = BV(DTXD); - - #if 0 /* Disable Rx for now */ - /* Enable DBGU receiver. */ - DBGU_CR = BV(US_RXEN); - /* Disable PIO on DGBU rx pin. */ - PIOA_PDR = BV(DRXD); - PIOA_ASR = BV(DRXD); - #endif - #else - #error CONFIG_KDEBUG_PORT should be KDEBUG_PORT_DBGU - #endif /* CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU */ -} diff --git a/cpu/arm/drv/kdebug_at91.h b/cpu/arm/drv/kdebug_at91.h deleted file mode 100644 index 165764e5..00000000 --- a/cpu/arm/drv/kdebug_at91.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief ARM debug support (interface). - */ - -#ifndef DRV_KDEBUG_AT91_H -#define DRV_KDEBUG_AT91_H - -/** - * \name Values for CONFIG_KDEBUG_PORT. - * - * Select which hardware UART to use for system debug. - * - * \{ - */ -#define KDEBUG_PORT_DBGU 0 ///< Debug on Debug Unit. - -#define KDEBUG_PORT_DEFAULT KDEBUG_PORT_DBGU ///< Default debug port. -/* \} */ - -#endif /* DRV_KDEBUG_AT91_H */ diff --git a/cpu/arm/drv/ser_arm.c b/cpu/arm/drv/ser_arm.c deleted file mode 100644 index dbd84d75..00000000 --- a/cpu/arm/drv/ser_arm.c +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file - * - * - * \version $Id: timer_arm.c 18260 2007-10-11 14:08:10Z batt $ - * - * \author Daniele Basile - * - * \brief Low-level USART module for ARM (inplementation). - */ - -#include - -#if CPU_ARM_AT91 - #include "ser_at91.c" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif diff --git a/cpu/arm/drv/ser_arm.h b/cpu/arm/drv/ser_arm.h deleted file mode 100644 index d3abfea6..00000000 --- a/cpu/arm/drv/ser_arm.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file - * - * - * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ - * - * \author Daniele Basile - * - * \brief Low-level serial module for ARM (interface). - */ - -#include - -#if CPU_ARM_AT91 - #include "ser_at91.h" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif diff --git a/cpu/arm/drv/ser_at91.c b/cpu/arm/drv/ser_at91.c deleted file mode 100644 index 74cca47b..00000000 --- a/cpu/arm/drv/ser_at91.c +++ /dev/null @@ -1,946 +0,0 @@ -/** - * \file - * - * - * \brief ARM UART and SPI I/O driver - * - * - * \version $Id: ser_at91.c 20881 2008-03-04 14:07:02Z batt $ - * \author Daniele Basile - */ - -#include - -#include -#include -#include - -#include /* Required for bus macros overrides */ -#include /* CLOCK_FREQ */ - -#include -#include - -#include - -#define SERIRQ_PRIORITY 4 ///< default priority for serial irqs. - -/** - * \name Overridable serial bus hooks - * - * These can be redefined in hw.h to implement - * special bus policies such as half-duplex, 485, etc. - * - * - * \code - * TXBEGIN TXCHAR TXEND TXOFF - * | __________|__________ | | - * | | | | | | | | | - * v v v v v v v v v - * ______ __ __ __ __ __ __ ________________ - * \/ \/ \/ \/ \/ \/ \/ - * ______/\__/\__/\__/\__/\__/\__/ - * - * \endcode - * - * \{ - */ - -#ifndef SER_UART0_BUS_TXINIT - /** - * Default TXINIT macro - invoked in uart0_init() - * - * - Disable GPIO on USART0 tx/rx pins - */ - #if !CPU_ARM_AT91SAM7S256 && !CPU_ARM_AT91SAM7X256 && !CPU_ARM_AT91SAM7X128 - #warning Check USART0 pins! - #endif - #define SER_UART0_BUS_TXINIT do { \ - PIOA_PDR = BV(RXD0) | BV(TXD0); \ - } while (0) - -#endif - -#ifndef SER_UART0_BUS_TXBEGIN - /** - * Invoked before starting a transmission - */ - #define SER_UART0_BUS_TXBEGIN -#endif - -#ifndef SER_UART0_BUS_TXCHAR - /** - * Invoked to send one character. - */ - #define SER_UART0_BUS_TXCHAR(c) do { \ - US0_THR = (c); \ - } while (0) -#endif - -#ifndef SER_UART0_BUS_TXEND - /** - * Invoked as soon as the txfifo becomes empty - */ - #define SER_UART0_BUS_TXEND -#endif - -/* End USART0 macros */ - -#ifndef SER_UART1_BUS_TXINIT - /** - * Default TXINIT macro - invoked in uart1_init() - * - * - Disable GPIO on USART1 tx/rx pins - */ - #if !CPU_ARM_AT91SAM7S256 && !CPU_ARM_AT91SAM7X256 && !CPU_ARM_AT91SAM7X128 - #warning Check USART1 pins! - #endif - #define SER_UART1_BUS_TXINIT do { \ - PIOA_PDR = BV(RXD1) | BV(TXD1); \ - } while (0) - -#endif - -#ifndef SER_UART1_BUS_TXBEGIN - /** - * Invoked before starting a transmission - */ - #define SER_UART1_BUS_TXBEGIN -#endif - -#ifndef SER_UART1_BUS_TXCHAR - /** - * Invoked to send one character. - */ - #define SER_UART1_BUS_TXCHAR(c) do { \ - US1_THR = (c); \ - } while (0) -#endif - -#ifndef SER_UART1_BUS_TXEND - /** - * Invoked as soon as the txfifo becomes empty - */ - #define SER_UART1_BUS_TXEND -#endif - -/** -* \name Overridable SPI hooks -* -* These can be redefined in hw.h to implement -* special bus policies such as slave select pin handling, etc. -* -* \{ -*/ - -#ifndef SER_SPI0_BUS_TXINIT - /** - * Default TXINIT macro - invoked in spi_init() - * The default is no action. - */ - #define SER_SPI0_BUS_TXINIT -#endif - -#ifndef SER_SPI0_BUS_TXCLOSE - /** - * Invoked after the last character has been transmitted. - * The default is no action. - */ - #define SER_SPI0_BUS_TXCLOSE -#endif - -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 - - #ifndef SER_SPI1_BUS_TXINIT - /** - * Default TXINIT macro - invoked in spi_init() - * The default is no action. - */ - #define SER_SPI1_BUS_TXINIT - #endif - - #ifndef SER_SPI1_BUS_TXCLOSE - /** - * Invoked after the last character has been transmitted. - * The default is no action. - */ - #define SER_SPI1_BUS_TXCLOSE - #endif -#endif -/*\}*/ - - -/** - * \def CONFIG_SER_STROBE - * - * This is a debug facility that can be used to - * monitor SER interrupt activity on an external pin. - * - * To use strobes, redefine the macros SER_STROBE_ON, - * SER_STROBE_OFF and SER_STROBE_INIT and set - * CONFIG_SER_STROBE to 1. - */ -#if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE - #define SER_STROBE_ON do {/*nop*/} while(0) - #define SER_STROBE_OFF do {/*nop*/} while(0) - #define SER_STROBE_INIT do {/*nop*/} while(0) -#endif - - -/* From the high-level serial driver */ -extern struct Serial ser_handles[SER_CNT]; - -/* TX and RX buffers */ -static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; -static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; - -static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; -static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; - -static unsigned char spi0_txbuffer[CONFIG_SPI0_TXBUFSIZE]; -static unsigned char spi0_rxbuffer[CONFIG_SPI0_RXBUFSIZE]; -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -static unsigned char spi1_txbuffer[CONFIG_SPI1_TXBUFSIZE]; -static unsigned char spi1_rxbuffer[CONFIG_SPI1_RXBUFSIZE]; -#endif - -/** - * Internal hardware state structure - * - * The \a sending variable is true while the transmission - * interrupt is retriggering itself. - * - * For the USARTs the \a sending flag is useful for taking specific - * actions before sending a burst of data, at the start of a trasmission - * but not before every char sent. - * - * For the SPI, this flag is necessary because the SPI sends and receives - * bytes at the same time and the SPI IRQ is unique for send/receive. - * The only way to start transmission is to write data in SPDR (this - * is done by spi_starttx()). We do this *only* if a transfer is - * not already started. - */ -struct ArmSerial -{ - struct SerialHardware hw; - volatile bool sending; -}; - - -/* - * These are to trick GCC into *not* using absolute addressing mode - * when accessing ser_handles, which is very expensive. - * - * Accessing through these pointers generates much shorter - * (and hopefully faster) code. - */ -struct Serial *ser_uart0 = &ser_handles[SER_UART0]; -struct Serial *ser_uart1 = &ser_handles[SER_UART1]; - -struct Serial *ser_spi0 = &ser_handles[SER_SPI0]; -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -struct Serial *ser_spi1 = &ser_handles[SER_SPI1]; -#endif - -static void uart0_irq_dispatcher(void); -static void uart1_irq_dispatcher(void); -static void spi0_irq_handler(void); -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -static void spi1_irq_handler(void); -#endif -/* - * Callbacks for USART0 - */ -static void uart0_init( - UNUSED_ARG(struct SerialHardware *, _hw), - UNUSED_ARG(struct Serial *, ser)) -{ - US0_IDR = 0xFFFFFFFF; - /* Set the vector. */ - AIC_SVR(US0_ID) = uart0_irq_dispatcher; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(US0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; - PMC_PCER = BV(US0_ID); - - /* - * - Reset USART0 - * - Set serial param: mode Normal, 8bit data, 1bit stop, parity none - * - Enable both the receiver and the transmitter - * - Enable only the RX complete interrupt - */ - US0_CR = BV(US_RSTRX) | BV(US_RSTTX); - US0_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO; - US0_CR = BV(US_RXEN) | BV(US_TXEN); - US0_IER = BV(US_RXRDY); - - SER_UART0_BUS_TXINIT; - - /* Enable the USART IRQ */ - AIC_IECR = BV(US0_ID); - - SER_STROBE_INIT; -} - -static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - US0_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA); -} - -static void uart0_enabletxirq(struct SerialHardware *_hw) -{ - struct ArmSerial *hw = (struct ArmSerial *)_hw; - - /* - * WARNING: racy code here! The tx interrupt sets hw->sending to false - * when it runs with an empty fifo. The order of statements in the - * if-block matters. - */ - if (!hw->sending) - { - hw->sending = true; - /* - * - Enable the transmitter - * - Enable TX empty interrupt - */ - SER_UART0_BUS_TXBEGIN; - US0_IER = BV(US_TXEMPTY); - } -} - -static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - /* Compute baud-rate period */ - US0_BRGR = CLOCK_FREQ / (16 * rate); - //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) -} - -static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) -{ - US0_MR &= ~US_PAR_MASK; - /* Set UART parity */ - switch(parity) - { - case SER_PARITY_NONE: - { - /* Parity none. */ - US0_MR |= US_PAR_NO; - break; - } - case SER_PARITY_EVEN: - { - /* Even parity. */ - US0_MR |= US_PAR_EVEN; - break; - } - case SER_PARITY_ODD: - { - /* Odd parity. */ - US0_MR |= US_PAR_ODD; - break; - } - default: - ASSERT(0); - } - -} -/* - * Callbacks for USART1 - */ -static void uart1_init( - UNUSED_ARG(struct SerialHardware *, _hw), - UNUSED_ARG(struct Serial *, ser)) -{ - US1_IDR = 0xFFFFFFFF; - /* Set the vector. */ - AIC_SVR(US1_ID) = uart1_irq_dispatcher; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(US1_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; - PMC_PCER = BV(US1_ID); - - /* - * - Reset USART1 - * - Set serial param: mode Normal, 8bit data, 1bit stop, parity none - * - Enable both the receiver and the transmitter - * - Enable only the RX complete interrupt - */ - US1_CR = BV(US_RSTRX) | BV(US_RSTTX); - US1_MR = US_CHMODE_NORMAL | US_CHRL_8 | US_NBSTOP_1 | US_PAR_NO; - US1_CR = BV(US_RXEN) | BV(US_TXEN); - US1_IER = BV(US_RXRDY); - - SER_UART1_BUS_TXINIT; - - /* Enable the USART IRQ */ - AIC_IECR = BV(US1_ID); - - SER_STROBE_INIT; -} - -static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - US1_CR = BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS) | BV(US_RSTSTA); -} - -static void uart1_enabletxirq(struct SerialHardware *_hw) -{ - struct ArmSerial *hw = (struct ArmSerial *)_hw; - - /* - * WARNING: racy code here! The tx interrupt sets hw->sending to false - * when it runs with an empty fifo. The order of statements in the - * if-block matters. - */ - if (!hw->sending) - { - hw->sending = true; - /* - * - Enable the transmitter - * - Enable TX empty interrupt - */ - SER_UART1_BUS_TXBEGIN; - US1_IER = BV(US_TXEMPTY); - } -} - -static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - /* Compute baud-rate period */ - US1_BRGR = CLOCK_FREQ / (16 * rate); - //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) -} - -static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) -{ - US1_MR &= ~US_PAR_MASK; - /* Set UART parity */ - switch(parity) - { - case SER_PARITY_NONE: - { - /* Parity none. */ - US1_MR |= US_PAR_NO; - break; - } - case SER_PARITY_EVEN: - { - /* Even parity. */ - US1_MR |= US_PAR_EVEN; - break; - } - case SER_PARITY_ODD: - { - /* Odd parity. */ - US1_MR |= US_PAR_ODD; - break; - } - default: - ASSERT(0); - } - -} - -/* SPI driver */ -static void spi0_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) -{ - /* Disable PIO on SPI pins */ - PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); - - /* Reset device */ - SPI0_CR = BV(SPI_SWRST); - - /* - * Set SPI to master mode, fixed peripheral select, chip select directly connected to a peripheral device, - * SPI clock set to MCK, mode fault detection disabled, loopback disable, NPCS0 active, Delay between CS = 0 - */ - SPI0_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); - - /* - * Set SPI mode. - * At reset clock division factor is set to 0, that is - * *forbidden*. Set SPI clock to minimum to keep it valid. - */ - SPI0_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); - - /* Disable all irqs */ - SPI0_IDR = 0xFFFFFFFF; - /* Set the vector. */ - AIC_SVR(SPI0_ID) = spi0_irq_handler; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(SPI0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; - /* Enable the USART IRQ */ - AIC_IECR = BV(SPI0_ID); - PMC_PCER = BV(SPI0_ID); - - /* Enable interrupt on tx buffer empty */ - SPI0_IER = BV(SPI_TXEMPTY); - - /* Enable SPI */ - SPI0_CR = BV(SPI_SPIEN); - - - SER_SPI0_BUS_TXINIT; - - SER_STROBE_INIT; -} - -static void spi0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - /* Disable SPI */ - SPI0_CR = BV(SPI_SPIDIS); - - /* Disable all irqs */ - SPI0_IDR = 0xFFFFFFFF; - - SER_SPI0_BUS_TXCLOSE; - - /* Enable PIO on SPI pins */ - PIOA_PER = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); -} - -static void spi0_starttx(struct SerialHardware *_hw) -{ - struct ArmSerial *hw = (struct ArmSerial *)_hw; - - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Send data only if the SPI is not already transmitting */ - if (!hw->sending && !fifo_isempty(&ser_spi0->txfifo)) - { - hw->sending = true; - SPI0_TDR = fifo_pop(&ser_spi0->txfifo); - } - - IRQ_RESTORE(flags); -} - -static void spi0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - SPI0_CSR0 &= ~SPI_SCBR; - - ASSERT((uint8_t)DIV_ROUND(CLOCK_FREQ, rate)); - SPI0_CSR0 |= DIV_ROUND(CLOCK_FREQ, rate) << SPI_SCBR_SHIFT; -} - -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -/* SPI driver */ -static void spi1_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) -{ - /* Disable PIO on SPI pins */ - PIOA_PDR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); - - /* Reset device */ - SPI1_CR = BV(SPI_SWRST); - -/* - * Set SPI to master mode, fixed peripheral select, chip select directly connected to a peripheral device, - * SPI clock set to MCK, mode fault detection disabled, loopback disable, NPCS0 active, Delay between CS = 0 - */ - SPI1_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); - - /* - * Set SPI mode. - * At reset clock division factor is set to 0, that is - * *forbidden*. Set SPI clock to minimum to keep it valid. - */ - SPI1_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); - - /* Disable all irqs */ - SPI1_IDR = 0xFFFFFFFF; - /* Set the vector. */ - AIC_SVR(SPI1_ID) = spi1_irq_handler; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(SPI1_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SERIRQ_PRIORITY; - /* Enable the USART IRQ */ - AIC_IECR = BV(SPI1_ID); - PMC_PCER = BV(SPI1_ID); - - /* Enable interrupt on tx buffer empty */ - SPI1_IER = BV(SPI_TXEMPTY); - - /* Enable SPI */ - SPI1_CR = BV(SPI_SPIEN); - - - SER_SPI1_BUS_TXINIT; - - SER_STROBE_INIT; -} - -static void spi1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - /* Disable SPI */ - SPI1_CR = BV(SPI_SPIDIS); - - /* Disable all irqs */ - SPI1_IDR = 0xFFFFFFFF; - - SER_SPI1_BUS_TXCLOSE; - - /* Enable PIO on SPI pins */ - PIOA_PER = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_MISO); -} - -static void spi1_starttx(struct SerialHardware *_hw) -{ - struct ArmSerial *hw = (struct ArmSerial *)_hw; - - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Send data only if the SPI is not already transmitting */ - if (!hw->sending && !fifo_isempty(&ser_spi1->txfifo)) - { - hw->sending = true; - SPI1_TDR = fifo_pop(&ser_spi1->txfifo); - } - - IRQ_RESTORE(flags); -} - -static void spi1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - SPI1_CSR0 &= ~SPI_SCBR; - - ASSERT((uint8_t)DIV_ROUND(CLOCK_FREQ, rate)); - SPI1_CSR0 |= DIV_ROUND(CLOCK_FREQ, rate) << SPI_SCBR_SHIFT; -} -#endif - -static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity)) -{ - // nop -} - - -static bool tx_sending(struct SerialHardware* _hw) -{ - struct ArmSerial *hw = (struct ArmSerial *)_hw; - return hw->sending; -} - -// FIXME: move into compiler.h? Ditch? -#if COMPILER_C99 - #define C99INIT(name,val) .name = val -#elif defined(__GNUC__) - #define C99INIT(name,val) name: val -#else - #warning No designated initializers, double check your code - #define C99INIT(name,val) (val) -#endif - -/* - * High-level interface data structures - */ -static const struct SerialHardwareVT UART0_VT = -{ - C99INIT(init, uart0_init), - C99INIT(cleanup, uart0_cleanup), - C99INIT(setBaudrate, uart0_setbaudrate), - C99INIT(setParity, uart0_setparity), - C99INIT(txStart, uart0_enabletxirq), - C99INIT(txSending, tx_sending), -}; - -static const struct SerialHardwareVT UART1_VT = -{ - C99INIT(init, uart1_init), - C99INIT(cleanup, uart1_cleanup), - C99INIT(setBaudrate, uart1_setbaudrate), - C99INIT(setParity, uart1_setparity), - C99INIT(txStart, uart1_enabletxirq), - C99INIT(txSending, tx_sending), -}; - -static const struct SerialHardwareVT SPI0_VT = -{ - C99INIT(init, spi0_init), - C99INIT(cleanup, spi0_cleanup), - C99INIT(setBaudrate, spi0_setbaudrate), - C99INIT(setParity, spi_setparity), - C99INIT(txStart, spi0_starttx), - C99INIT(txSending, tx_sending), -}; -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -static const struct SerialHardwareVT SPI1_VT = -{ - C99INIT(init, spi1_init), - C99INIT(cleanup, spi1_cleanup), - C99INIT(setBaudrate, spi1_setbaudrate), - C99INIT(setParity, spi_setparity), - C99INIT(txStart, spi1_starttx), - C99INIT(txSending, tx_sending), -}; -#endif - -static struct ArmSerial UARTDescs[SER_CNT] = -{ - { - C99INIT(hw, /**/) { - C99INIT(table, &UART0_VT), - C99INIT(txbuffer, uart0_txbuffer), - C99INIT(rxbuffer, uart0_rxbuffer), - C99INIT(txbuffer_size, sizeof(uart0_txbuffer)), - C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)), - }, - C99INIT(sending, false), - }, - { - C99INIT(hw, /**/) { - C99INIT(table, &UART1_VT), - C99INIT(txbuffer, uart1_txbuffer), - C99INIT(rxbuffer, uart1_rxbuffer), - C99INIT(txbuffer_size, sizeof(uart1_txbuffer)), - C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)), - }, - C99INIT(sending, false), - }, - - { - C99INIT(hw, /**/) { - C99INIT(table, &SPI0_VT), - C99INIT(txbuffer, spi0_txbuffer), - C99INIT(rxbuffer, spi0_rxbuffer), - C99INIT(txbuffer_size, sizeof(spi0_txbuffer)), - C99INIT(rxbuffer_size, sizeof(spi0_rxbuffer)), - }, - C99INIT(sending, false), - }, - #if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 - { - C99INIT(hw, /**/) { - C99INIT(table, &SPI1_VT), - C99INIT(txbuffer, spi1_txbuffer), - C99INIT(rxbuffer, spi1_rxbuffer), - C99INIT(txbuffer_size, sizeof(spi1_txbuffer)), - C99INIT(rxbuffer_size, sizeof(spi1_rxbuffer)), - }, - C99INIT(sending, false), - } - - #endif -}; - -struct SerialHardware *ser_hw_getdesc(int unit) -{ - ASSERT(unit < SER_CNT); - return &UARTDescs[unit].hw; -} - -/** - * Serial 0 TX interrupt handler - */ -static void uart0_irq_tx(void) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; - - if (fifo_isempty(txfifo)) - { - /* - * - Disable the TX empty interrupts - */ - US0_IDR = BV(US_TXEMPTY); - SER_UART0_BUS_TXEND; - UARTDescs[SER_UART0].sending = false; - } - else - { - char c = fifo_pop(txfifo); - SER_UART0_BUS_TXCHAR(c); - } - - SER_STROBE_OFF; -} - -/** - * Serial 0 RX complete interrupt handler. - */ -static void uart0_irq_rx(void) -{ - SER_STROBE_ON; - - /* Should be read before US_CRS */ - ser_uart0->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); - - char c = US0_RHR; - struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo; - - if (fifo_isfull(rxfifo)) - ser_uart0->status |= SERRF_RXFIFOOVERRUN; - else - fifo_push(rxfifo, c); - - SER_STROBE_OFF; -} - -/** - * Serial IRQ dispatcher for USART0. - */ -static void uart0_irq_dispatcher(void) __attribute__ ((interrupt)); -static void uart0_irq_dispatcher(void) -{ - if (US0_CSR & BV(US_RXRDY)) - uart0_irq_rx(); - - if (US0_CSR & BV(US_TXEMPTY)) - uart0_irq_tx(); - - /* Inform hw that we have served the IRQ */ - AIC_EOICR = 0; -} - -/** - * Serial 1 TX interrupt handler - */ -static void uart1_irq_tx(void) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; - - if (fifo_isempty(txfifo)) - { - /* - * - Disable the TX empty interrupts - */ - US1_IDR = BV(US_TXEMPTY); - SER_UART1_BUS_TXEND; - UARTDescs[SER_UART1].sending = false; - } - else - { - char c = fifo_pop(txfifo); - SER_UART1_BUS_TXCHAR(c); - } - - SER_STROBE_OFF; -} - -/** - * Serial 1 RX complete interrupt handler. - */ -static void uart1_irq_rx(void) -{ - SER_STROBE_ON; - - /* Should be read before US_CRS */ - ser_uart1->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); - - char c = US1_RHR; - struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo; - - if (fifo_isfull(rxfifo)) - ser_uart1->status |= SERRF_RXFIFOOVERRUN; - else - fifo_push(rxfifo, c); - - SER_STROBE_OFF; -} - -/** - * Serial IRQ dispatcher for USART1. - */ -static void uart1_irq_dispatcher(void) __attribute__ ((interrupt)); -static void uart1_irq_dispatcher(void) -{ - if (US1_CSR & BV(US_RXRDY)) - uart1_irq_rx(); - - if (US1_CSR & BV(US_TXEMPTY)) - uart1_irq_tx(); - - /* Inform hw that we have served the IRQ */ - AIC_EOICR = 0; -} - -/** - * SPI0 interrupt handler - */ -static void spi0_irq_handler(void) __attribute__ ((interrupt)); -static void spi0_irq_handler(void) -{ - SER_STROBE_ON; - - char c = SPI0_RDR; - /* Read incoming byte. */ - if (!fifo_isfull(&ser_spi0->rxfifo)) - fifo_push(&ser_spi0->rxfifo, c); - /* - * FIXME - else - ser_spi0->status |= SERRF_RXFIFOOVERRUN; - */ - - /* Send */ - if (!fifo_isempty(&ser_spi0->txfifo)) - SPI0_TDR = fifo_pop(&ser_spi0->txfifo); - else - UARTDescs[SER_SPI0].sending = false; - - /* Inform hw that we have served the IRQ */ - AIC_EOICR = 0; - SER_STROBE_OFF; -} - - -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -/** - * SPI1 interrupt handler - */ -static void spi1_irq_handler(void) __attribute__ ((interrupt)); -static void spi1_irq_handler(void) -{ - SER_STROBE_ON; - - char c = SPI1_RDR; - /* Read incoming byte. */ - if (!fifo_isfull(&ser_spi1->rxfifo)) - fifo_push(&ser_spi1->rxfifo, c); - /* - * FIXME - else - ser_spi1->status |= SERRF_RXFIFOOVERRUN; - */ - - /* Send */ - if (!fifo_isempty(&ser_spi1->txfifo)) - SPI1_TDR = fifo_pop(&ser_spi1->txfifo); - else - UARTDescs[SER_SPI1].sending = false; - - /* Inform hw that we have served the IRQ */ - AIC_EOICR = 0; - SER_STROBE_OFF; -} -#endif diff --git a/cpu/arm/drv/ser_at91.h b/cpu/arm/drv/ser_at91.h deleted file mode 100644 index fd836c41..00000000 --- a/cpu/arm/drv/ser_at91.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * \file - * - * - * \brief High level serial I/O API - * - * \version $Id: ser_at91.h 20552 2008-02-14 16:40:41Z batt $ - * \author Daniele Basile - */ - -#ifndef SER_AT91_H -#define SER_AT91_H - -#include /* BV() */ -#include /* uint32_t */ -#include /* CPU_* */ - -/** \name Serial Error/status flags. */ -/*\{*/ -typedef uint32_t serstatus_t; - -/* Software errors */ -#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ -#define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */ -#define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */ - -/* - * Hardware errors. - * These flags map directly to the ARM USART Channel Status Register (US_CSR). - */ -#define SERRF_RXSROVERRUN BV(5) /**< Rx shift register overrun */ -#define SERRF_FRAMEERROR BV(6) /**< Stop bit missing */ -#define SERRF_PARITYERROR BV(7) /**< Parity error */ -#define SERRF_NOISEERROR 0 /**< Unsupported */ -/*\}*/ - -/** - * \name Serial hw numbers - * - * \{ - */ -enum -{ -SER_UART0, -SER_UART1, -SER_SPI0, -#if CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7X256 -SER_SPI1, -#endif -SER_CNT /**< Number of serial ports */ -}; -/*\}*/ - -#endif /* SER_AT91_H */ diff --git a/cpu/arm/drv/sysirq_at91.c b/cpu/arm/drv/sysirq_at91.c deleted file mode 100644 index 281c7963..00000000 --- a/cpu/arm/drv/sysirq_at91.c +++ /dev/null @@ -1,171 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief System IRQ handler for Atmel AT91 ARM7 processors. - * - * In Atmel AT91 ARM7TDMI processors, there are various - * peripheral interrupt sources. - * In general, every source has its own interrupt vector, so it - * is possible to assign a specific handler for each interrupt - * independently. - * However, there are a few sources called "system sources" that - * share a common IRQ line and vector, called "system IRQ". - * So a unique system IRQ dispatcher is implemented here. - * This module also contains an interface to manage every source - * independently. It is possible to assign to every system IRQ - * a specific IRQ handler. - * - * \see sysirq_setHandler - * \see sysirq_setEnable - */ - -#include "sysirq_at91.h" -#include -#include -#include -#include -#include - -/** - * Enable/disable the Periodic Interrupt Timer - * interrupt. - */ -INLINE void pit_setEnable(bool enable) -{ - if (enable) - PIT_MR |= BV(PITIEN); - else - PIT_MR &= ~BV(PITIEN); -} - -/** - * Table containing all system irqs. - */ -static SysIrq sysirq_tab[] = -{ - /* PIT, Periodic Interval Timer (System timer)*/ - { - .enabled = false, - .setEnable = pit_setEnable, - .handler = NULL, - }, - /* TODO: add other system sources here */ -}; - -STATIC_ASSERT(countof(sysirq_tab) == SYSIRQ_CNT); - -/** - * System IRQ dispatcher. - * This is the entry point for all system IRQs in AT91. - * This function checks for interrupt enable state of - * various sources (system timer, etc..) and calls - * the corresponding handler. - */ -static void sysirq_dispatcher(void) __attribute__ ((interrupt)); -static void sysirq_dispatcher(void) -{ - for (unsigned i = 0; i < countof(sysirq_tab); i++) - { - if (sysirq_tab[i].enabled - && sysirq_tab[i].handler) - sysirq_tab[i].handler(); - } - - /* Inform hw that we have served the IRQ */ - AIC_EOICR = 0; -} - -#define SYSIRQ_PRIORITY 0 ///< default priority for system irqs. - - -MOD_DEFINE(sysirq); - -/** - * Init system IRQ handling. - * \note all system interrupts are disabled. - */ -void sysirq_init(void) -{ - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Disable all system interrupts */ - for (unsigned i = 0; i < countof(sysirq_tab); i++) - sysirq_tab[i].setEnable(false); - - /* Set the vector. */ - AIC_SVR(SYSC_ID) = sysirq_dispatcher; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(SYSC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SYSIRQ_PRIORITY; - /* Clear pending interrupt */ - AIC_ICCR = BV(SYSC_ID); - /* Enable the system IRQ */ - AIC_IECR = BV(SYSC_ID); - - IRQ_RESTORE(flags); - MOD_INIT(sysirq); -} - - -/** - * Helper function used to set handler for system IRQ \a irq. - */ -void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler) -{ - ASSERT(irq < SYSIRQ_CNT); - sysirq_tab[irq].handler = handler; -} - -/** - * Helper function used to enable/disable system IRQ \a irq. - */ -void sysirq_setEnable(sysirq_t irq, bool enable) -{ - ASSERT(irq < SYSIRQ_CNT); - - sysirq_tab[irq].setEnable(enable); - sysirq_tab[irq].enabled = enable; -} - -/** - * Helper function used to get system IRQ \a irq state. - */ -bool sysirq_enabled(sysirq_t irq) -{ - ASSERT(irq < SYSIRQ_CNT); - - return sysirq_tab[irq].enabled; -} diff --git a/cpu/arm/drv/sysirq_at91.h b/cpu/arm/drv/sysirq_at91.h deleted file mode 100644 index ad094fca..00000000 --- a/cpu/arm/drv/sysirq_at91.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief System irq handler for Atmel AT91 ARM7 processors (interface). - */ - -#ifndef DRV_AT91_SYSIRQ_H -#define DRV_AT91_SYSIRQ_H - -#include - -typedef void (* sysirq_handler_t)(void); ///< Type for system irq handler. -typedef void (* sysirq_setEnable_t)(bool); ///< Type for system irq enable/disable function. - -/** - * Structure used to define a system interrupt source. - */ -typedef struct SysIrq -{ - bool enabled; ///< Getter for irq enable/disable state. - sysirq_setEnable_t setEnable; ///< Setter for irq enable/disable state. - sysirq_handler_t handler; ///< IRQ handler. -} SysIrq; - -/** - * System IRQ ID list. - */ -typedef enum sysirq_t -{ - SYSIRQ_PIT, ///< Periodic Interval Timer - /* TODO: add all system irqs */ - SYSIRQ_CNT -} sysirq_t; - -void sysirq_init(void); -void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler); -void sysirq_setEnable(sysirq_t irq, bool enable); -bool sysirq_enabled(sysirq_t irq); - -#endif /* ARCH_ARM_SYSIRQ_H */ diff --git a/cpu/arm/drv/timer_arm.c b/cpu/arm/drv/timer_arm.c deleted file mode 100644 index 405366ce..00000000 --- a/cpu/arm/drv/timer_arm.c +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief Low-level timer module for ARM (inplementation). - */ - -#include - -#if CPU_ARM_AT91 - #include "timer_at91.c" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif diff --git a/cpu/arm/drv/timer_arm.h b/cpu/arm/drv/timer_arm.h deleted file mode 100644 index 60b096cc..00000000 --- a/cpu/arm/drv/timer_arm.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief Low-level timer module for ARM (interface). - */ - -#include - -#if CPU_ARM_AT91 - #include "timer_at91.h" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif diff --git a/cpu/arm/drv/timer_at91.c b/cpu/arm/drv/timer_at91.c deleted file mode 100644 index e27e8a63..00000000 --- a/cpu/arm/drv/timer_at91.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief Low-level timer module for Atmel AT91 (inplementation). - */ - -#include "timer_at91.h" -#include -#include "sysirq_at91.h" - -#include // BV() -#include -#include -#include - - -/** HW dependent timer initialization */ -#if (CONFIG_TIMER == TIMER_ON_PIT) - INLINE void timer_hw_irq(void) - { - /* Reset counters, this is needed to reset timer and interrupt flags */ - uint32_t dummy = PIVR; - (void) dummy; - } - - INLINE bool timer_hw_triggered(void) - { - return PIT_SR & BV(PITS); - } - - INLINE void timer_hw_init(void) - { - cpuflags_t flags; - - MOD_CHECK(sysirq); - - IRQ_SAVE_DISABLE(flags); - - PIT_MR = TIMER_HW_CNT; - /* Register system interrupt handler. */ - sysirq_setHandler(SYSIRQ_PIT, timer_handler); - - /* Enable interval timer and interval timer interrupts */ - PIT_MR |= BV(PITEN); - sysirq_setEnable(SYSIRQ_PIT, true); - - /* Reset counters, this is needed to start timer and interrupt flags */ - uint32_t dummy = PIVR; - (void) dummy; - - IRQ_RESTORE(flags); - } - - INLINE hptime_t timer_hw_hpread(void) - { - /* In the upper part of PIT_PIIR there is unused data */ - return PIIR & CPIV_MASK; - } - -#else - #error Unimplemented value for CONFIG_TIMER -#endif /* CONFIG_TIMER */ diff --git a/cpu/arm/drv/timer_at91.h b/cpu/arm/drv/timer_at91.h deleted file mode 100644 index 87bccd1e..00000000 --- a/cpu/arm/drv/timer_at91.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * \brief Low-level timer module for Atmel AT91 (interface). - */ - -#ifndef DRV_AT91_TIMER_H -#define DRV_AT91_TIMER_H - -#include /* CONFIG_TIMER */ -#include /* uint8_t */ -#include /* CLOCK_FREQ */ - -/** - * \name Values for CONFIG_TIMER. - * - * Select which hardware timer interrupt to use for system clock and softtimers. - * - * \{ - */ -#define TIMER_ON_PIT 1 ///< System timer on Periodic interval timer - -#define TIMER_DEFAULT TIMER_ON_PIT ///< Default system timer -/* \} */ - -/* - * Hardware dependent timer initialization. - */ -#if (CONFIG_TIMER == TIMER_ON_PIT) - - void timer_handler(void); - - #define DEFINE_TIMER_ISR void timer_handler(void) - #define TIMER_TICKS_PER_SEC 1000 - #define TIMER_HW_CNT (CLOCK_FREQ / (16 * TIMER_TICKS_PER_SEC) - 1) - - /** Frequency of the hardware high-precision timer. */ - #define TIMER_HW_HPTICKS_PER_SEC (CLOCK_FREQ / 16) - - /// Type of time expressed in ticks of the hardware high-precision timer - typedef uint32_t hptime_t; -#else - - #error Unimplemented value for CONFIG_TIMER -#endif /* CONFIG_TIMER */ - - -#endif /* DRV_TIMER_AT91_H */ diff --git a/cpu/arm/hw/crt.s b/cpu/arm/hw/crt.s deleted file mode 100644 index 98d723ee..00000000 --- a/cpu/arm/hw/crt.s +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. 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 of the author 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. -* -**************************************************************************** -* -* History: -* -* 18.12.06 mifi First Version -* The hardware initialization is based on the startup file -* crtat91sam7x256_rom.S from NutOS 4.2.1. -* Therefore partial copyright by egnite Software GmbH. -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - AIC_BASE = 0xFFFFF000 - AIC_EOICR_OFF = 0x130 - AIC_IDCR_OFF = 0x124 - - RSTC_MR = 0xFFFFFD08 - RSTC_KEY = 0xA5000000 - RSTC_URSTEN = 0x00000001 - - WDT_BASE = 0xFFFFFD40 - WDT_MR_OFF = 0x00000004 - WDT_WDDIS = 0x00008000 - - MC_BASE = 0xFFFFFF00 - MC_FMR_OFF = 0x00000060 - MC_FWS_1FWS = 0x00480100 - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, [pc, #-0xF20] /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - -.extern maion - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: - /* - * The watchdog is enabled after processor reset. Disable it. - */ - ldr r1, =WDT_BASE - ldr r0, =WDT_WDDIS - str r0, [r1, #WDT_MR_OFF] - - - /* - * Enable user reset: assertion length programmed to 1ms - */ - ldr r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8)) - ldr r1, =RSTC_MR - str r0, [r1, #0] - - - /* - * Use 2 cycles for flash access. - */ - ldr r1, =MC_BASE - ldr r0, =MC_FWS_1FWS - str r0, [r1, #MC_FMR_OFF] - - - /* - * Disable all interrupts. Useful for debugging w/o target reset. - */ - ldr r1, =AIC_BASE - mvn r0, #0 - str r0, [r1, #AIC_EOICR_OFF] - str r0, [r1, #AIC_IDCR_OFF] - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/cpu/arm/hw/crtat91sam7_rom.S b/cpu/arm/hw/crtat91sam7_rom.S deleted file mode 100644 index 0a2fa4a7..00000000 --- a/cpu/arm/hw/crtat91sam7_rom.S +++ /dev/null @@ -1,331 +0,0 @@ -/** - * \file - * - * - * \version $Id: $ - * - * \author Francesco Sacchi - * - * \brief AT91SAM7S256 CRT, adapted from NUt/OS, see license below. - */ - -/* - * Copyright (C) 2005-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - * - */ - -#include "hw_cpu.h" -#include - - -#if CLOCK_FREQ != 48023000L -#error Clock registers set for 48MHz operation, revise following code if you want a different clock. -#endif - - -#if CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X256 - /** - * With a 18.420MHz cristal, master clock is: - * (((18.420 * PLL_MUL_VAL + 1) / PLL_DIV_VAL) / AT91MCK_PRES) = 48.023MHz - */ - #define PLL_MUL_VAL 72 /**< Real multiplier value is PLL_MUL_VAL + 1! */ - #define PLL_DIV_VAL 14 - #define AT91MCK_PRES PMC_PRES_CLK_2 - - /** - * Register I/O adresses. - * \{ - */ - #define MC_BASE 0xFFFFFF00 - #define MC_FMR_OFF 0x00000060 - #define MC_FWS_2R3W 0x00000100 - - #define AIC_BASE 0xFFFFF000 - #define AIC_EOICR_OFF 0x00000130 - #define AIC_IDCR_OFF 0x00000124 - - #define WDT_BASE 0xFFFFFD40 - #define WDT_MR_OFF 0x00000004 - #define WDT_WDDIS (1 << 15) - - #define PMC_BASE 0xFFFFFC00 - #define PMC_SR_OFF 0x00000068 - #define PMC_MCKR_OFF 0x00000030 - #define PMC_MOSCS (1 << 0) - #define PMC_LOCK (1 << 2) - #define PMC_MCKRDY (1 << 3) - #define PMC_CSS_PLL_CLK 0x00000003 - #define PMC_PRES_CLK_2 0x00000004 - - #define CKGR_MOR_OFF 0x00000020 - #define CKGR_PLLR_OFF 0x0000002C - #define CKGR_MOSCEN (1 << 0) - #define CKGR_MUL_SHIFT 16 - #define CKGR_PLLCOUNT_SHIFT 8 - - #define RSTC_MR 0xFFFFFD08 - #define RSTC_KEY 0xA5000000 - #define RSTC_URSTEN (1 << 0) - - #define ARM_MODE_FIQ 0x11 - #define ARM_MODE_IRQ 0x12 - #define ARM_MODE_SVC 0x13 - #define ARM_MODE_ABORT 0x17 - #define ARM_MODE_UNDEF 0x1B - -#else - #error No register I/O definition for selected ARM CPU -#endif -/*\}*/ - -/* - * Section 0: Vector table and reset entry. - */ - .section .vectors,"ax",%progbits - - .global __vectors -__vectors: - ldr pc, [pc, #24] /* Reset */ - ldr pc, [pc, #24] /* Undefined instruction */ - ldr pc, [pc, #24] /* Software interrupt */ - ldr pc, [pc, #24] /* Prefetch abort */ - ldr pc, [pc, #24] /* Data abort */ - ldr pc, [pc, #24] /* Reserved */ - - /* - * On IRQ the PC will be loaded from AIC_IVR, which - * provides the address previously set in AIC_SVR. - * The interrupt routine will be called in ARM_MODE_IRQ - * with IRQ disabled and FIQ unchanged. - */ - ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */ - ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */ - - .word _init - .word __undef - .word __swi - .word __prefetch_abort - .word __data_abort - - .weak __undef - .set __undef, __xcpt_dummy_undef - .weak __swi - .set __swi, __xcpt_dummy_swi - .weak __prefetch_abort - .set __prefetch_abort, __xcpt_dummy_pref - .weak __data_abort - .set __data_abort, __xcpt_dummy_dab - -/** .global __xcpt_dummy*/ -__xcpt_dummy_undef: - b __xcpt_dummy_undef - -__xcpt_dummy_swi: - b __xcpt_dummy_swi - -__xcpt_dummy_pref: - b __xcpt_dummy_pref - -__xcpt_dummy_dab: - b __xcpt_dummy_dab - - - .ltorg -/* - * Hardware initialization. - */ - .section .init, "ax", %progbits - .globl _init -_init: - /* - * Use 2 cycles for flash access. - */ - ldr r1, =MC_BASE - mov r0, #MC_FWS_2R3W - str r0, [r1, #MC_FMR_OFF] - - /* - * Disable all interrupts. Useful for debugging w/o target reset. - */ - ldr r1, =AIC_BASE - mvn r0, #0 - str r0, [r1, #AIC_EOICR_OFF] - str r0, [r1, #AIC_IDCR_OFF] - - /* - * The watchdog is enabled after processor reset. Disable it. - */ - ldr r1, =WDT_BASE - ldr r0, =WDT_WDDIS - str r0, [r1, #WDT_MR_OFF] - - /* - * Enable the main oscillator. Set startup time of 6 * 8 slow - * clock cycles and wait until oscillator is stabilized. - */ - ldr r1, =PMC_BASE - mov r0, #(6 << 8) - orr r0, r0, #CKGR_MOSCEN - str r0, [r1, #CKGR_MOR_OFF] -wait_moscs: - ldr r0, [r1, #PMC_SR_OFF] - tst r0, #PMC_MOSCS - beq wait_moscs - - /* - * Set PLL: - * PLLfreq = crystal / divider * (multiplier + 1) - * Wait 28 clock cycles until PLL is locked. - */ - ldr r0, =((PLL_MUL_VAL << CKGR_MUL_SHIFT) | (28 << CKGR_PLLCOUNT_SHIFT) | PLL_DIV_VAL) - - str r0, [r1, #CKGR_PLLR_OFF] -wait_lock: - ldr r0, [r1, #PMC_SR_OFF] - tst r0, #PMC_LOCK - beq wait_lock - - /* - * Set master clock prescaler. - */ - mov r0, #AT91MCK_PRES - str r0, [r1, #PMC_MCKR_OFF] -wait_presrdy: - ldr r0, [r1, #PMC_SR_OFF] - tst r0, #PMC_MCKRDY - beq wait_presrdy - - /* - * Switch to PLL clock. Trying to set this together with the - * prescaler fails (see datasheets). - */ - ldr r0, [r1, #PMC_MCKR_OFF] - orr r0, r0, #PMC_CSS_PLL_CLK - str r0, [r1, #PMC_MCKR_OFF] -wait_pllsel: - ldr r0, [r1, #PMC_SR_OFF] - tst r0, #PMC_MCKRDY - beq wait_pllsel - - /* - * Enable external reset key. - */ - ldr r0, =(RSTC_KEY | RSTC_URSTEN) - ldr r1, =RSTC_MR - str r0, [r1, #0] - - /* - * Set exception stack pointers - */ - ldr r0, =__stack_fiq_end - msr CPSR_c, #ARM_MODE_FIQ | 0xC0 - mov r13, r0 - ldr r0, =__stack_irq_end - msr CPSR_c, #ARM_MODE_IRQ | 0xC0 - mov r13, r0 - ldr r0, =__stack_abt_end - msr CPSR_c, #ARM_MODE_ABORT | 0xC0 - mov r13, r0 - ldr r0, =__stack_und_end - msr CPSR_c, #ARM_MODE_UNDEF | 0xC0 - mov r13, r0 - ldr r0, =__stack_svc_end - msr CPSR_c, #ARM_MODE_SVC | 0xC0 - mov r13, r0 - - /* - * Clear .bss - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 - -_40: - cmp r1, r2 - strne r3, [r1], #+4 - bne _40 - - /* - * Relocate .data section (Copy from ROM to RAM). - */ - ldr r1, =__etext - ldr r2, =__data_start - ldr r3, =__data_end - -_41: - cmp r2, r3 - ldrlo r0, [r1], #4 - strlo r0, [r2], #4 - blo _41 - - /* - * Initialize user stack pointer. - */ - ldr r13, =__stack_end - - /* - * Jump to main - */ - ldr r0, =main - bx r0 - -End: - b End - - .ltorg diff --git a/cpu/arm/hw/switch.h b/cpu/arm/hw/switch.h deleted file mode 100644 index 9ed15b94..00000000 --- a/cpu/arm/hw/switch.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * \file - * - * - * \brief Kernel scheduler macros. - * - * \version $Id$ - * - * \author Francesco Sacchi - * \author Stefano Fedrigo - */ - -#ifndef CPU_ARM_HW_SWITCH_H -#define CPU_ARM_HW_SWITCH_H - -#include - -/** - * Interrupt entry point. - * Needed because AT91 uses an Interrupt Controller with auto-vectoring. - */ -#define SCHEDULER_IRQ_ENTRY \ - asm volatile("sub lr, lr, #4 \n\t" /* Adjust LR */ \ - "stmfd sp!, {r0} \n\t" /* Save r0 */ \ - "stmfd sp, {sp}^ \n\t" /* Save user SP */ \ - "sub sp, sp, #4 \n\t" /* Decrement irq SP, writeback is illegal */ \ - "ldmfd sp!, {r0} \n\t" /* Restore user SP immedately in r0 */ \ - "stmfd r0!, {lr} \n\t" /* Store system LR in user stack */ \ - "stmfd r0, {r1-r12,lr}^ \n\t" /* Store registers on user stack (user LR too) */ \ - "sub r0, r0, #52 \n\t" /* Decrement r0, writeback is illegal */ \ - "ldmfd sp!, {r1} \n\t" /* Restore r0 */ \ - "stmfd r0!, {r1} \n\t" /* Store r0 in user stack too */ \ - "mrs r1, spsr \n\t" /* Save SPSR... */ \ - "stmfd r0!, {r1} \n\t" /* ... in user stack */ \ - "ldr r1, =CurrentProcess \n\t" /* Load in r1 &CurrentProcess->stack */ \ - "ldr r1, [r1, %0] \n\t" \ - "str r0, [r1] \n\t" /* Store the process SP */ \ - "sub fp, sp, #4 \n\t" /* Store the process SP */ \ - : /* no output */ \ - : "n" (offsetof(Process, stack)) \ - ) - - -#define SCHEDULER_IRQ_EXIT \ - asm volatile("ldr lr, =CurrentProcess \n\t" /* Load &CurrentProcess->stack */ \ - "ldr lr, [lr, %0] \n\t" \ - "ldr lr, [lr] \n\t" /* Load current process SP */ \ - "ldr r0, =0xFFFFF000 \n\t" /* End of interrupt for AT91 */ \ - "str r0, [r0, #0x130] \n\t" /* */ \ - "ldmfd lr!, {r0} \n\t" /* Pop status reg */ \ - "msr spsr, r0 \n\t" /* ... */ \ - "ldmfd lr, {r0-r12,lr}^ \n\t" /* Restore user regs */ \ - "add lr, lr, #56 \n\t" /* 52 + irq link register (extracted below) */ \ - "stmfd sp!, {lr} \n\t" /* Push user stack pointer in irq stack */ \ - "ldmfd sp, {sp}^ \n\t" /* Restore user SP */ \ - "sub sp, sp, #4 \n\t" /* Align irq SP */ \ - "ldmdb lr, {pc}^ \n\t" /* And return to user space (We use ldmdb cause lr is sp+4) */ \ - : /* no output */ \ - : "n" (offsetof(Process, stack)) \ - ) - -#endif /* CPU_ARM_HW_SWITCH_H */ diff --git a/cpu/arm/io/arm.h b/cpu/arm/io/arm.h deleted file mode 100644 index 5690c317..00000000 --- a/cpu/arm/io/arm.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * ARM I/O registers. - */ - - -#ifndef ARM_H -#define ARM_H - -#include - -#if CPU_ARM_AT91 - #include "at91.h" -/*#elif Add other ARM families here */ -#else - #error Unknown CPU -#endif - - -#endif /* ARM_H */ diff --git a/cpu/arm/io/at91.h b/cpu/arm/io/at91.h deleted file mode 100644 index 7bdde9b9..00000000 --- a/cpu/arm/io/at91.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 common definitions. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_H -#define AT91_H - -#include - -#if CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X256 - #include "at91sam7.h" - -#else - #error Missing I/O definitions for CPU. -#endif - -#endif /* AT91_H */ diff --git a/cpu/arm/io/at91_adc.h b/cpu/arm/io/at91_adc.h deleted file mode 100644 index 2abe435b..00000000 --- a/cpu/arm/io/at91_adc.h +++ /dev/null @@ -1,199 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Daniele Basile - * - * AT91SAM7 Analog to Digital Converter. - * - */ - - -#ifndef AT91_ADC_H -#define AT91_ADC_H - - -/** - * ADC control register - */ -#define ADC_CR_OFF 0x00000000 ///< Control register offeset. -#define ADC_CR (*((reg32_t *)(ADC_BASE + ADC_CR_OFF))) ///< Control register address. -#define ADC_SWRST 0 ///< Software reset. -#define ADC_START 1 ///< Start conversion. - - -/** - * ADC mode register - */ -#define ADC_MR_OFF 0x00000004 ///< Mode register offeset. -#define ADC_MR (*((reg32_t *)(ADC_BASE + ADC_MR_OFF))) ///< Mode register address. -#define ADC_TRGEN 0 ///< Trigger enable. - -#define ADC_TRGSEL_TIOA0 0x00000000 ///< TIOA output of the timer counter channel 0. -#define ADC_TRGSEL_TIOA1 0x00000002 ///< TIOA output of the timer counter channel 1. -#define ADC_TRGSEL_TIOA2 0x00000004 ///< TIOA output of the timer counter channel 2. -#define ADC_TRGSEL_EXT 0x0000000C ///< External trigger. - -#define ADC_LOWRES 4 ///< Resolution 0: 10-bit, 1: 8-bit. -#define ADC_SLEEP 5 ///< Sleep mode. - -/** - * Prescaler rate selection. - * ADCClock = MCK / ((ADC_PRESCALER_VALUE + 1) * 2) - */ -#define ADC_PRESCALER_MASK 0x00003F00 ///< Prescaler rate selection mask. -#define ADC_PRESCALER_SHIFT 8 ///< Prescale rate selection shift. - -/** - * Start up timer. - * Startup time = (ADC_STARTUP_VALUE + 1) * 8 /ADCClock - */ -#define ADC_STARTUP_MASK 0x001F0000 ///< Start up timer mask. -#define ADC_STARTUP_SHIFT 16 ///< Start up timer shift. - - -/** - * Sample & hold time. - * Sample & hold time = (ADC_SHTIM_VALUE + 1) * 8 /ADCClock - */ -#define ADC_SHTIME_MASK 0x0F000000 ///< Sample & hold time mask. -#define ADC_SHTIME_SHIFT 24 ///< Sample & hold time shift. - - -/** - * ADC channel enable register - */ -#define ADC_CHER_OFF 0x00000010 ///< Channel enable register offeset. -#define ADC_CHER (*((reg32_t *)(ADC_BASE + ADC_CHER_OFF))) ///< Channel enable register address. - -/** - * ADC channel disable register - */ -#define ADC_CHDR_OFF 0x00000014 ///< Channel disable register offeset. -#define ADC_CHDR (*((reg32_t *)(ADC_BASE + ADC_CHDR_OFF))) ///< Channel disable register address. - -/** - * ADC channel status register - */ -#define ADC_CHSR_OFF 0x00000018 ///< Channel status register offeset. -#define ADC_CHSR (*((reg32_t *)(ADC_BASE + ADC_CHSR_OFF))) ///< Channel status register address. - -#define ADC_CH_MASK 0x000000FF ///< Channel mask. -#define ADC_CH0 0 ///< Channel 0 -#define ADC_CH1 1 ///< Channel 1 -#define ADC_CH2 2 ///< Channel 2 -#define ADC_CH3 3 ///< Channel 3 -#define ADC_CH4 4 ///< Channel 4 -#define ADC_CH5 5 ///< Channel 5 -#define ADC_CH6 6 ///< Channel 6 -#define ADC_CH7 7 ///< Channel 7 - -/** - * ADC status register - */ -#define ADC_SR_OFF 0x0000001C ///< Status register offeset. -#define ADC_SR (*((reg32_t *)(ADC_BASE + ADC_SR_OFF))) ///< Status register address. - -/** - * ADC Interrupt enable register. - */ -#define ADC_IER_OFF 0x00000024 ///< Interrupt enable register offeset. -#define ADC_IER (*((reg32_t *)(ADC_BASE + ADC_IER_OFF))) ///< Interrupt enable register. - -/** - * ADC Interrupt disable register. - */ -#define ADC_IDR_OFF 0x00000028 ///< Interrupt disable register offeset. -#define ADC_IDR (*((reg32_t *)(ADC_BASE + ADC_IDR_OFF))) ///< Interrupt disable register. - -/** - * ADC Interrupt mask register. - */ -#define ADC_IMR_OFF 0x0000002C ///< Interrupt mask register offeset. -#define ADC_IMR (*((reg32_t *)(ADC_BASE + ADC_IMR_OFF))) ///< Interrupt mask register. - -#define ADC_EOC_MASK 0x000000FF ///< End of converison mask. -#define ADC_EOC0 0 ///< End of conversion channel 0. -#define ADC_EOC1 1 ///< End of conversion channel 1. -#define ADC_EOC2 2 ///< End of conversion channel 2. -#define ADC_EOC3 3 ///< End of conversion channel 3. -#define ADC_EOC4 4 ///< End of conversion channel 4. -#define ADC_EOC5 5 ///< End of conversion channel 5. -#define ADC_EOC6 6 ///< End of conversion channel 6. -#define ADC_EOC7 7 ///< End of conversion channel 7. - -#define ADC_OVRE0 8 ///< Overrun error channel 0. -#define ADC_OVRE1 9 ///< Overrun error channel 1. -#define ADC_OVRE2 10 ///< Overrun error channel 2. -#define ADC_OVRE3 11 ///< Overrun error channel 3. -#define ADC_OVRE4 12 ///< Overrun error channel 4. -#define ADC_OVRE5 13 ///< Overrun error channel 5. -#define ADC_OVRE6 14 ///< Overrun error channel 6. -#define ADC_OVRE7 15 ///< Overrun error channel 7. - -#define ADC_DRDY 16 ///< Data ready. -#define ADC_GOVRE 17 ///< General overrun error. -#define ADC_ENDRX 18 ///< End of RX buffer. -#define ADC_RXBUFF 19 ///< Rx buffer full. - -/** - * ADC last convert data register. - */ -#define ADC_LCDR_OFF 0x00000020 ///< Last converted data register offeset. -#define ADC_LCDR (*((reg32_t *)(ADC_BASE + ADC_LCDR_OFF))) ///< Last converted data register. - -/** - * ADC channel data register. - * - * \{ - */ -#define ADC_CDR0_OFF 0x00000030 ///< Channel data register 0 offeset. -#define ADC_CDR1_OFF 0x00000034 ///< Channel data register 1 offeset. -#define ADC_CDR2_OFF 0x00000038 ///< Channel data register 2 offeset. -#define ADC_CDR3_OFF 0x0000003C ///< Channel data register 3 offeset. -#define ADC_CDR4_OFF 0x00000040 ///< Channel data register 4 offeset. -#define ADC_CDR5_OFF 0x00000044 ///< Channel data register 5 offeset. -#define ADC_CDR6_OFF 0x00000048 ///< Channel data register 6 offeset. -#define ADC_CDR7_OFF 0x0000004C ///< Channel data register 7 offeset. - -#define ADC_CDR0 (*((reg32_t *)(ADC_BASE + ADC_CDR0_OFF))) ///< Channel data register 0. -#define ADC_CDR1 (*((reg32_t *)(ADC_BASE + ADC_CDR1_OFF))) ///< Channel data register 1. -#define ADC_CDR2 (*((reg32_t *)(ADC_BASE + ADC_CDR2_OFF))) ///< Channel data register 2. -#define ADC_CDR3 (*((reg32_t *)(ADC_BASE + ADC_CDR3_OFF))) ///< Channel data register 3. -#define ADC_CDR4 (*((reg32_t *)(ADC_BASE + ADC_CDR4_OFF))) ///< Channel data register 4. -#define ADC_CDR5 (*((reg32_t *)(ADC_BASE + ADC_CDR5_OFF))) ///< Channel data register 5. -#define ADC_CDR6 (*((reg32_t *)(ADC_BASE + ADC_CDR6_OFF))) ///< Channel data register 6. -#define ADC_CDR7 (*((reg32_t *)(ADC_BASE + ADC_CDR7_OFF))) ///< Channel data register 7. -/* \} */ - -#endif /* AT91_ADC_H */ diff --git a/cpu/arm/io/at91_aic.h b/cpu/arm/io/at91_aic.h deleted file mode 100644 index 8fdd2914..00000000 --- a/cpu/arm/io/at91_aic.h +++ /dev/null @@ -1,223 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 advanced interrupt controller. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_AIC_H -#define AT91_AIC_H - -#include - - - -/** - * Source mode register array. - */ -#define AIC_SMR(i) (*((reg32_t *)(AIC_BASE + (i) * 4))) - -/** - * Priority mask. - * Priority levels can be between 0 (lowest) and 7 (highest). - */ -#define AIC_PRIOR_MASK 0x00000007 - -/** - * Interrupt source type mask. - * Internal interrupts can level sensitive or edge triggered. - * - * External interrupts can triggered on positive or negative levels or - * on rising or falling edges. - */ -/*\{*/ -#define AIC_SRCTYPE_MASK 0x00000060 - -#define AIC_SRCTYPE_INT_LEVEL_SENSITIVE 0x00000000 ///< Internal level sensitive. -#define AIC_SRCTYPE_INT_EDGE_TRIGGERED 0x00000020 ///< Internal edge triggered. -#define AIC_SRCTYPE_EXT_LOW_LEVEL 0x00000000 ///< External low level. -#define AIC_SRCTYPE_EXT_NEGATIVE_EDGE 0x00000020 ///< External falling edge. -#define AIC_SRCTYPE_EXT_HIGH_LEVEL 0x00000040 ///< External high level. -#define AIC_SRCTYPE_EXT_POSITIVE_EDGE 0x00000060 ///< External rising edge. -/*\}*/ - - -/** - * Type for interrupt handlers. - */ -typedef void (*irq_handler_t)(void); - -/** Interrupt Source Vector Registers */ -/*\{*/ -/** Source vector register array. - * - * Stores the addresses of the corresponding interrupt handlers. - */ -#define AIC_SVR(i) (*((volatile irq_handler_t *)(AIC_BASE + 0x80 + (i) * 4))) -/*\}*/ - -/** Interrupt Vector Register */ -/*\{*/ -#define AIC_IVR_OFF 0x00000100 ///< IRQ vector register offset. -#define AIC_IVR (*((reg32_t *)(AIC_BASE + AIC_IVR_OFF))) ///< IRQ vector register address. -/*\}*/ - -/** Fast Interrupt Vector Register */ -/*\{*/ -#define AIC_FVR_OFF 0x00000104 ///< FIQ vector register offset. -#define AIC_FVR (*((reg32_t *)(AIC_BASE + AIC_FVR_OFF))) ///< FIQ vector register address. -/*\}*/ - -/** Interrupt Status Register */ -/*\{*/ -#define AIC_ISR_OFF 0x00000108 ///< Interrupt status register offset. -#define AIC_ISR (*((reg32_t *)(AIC_BASE + AIC_ISR_OFF))) ///< Interrupt status register address. -#define AIC_IRQID_MASK 0x0000001F ///< Current interrupt identifier mask. -/*\}*/ - -/** Interrupt Pending Register */ -/*\{*/ -#define AIC_IPR_OFF 0x0000010C ///< Interrupt pending register offset. -#define AIC_IPR (*((reg32_t *)(AIC_BASE + AIC_IPR_OFF))) ///< Interrupt pending register address. -/*\}*/ - -/** Interrupt Mask Register */ -/*\{*/ -#define AIC_IMR_OFF 0x00000110 ///< Interrupt mask register offset. -#define AIC_IMR (*((reg32_t *)(AIC_BASE + AIC_IMR_OFF))) ///< Interrupt mask register address. -/*\}*/ - -/** Interrupt Core Status Register */ -/*\{*/ -#define AIC_CISR_OFF 0x00000114 ///< Core interrupt status register offset. -#define AIC_CISR (*((reg32_t *)(AIC_BASE + AIC_CISR_OFF))) ///< Core interrupt status register address. -#define AIC_NFIQ 1 ///< Core FIQ Status -#define AIC_NIRQ 2 ///< Core IRQ Status -/*\}*/ - -/** Interrupt Enable Command Register */ -/*\{*/ -#define AIC_IECR_OFF 0x00000120 ///< Interrupt enable command register offset. -#define AIC_IECR (*((reg32_t *)(AIC_BASE + AIC_IECR_OFF))) ///< Interrupt enable command register address. -/*\}*/ - -/** Interrupt Disable Command Register */ -/*\{*/ -#define AIC_IDCR_OFF 0x00000124 ///< Interrupt disable command register offset. -#define AIC_IDCR (*((reg32_t *)(AIC_BASE + AIC_IDCR_OFF))) ///< Interrupt disable command register address. -/*\}*/ - -/** Interrupt Clear Command Register */ -/*\{*/ -#define AIC_ICCR_OFF 0x00000128 ///< Interrupt clear command register offset. -#define AIC_ICCR (*((reg32_t *)(AIC_BASE + AIC_ICCR_OFF))) ///< Interrupt clear command register address. -/*\}*/ - -/** Interrupt Set Command Register */ -/*\{*/ -#define AIC_ISCR_OFF 0x0000012C ///< Interrupt set command register offset. -#define AIC_ISCR (*((reg32_t *)(AIC_BASE + AIC_ISCR_OFF))) ///< Interrupt set command register address. -/*\}*/ - -/** End Of Interrupt Command Register */ -/*\{*/ -#define AIC_EOICR_OFF 0x00000130 ///< End of interrupt command register offset. -#define AIC_EOICR (*((reg32_t *)(AIC_BASE + AIC_EOICR_OFF))) ///< End of interrupt command register address. -/*\}*/ - -/** Spurious Interrupt Vector Register */ -/*\{*/ -#define AIC_SPU_OFF 0x00000134 ///< Spurious vector register offset. -#define AIC_SPU (*((reg32_t *)(AIC_BASE + AIC_SPU_OFF)== ///< Spurious vector register address. -/*\}*/ - -/** Debug Control Register */ -/*\{*/ -#define AIC_DCR_OFF 0x0000138 ///< Debug control register offset. -#define AIC_DCR (*((reg32_t *)(AIC_BASE + AIC_DCR_OFF))) ///< Debug control register address. -/*\}*/ - -/** Fast Forcing Enable Register */ -/*\{*/ -#define AIC_FFER_OFF 0x00000140 ///< Fast forcing enable register offset. -#define AIC_FFER (*((reg32_t *)(AIC_BASE + AIC_FFER_OFF))) ///< Fast forcing enable register address. -/*\}*/ - -/** Fast Forcing Disable Register */ -/*\{*/ -#define AIC_FFDR_OFF 0x00000144 ///< Fast forcing disable register address. -#define AIC_FFDR (*((reg32_t *)(AIC_BASE + AIC_FFDR_OFF))) ///< Fast forcing disable register address. -/*\}*/ - -/** Fast Forcing Status Register */ -/*\{*/ -#define AIC_FFSR_OFF 0x00000148 ///< Fast forcing status register address. -#define AIC_FFSR (*((reg32_t *)(AIC_BASE + AIC_FFSR_OFF))) ///< Fast forcing status register address. -/*\}*/ - -#endif /* AT91_AIC_H */ diff --git a/cpu/arm/io/at91_dbgu.h b/cpu/arm/io/at91_dbgu.h deleted file mode 100644 index 5fa700de..00000000 --- a/cpu/arm/io/at91_dbgu.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 Debug unit. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ -#ifndef AT91_DBGU_H -#define AT91_DBGU_H - -#define DBGU_CR (*((reg32_t *)(DBGU_BASE + US_CR_OFF))) /// - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 Memory controller. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_MC_H -#define AT91_MC_H - -#define MC_RCR_OFF 0x00000000 ///< MC remap control register offset. -#define MC_RCR (*((reg32_t *)(MC_BASE + MC_RCR_OFF))) ///< MC remap control register address. -#define MC_RCB 0 ///< Remap command. - -#define MC_ASR_OFF 0x00000004 ///< MC abort status register offset. -#define MC_ASR (*((reg32_t *)(MC_BASE + MC_ASR_OFF))) ///< MC abort status register address. -#define MC_UNDADD 0 ///< Undefined Addess Abort status. -#define MC_MISADD 1 ///< Misaligned Addess Abort status. -#define MC_ABTSZ_MASK 0x00000300 ///< Abort size status mask. -#define MC_ABTSZ_BYTE 0x00000000 ///< Byte size abort. -#define MC_ABTSZ_HWORD 0x00000100 ///< Half-word size abort. -#define MC_ABTSZ_WORD 0x00000200 ///< Word size abort. -#define MC_ABTTYP_MASK 0x00000C00 ///< Abort type status mask. -#define MC_ABTTYP_DATAR 0x00000000 ///< Data read abort. -#define MC_ABTTYP_DATAW 0x00000400 ///< Data write abort. -#define MC_ABTTYP_FETCH 0x00000800 ///< Code fetch abort. -#define MC_MST_PDC 0x00020000 ///< PDC abort source. -#define MC_MST_ARM 0x00040000 ///< ARM abort source. -#define MC_SVMST_PDC 0x02000000 ///< Saved PDC abort source. -#define MC_SVMST_ARM 0x04000000 ///< Saved ARM abort source. - -#define MC_AASR_OFF 0x00000008 ///< MC abort address status register offset. -#define MC_AASR (*((reg32_t *)(MC_BASE + MC_AASR_OFF))) ///< MC abort address status register address. - -#define MC_FMR_OFF 0x00000060 ///< MC flash mode register offset. -#define MC_FMR (*((reg32_t *)(MC_BASE + MC_FMR_OFF))) ///< MC flash mode register address. -#define MC_FRDY 0 ///< Flash ready. -#define MC_LOCKE 2 ///< Lock error. -#define MC_PROGE 3 ///< Programming error. -#define MC_NEBP 7 ///< No erase before programming. -#define MC_FWS_MASK 0x00000300 ///< Flash wait state mask. -#define MC_FWS_1R2W 0x00000000 ///< 1 cycle for read, 2 for write operations. -#define MC_FWS_2R3W 0x00000100 ///< 2 cycles for read, 3 for write operations. -#define MC_FWS_3R4W 0x00000200 ///< 3 cycles for read, 4 for write operations. -#define MC_FWS_4R4W 0x00000300 ///< 4 cycles for read and write operations. -#define MC_FMCN_MASK 0x00FF0000 ///< Flash microsecond cycle number mask. - -#define MC_FCR_OFF 0x00000064 ///< MC flash command register offset. -#define MC_FCR (*((reg32_t *)(MC_BASE + MC_FCR_OFF))) ///< MC flash command register address. -#define MC_FCMD_MASK 0x0000000F ///< Flash command mask. -#define MC_FCMD_NOP 0x00000000 ///< No command. -#define MC_FCMD_WP 0x00000001 ///< Write page. -#define MC_FCMD_SLB 0x00000002 ///< Set lock bit. -#define MC_FCMD_WPL 0x00000003 ///< Write page and lock. -#define MC_FCMD_CLB 0x00000004 ///< Clear lock bit. -#define MC_FCMD_EA 0x00000008 ///< Erase all. -#define MC_FCMD_SGPB 0x0000000B ///< Set general purpose NVM bit. -#define MC_FCMD_CGPB 0x0000000D ///< Clear general purpose NVM bit. -#define MC_FCMD_SSB 0x0000000F ///< Set security bit. -#define MC_PAGEN_MASK 0x0003FF00 ///< Page number mask. -#define MC_KEY 0x5A000000 ///< Writing protect key. - -#define MC_FSR_OFF 0x00000068 ///< MC flash status register offset. -#define MC_FSR (*((reg32_t *)(MC_BASE + MC_FSR_OFF))) ///< MC flash status register address. -#define MC_SECURITY 4 ///< Security bit status. - -#define MC_GPNVM0 8 ///< General purpose NVM bit 0. -#define MC_GPNVM1 9 ///< General purpose NVM bit 1. -#define MC_GPNVM2 10 ///< General purpose NVM bit 2. - -#define MC_LOCKS0 16 ///< Lock region 0 lock status. -#define MC_LOCKS1 17 ///< Lock region 1 lock status. -#define MC_LOCKS2 18 ///< Lock region 2 lock status. -#define MC_LOCKS3 19 ///< Lock region 3 lock status. -#define MC_LOCKS4 20 ///< Lock region 4 lock status. -#define MC_LOCKS5 21 ///< Lock region 5 lock status. -#define MC_LOCKS6 22 ///< Lock region 6 lock status. -#define MC_LOCKS7 23 ///< Lock region 7 lock status. -#define MC_LOCKS8 24 ///< Lock region 8 lock status. -#define MC_LOCKS9 25 ///< Lock region 9 lock status. -#define MC_LOCKS10 26 ///< Lock region 10 lock status. -#define MC_LOCKS11 27 ///< Lock region 11 lock status. -#define MC_LOCKS12 28 ///< Lock region 12 lock status. -#define MC_LOCKS13 29 ///< Lock region 13 lock status. -#define MC_LOCKS14 30 ///< Lock region 14 lock status. -#define MC_LOCKS15 31 ///< Lock region 15 lock status. - -#endif /* AT91_MC_H */ diff --git a/cpu/arm/io/at91_pio.h b/cpu/arm/io/at91_pio.h deleted file mode 100644 index 3aa47565..00000000 --- a/cpu/arm/io/at91_pio.h +++ /dev/null @@ -1,297 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 Parallel input/output controller. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_PIO_H -#define AT91_PIO_H - -/** PIO Register Offsets */ -/*\{*/ -#define PIO_PER_OFF 0x00000000 ///< PIO enable register offset. -#define PIO_PDR_OFF 0x00000004 ///< PIO disable register offset. -#define PIO_PSR_OFF 0x00000008 ///< PIO status register offset. -#define PIO_OER_OFF 0x00000010 ///< Output enable register offset. -#define PIO_ODR_OFF 0x00000014 ///< Output disable register offset. -#define PIO_OSR_OFF 0x00000018 ///< Output status register offset. -#define PIO_IFER_OFF 0x00000020 ///< Input filter enable register offset. -#define PIO_IFDR_OFF 0x00000024 ///< Input filter disable register offset. -#define PIO_IFSR_OFF 0x00000028 ///< Input filter status register offset. -#define PIO_SODR_OFF 0x00000030 ///< Set output data register offset. -#define PIO_CODR_OFF 0x00000034 ///< Clear output data register offset. -#define PIO_ODSR_OFF 0x00000038 ///< Output data status register offset. -#define PIO_PDSR_OFF 0x0000003C ///< Pin data status register offset. -#define PIO_IER_OFF 0x00000040 ///< Interrupt enable register offset. -#define PIO_IDR_OFF 0x00000044 ///< Interrupt disable register offset. -#define PIO_IMR_OFF 0x00000048 ///< Interrupt mask register offset. -#define PIO_ISR_OFF 0x0000004C ///< Interrupt status register offset. -#if PIO_HAS_MULTIDRIVER -#define PIO_MDER_OFF 0x00000050 ///< Multi-driver enable register offset. -#define PIO_MDDR_OFF 0x00000054 ///< Multi-driver disable register offset. -#define PIO_MDSR_OFF 0x00000058 ///< Multi-driver status register offset. -#endif /* PIO_HAS_MULTIDRIVER */ -#if PIO_HAS_PULLUP -#define PIO_PUDR_OFF 0x00000060 ///< Pull-up disable register offset. -#define PIO_PUER_OFF 0x00000064 ///< Pull-up enable register offset. -#define PIO_PUSR_OFF 0x00000068 ///< Pull-up status register offset. -#endif /* PIO_HAS_PULLUP */ -#if PIO_HAS_PERIPHERALSELECT -#define PIO_ASR_OFF 0x00000070 ///< PIO peripheral A select register offset. -#define PIO_BSR_OFF 0x00000074 ///< PIO peripheral B select register offset. -#define PIO_ABSR_OFF 0x00000078 ///< PIO peripheral AB status register offset. -#endif /* PIO_HAS_PERIPHERALSELECT */ -#if PIO_HAS_OUTPUTWRITEENABLE -#define PIO_OWER_OFF 0x000000A0 ///< PIO output write enable register offset. -#define PIO_OWDR_OFF 0x000000A4 ///< PIO output write disable register offset. -#define PIO_OWSR_OFF 0x000000A8 ///< PIO output write status register offset. -#endif /* PIO_HAS_OUTPUTWRITEENABLE */ -/*\}*/ - -/** Single PIO Register Addresses */ -/*\{*/ -#if defined(PIO_BASE) - #define PIO_ACCESS(offset) (*((reg32_t *)(PIO_BASE + (offset)))) - - #define PIO_PER PIO_ACCESS(PIO_PER_OFF) ///< PIO enable register address. - #define PIO_PDR PIO_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. - #define PIO_PSR PIO_ACCESS(PIO_PSR_OFF) ///< PIO status register address. - #define PIO_OER PIO_ACCESS(PIO_OER_OFF) ///< Output enable register address. - #define PIO_ODR PIO_ACCESS(PIO_ODR_OFF) ///< Output disable register address. - #define PIO_OSR PIO_ACCESS(PIO_OSR_OFF) ///< Output status register address. - #define PIO_IFER PIO_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. - #define PIO_IFDR PIO_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. - #define PIO_IFSR PIO_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. - #define PIO_SODR PIO_ACCESS(PIO_SODR_OFF) ///< Set output data register address. - #define PIO_CODR PIO_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. - #define PIO_ODSR PIO_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. - #define PIO_PDSR PIO_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. - #define PIO_IER PIO_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. - #define PIO_IDR PIO_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. - #define PIO_IMR PIO_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. - #define PIO_ISR PIO_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. - #if PIO_HAS_MULTIDRIVER - #define PIO_MDER PIO_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. - #define PIO_MDDR PIO_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. - #define PIO_MDSR PIO_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. - #endif /* PIO_HAS_MULTIDRIVER */ - #if PIO_HAS_PULLUP - #define PIO_PUDR PIO_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. - #define PIO_PUER PIO_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. - #define PIO_PUSR PIO_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. - #endif /* PIO_HAS_PULLUP */ - #if PIO_HAS_PERIPHERALSELECT - #define PIO_ASR PIO_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. - #define PIO_BSR PIO_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. - #define PIO_ABSR PIO_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. - #endif /* PIO_HAS_PERIPHERALSELECT */ - #if PIO_HAS_OUTPUTWRITEENABLE - #define PIO_OWER PIO_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. - #define PIO_OWDR PIO_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. - #define PIO_OWSR PIO_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. - #endif /* PIO_HAS_OUTPUTWRITEENABLE */ -#endif /* PIO_BASE */ -/*\}*/ - -/** PIO A Register Addresses */ -/*\{*/ -#if defined(PIOA_BASE) - #define PIOA_ACCESS(offset) (*((reg32_t *)(PIOA_BASE + (offset)))) - - #define PIOA_PER PIOA_ACCESS(PIO_PER_OFF) ///< PIO enable register address. - #define PIOA_PDR PIOA_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. - #define PIOA_PSR PIOA_ACCESS(PIO_PSR_OFF) ///< PIO status register address. - #define PIOA_OER PIOA_ACCESS(PIO_OER_OFF) ///< Output enable register address. - #define PIOA_ODR PIOA_ACCESS(PIO_ODR_OFF) ///< Output disable register address. - #define PIOA_OSR PIOA_ACCESS(PIO_OSR_OFF) ///< Output status register address. - #define PIOA_IFER PIOA_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. - #define PIOA_IFDR PIOA_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. - #define PIOA_IFSR PIOA_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. - #define PIOA_SODR PIOA_ACCESS(PIO_SODR_OFF) ///< Set output data register address. - #define PIOA_CODR PIOA_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. - #define PIOA_ODSR PIOA_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. - #define PIOA_PDSR PIOA_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. - #define PIOA_IER PIOA_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. - #define PIOA_IDR PIOA_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. - #define PIOA_IMR PIOA_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. - #define PIOA_ISR PIOA_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. - #if PIO_HAS_MULTIDRIVER - #define PIOA_MDER PIOA_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. - #define PIOA_MDDR PIOA_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. - #define PIOA_MDSR PIOA_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. - #endif /* PIO_HAS_MULTIDRIVER */ - #if PIO_HAS_PULLUP - #define PIOA_PUDR PIOA_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. - #define PIOA_PUER PIOA_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. - #define PIOA_PUSR PIOA_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. - #endif /* PIO_HAS_PULLUP */ - #if PIO_HAS_PERIPHERALSELECT - #define PIOA_ASR PIOA_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. - #define PIOA_BSR PIOA_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. - #define PIOA_ABSR PIOA_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. - #endif /* PIO_HAS_PERIPHERALSELECT */ - #if PIO_HAS_OUTPUTWRITEENABLE - #define PIOA_OWER PIOA_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. - #define PIOA_OWDR PIOA_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. - #define PIOA_OWSR PIOA_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. - #endif /* PIO_HAS_OUTPUTWRITEENABLE */ -#endif /* PIOA_BASE */ -/*\}*/ - -/** PIO B Register Addresses */ -/*\{*/ -#if defined(PIOB_BASE) - #define PIOB_ACCESS(offset) (*((reg32_t *)(PIOB_BASE + (offset)))) - - #define PIOB_PER PIOB_ACCESS(PIO_PER_OFF) ///< PIO enable register address. - #define PIOB_PDR PIOB_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. - #define PIOB_PSR PIOB_ACCESS(PIO_PSR_OFF) ///< PIO status register address. - #define PIOB_OER PIOB_ACCESS(PIO_OER_OFF) ///< Output enable register address. - #define PIOB_ODR PIOB_ACCESS(PIO_ODR_OFF) ///< Output disable register address. - #define PIOB_OSR PIOB_ACCESS(PIO_OSR_OFF) ///< Output status register address. - #define PIOB_IFER PIOB_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. - #define PIOB_IFDR PIOB_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. - #define PIOB_IFSR PIOB_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. - #define PIOB_SODR PIOB_ACCESS(PIO_SODR_OFF) ///< Set output data register address. - #define PIOB_CODR PIOB_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. - #define PIOB_ODSR PIOB_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. - #define PIOB_PDSR PIOB_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. - #define PIOB_IER PIOB_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. - #define PIOB_IDR PIOB_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. - #define PIOB_IMR PIOB_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. - #define PIOB_ISR PIOB_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. - #if PIO_HAS_MULTIDRIVER - #define PIOB_MDER PIOB_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. - #define PIOB_MDDR PIOB_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. - #define PIOB_MDSR PIOB_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. - #endif /* PIO_HAS_MULTIDRIVER */ - #if PIO_HAS_PULLUP - #define PIOB_PUDR PIOB_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. - #define PIOB_PUER PIOB_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. - #define PIOB_PUSR PIOB_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. - #endif /* PIO_HAS_PULLUP */ - #if PIO_HAS_PERIPHERALSELECT - #define PIOB_ASR PIOB_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. - #define PIOB_BSR PIOB_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. - #define PIOB_ABSR PIOB_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. - #endif /* PIO_HAS_PERIPHERALSELECT */ - #if PIO_HAS_OUTPUTWRITEENABLE - #define PIOB_OWER PIOB_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. - #define PIOB_OWDR PIOB_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. - #define PIOB_OWSR PIOB_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. - #endif /* PIO_HAS_OUTPUTWRITEENABLE */ -#endif /* PIOB_BASE */ -/*\}*/ - -/** PIO C Register Addresses */ -/*\{*/ -#if defined(PIOC_BASE) - #define PIOC_ACCESS(offset) (*((reg32_t *)(PIOC_BASE + (offset)))) - - #define PIOC_PER PIOC_ACCESS(PIO_PER_OFF) ///< PIO enable register address. - #define PIOC_PDR PIOC_ACCESS(PIO_PDR_OFF) ///< PIO disable register address. - #define PIOC_PSR PIOC_ACCESS(PIO_PSR_OFF) ///< PIO status register address. - #define PIOC_OER PIOC_ACCESS(PIO_OER_OFF) ///< Output enable register address. - #define PIOC_ODR PIOC_ACCESS(PIO_ODR_OFF) ///< Output disable register address. - #define PIOC_OSR PIOC_ACCESS(PIO_OSR_OFF) ///< Output status register address. - #define PIOC_IFER PIOC_ACCESS(PIO_IFER_OFF) ///< Input filter enable register address. - #define PIOC_IFDR PIOC_ACCESS(PIO_IFDR_OFF) ///< Input filter disable register address. - #define PIOC_IFSR PIOC_ACCESS(PIO_IFSR_OFF) ///< Input filter status register address. - #define PIOC_SODR PIOC_ACCESS(PIO_SODR_OFF) ///< Set output data register address. - #define PIOC_CODR PIOC_ACCESS(PIO_CODR_OFF) ///< Clear output data register address. - #define PIOC_ODSR PIOC_ACCESS(PIO_ODSR_OFF) ///< Output data status register address. - #define PIOC_PDSR PIOC_ACCESS(PIO_PDSR_OFF) ///< Pin data status register address. - #define PIOC_IER PIOC_ACCESS(PIO_IER_OFF) ///< Interrupt enable register address. - #define PIOC_IDR PIOC_ACCESS(PIO_IDR_OFF) ///< Interrupt disable register address. - #define PIOC_IMR PIOC_ACCESS(PIO_IMR_OFF) ///< Interrupt mask register address. - #define PIOC_ISR PIOC_ACCESS(PIO_ISR_OFF) ///< Interrupt status register address. - #if PIO_HAS_MULTIDRIVER - #define PIOC_MDER PIOC_ACCESS(PIO_MDER_OFF) ///< Multi-driver enable register address. - #define PIOC_MDDR PIOC_ACCESS(PIO_MDDR_OFF) ///< Multi-driver disable register address. - #define PIOC_MDSR PIOC_ACCESS(PIO_MDSR_OFF) ///< Multi-driver status register address. - #endif /* PIO_HAS_MULTIDRIVER */ - #if PIO_HAS_PULLUP - #define PIOC_PUDR PIOC_ACCESS(PIO_PUDR_OFF) ///< Pull-up disable register address. - #define PIOC_PUER PIOC_ACCESS(PIO_PUER_OFF) ///< Pull-up enable register address. - #define PIOC_PUSR PIOC_ACCESS(PIO_PUSR_OFF) ///< Pull-up status register address. - #endif /* PIO_HAS_PULLUP */ - #if PIO_HAS_PERIPHERALSELECT - #define PIOC_ASR PIOC_ACCESS(PIO_ASR_OFF) ///< PIO peripheral A select register address. - #define PIOC_BSR PIOC_ACCESS(PIO_BSR_OFF) ///< PIO peripheral B select register address. - #define PIOC_ABSR PIOC_ACCESS(PIO_ABSR_OFF) ///< PIO peripheral AB status register address. - #endif /* PIO_HAS_PERIPHERALSELECT */ - #if PIO_HAS_OUTPUTWRITEENABLE - #define PIOC_OWER PIOC_ACCESS(PIO_OWER_OFF) ///< PIO output write enable register address. - #define PIOC_OWDR PIOC_ACCESS(PIO_OWDR_OFF) ///< PIO output write disable register address. - #define PIOC_OWSR PIOC_ACCESS(PIO_OWSR_OFF) ///< PIO output write status register address. - #endif /* PIO_HAS_OUTPUTWRITEENABLE */ -#endif /* PIOC_BASE */ -/*\}*/ - -#endif /* AT91_PIO_H */ diff --git a/cpu/arm/io/at91_pit.h b/cpu/arm/io/at91_pit.h deleted file mode 100644 index 9bfc3f98..00000000 --- a/cpu/arm/io/at91_pit.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 periodic interval timer. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2007 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_PIT_H -#define AT91_PIT_H - -#include -/** - *Periodic Inverval Timer Mode Register - *\{ - */ -#define PIT_MR_OFF 0x00000000 ///< Mode register offset. -#define PIT_MR (*((reg32_t *)(PIT_BASE + PIT_MR_OFF))) ///< Mode register address. - -#define PIV_MASK 0x000FFFFF ///< Periodic interval value mask. -#define PIV_SHIFT 0 ///< Periodic interval value shift. -#define PITEN 24 ///< Periodic interval timer enable. -#define PITIEN 25 ///< Periodic interval timer interrupt enable. -/*\}*/ - -/** - * Periodic Inverval Timer Status Register - *\{ - */ -#define PIT_SR_OFF 0x00000004 ///< Status register offset. -#define PIT_SR (*((reg32_t *)(PIT_BASE + PIT_SR_OFF))) ///< Status register address. - -#define PITS 0 ///< Timer has reached PIV. -/*\}*/ - -/** - * Periodic Inverval Timer Value and Image Registers - *\{ - */ -#define PIVR_OFF 0x00000008 ///< Value register offset. -#define PIVR (*((reg32_t *)(PIT_BASE + PIVR_OFF))) ///< Value register address. - -#define PIIR_OFF 0x0000000C ///< Image register offset. -#define PIIR (*((reg32_t *)(PIT_BASE + PIIR_OFF))) ///< Image register address. -#define CPIV_MASK 0x000FFFFF ///< Current periodic interval value mask. -#define CPIV_SHIFT 0 ///< Current periodic interval value SHIFT. -#define PICNT_MASK 0xFFF00000 ///< Periodic interval counter mask. -#define PICNT_SHIFT 20 ///< Periodic interval counter LSB. -/*\}*/ - -#endif /* AT91_PIT_H */ diff --git a/cpu/arm/io/at91_pmc.h b/cpu/arm/io/at91_pmc.h deleted file mode 100644 index b7d5b4f5..00000000 --- a/cpu/arm/io/at91_pmc.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 power management controller. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_PMC_H -#define AT91_PMC_H - -/** System Clock Enable, Disable and Status Register */ -/*\{*/ -#define PMC_SCER_OFF 0x00000000 ///< System clock enable register offset. -#define PMC_SCER (*((reg32_t *)(PMC_BASE + PMC_SCER_OFF))) ///< System clock enable register address. -#define PMC_SCDR_OFF 0x00000004 ///< System clock disable register offset. -#define PMC_SCDR (*((reg32_t *)(PMC_BASE + PMC_SCDR_OFF))) ///< System clock disable register address. -#define PMC_SCSR_OFF 0x00000008 ///< System clock status register offset. -#define PMC_SCSR (*((reg32_t *)(PMC_BASE + PMC_SCSR_OFF))) ///< System clock status register address. - -#define PMC_PCK 0 ///< Processor clock. -#define PMC_UDP 7 ///< USB device port clock. -#define PMC_PCK0 8 ///< Programmable clock 0 output. -#define PMC_PCK1 9 ///< Programmable clock 1 output. -#define PMC_PCK2 10 ///< Programmable clock 2 output. -/*\}*/ - -/** Peripheral Clock Enable, Disable and Status Register */ -/*\{*/ -#define PMC_PCER_OFF 0x00000010 ///< Peripheral clock enable register offset. -#define PMC_PCER (*((reg32_t *)(PMC_BASE + PMC_PCER_OFF))) ///< Peripheral clock enable register address. -#define PMC_PCDR_OFF 0x00000014 ///< Peripheral clock disable register offset. -#define PMC_PCDR (*((reg32_t *)(PMC_BASE + PMC_PCDR_OFF))) ///< Peripheral clock disable register address. -#define PMC_PCSR_OFF 0x00000018 ///< Peripheral clock status register offset. -#define PMC_PCSR (*((reg32_t *)(PMC_BASE + PMC_PCSR_OFF))) ///< Peripheral clock status register address. -/*\}*/ - -/** Clock Generator Main Oscillator Register */ -/*\{*/ -#define CKGR_MOR_OFF 0x00000020 ///< Main oscillator register offset. -#define CKGR_MOR (*((reg32_t *)(PMC_BASE + CKGR_MOR_OFF))) ///< Main oscillator register address. - -#define CKGR_MOSCEN 0 ///< Main oscillator enable. -#define CKGR_OSCBYPASS 1 ///< Main oscillator bypass. -#define CKGR_OSCOUNT_MASK 0x0000FF00 ///< Main oscillator start-up time mask. -#define CKGR_OSCOUNT_SHIFT 8 ///< Main oscillator start-up time LSB. -/*\}*/ - -/** Clock Generator Main Clock Frequency Register */ -/*\{*/ -#define CKGR_MCFR_OFF 0x00000024 ///< Main clock frequency register offset. -#define CKGR_MCFR (*((reg32_t *)(PMC_BASE + CKGR_MCFR_OFF))) ///< Main clock frequency register address. - -#define CKGR_MAINF_MASK 0x0000FFFF ///< Main clock frequency mask mask. -#define CKGR_MAINRDY 16 ///< Main clock ready. -/*\}*/ - -/** PLL Registers */ -/*\{*/ -#define CKGR_PLLR_OFF 0x0000002C ///< Clock generator PLL register offset. -#define CKGR_PLLR (*((reg32_t *)(PMC_BASE + CKGR_PLLR_OFF))) ///< Clock generator PLL register address. - -#define CKGR_DIV_MASK 0x000000FF ///< Divider. -#define CKGR_DIV_SHIFT 0 ///< Least significant bit of the divider. -#define CKGR_DIV_0 0x00000000 ///< Divider output is 0. -#define CKGR_DIV_BYPASS 0x00000001 ///< Divider is bypassed. -#define CKGR_PLLCOUNT_MASK 0x00003F00 ///< PLL counter mask. -#define CKGR_PLLCOUNT_SHIFT 8 ///< PLL counter LSB. - -#define CKGR_OUT_MASK 0x0000C000 ///< PLL output frequency range. -#define CKGR_OUT_0 0x00000000 ///< Please refer to the PLL datasheet. -#define CKGR_OUT_1 0x00004000 ///< Please refer to the PLL datasheet. -#define CKGR_OUT_2 0x00008000 ///< Please refer to the PLL datasheet. -#define CKGR_OUT_3 0x0000C000 ///< Please refer to the PLL datasheet. -#define CKGR_MUL_MASK 0x07FF0000 ///< PLL multiplier. -#define CKGR_MUL_SHIFT 16 ///< Least significant bit of the PLL multiplier. - -#define CKGR_USBDIV_MASK 0x30000000 ///< Divider for USB clocks. -#define CKGR_USBDIV_1 0x00000000 ///< Divider output is PLL clock output. -#define CKGR_USBDIV_2 0x10000000 ///< Divider output is PLL clock output divided by 2. -#define CKGR_USBDIV_4 0x20000000 ///< Divider output is PLL clock output divided by 4. -/*\}*/ - -/** Master Clock Register */ -/*\{*/ -#define PMC_MCKR_OFF 0x00000030 ///< Master clock register offset. -#define PMC_MCKR (*((reg32_t *)(PMC_BASE + PMC_MCKR_OFF))) ///< Master clock register address. - -#define PMC_PCKR0_OFF 0x00000040 ///< Programmable clock 0 register offset. -#define PMC_PCKR0 (*((reg32_t *)(PMC_BASE + PMC_PCKR0_OFF))) ///< Programmable clock 0 register address. -#define PMC_PCKR1_OFF 0x00000044 ///< Programmable clock 1 register offset. -#define PMC_PCKR1 (*((reg32_t *)(PMC_BASE + PMC_PCKR1_OFF))) ///< Programmable clock 1 register address. -#define PMC_PCKR2_OFF 0x00000048 ///< Programmable clock 2 register offset. -#define PMC_PCKR2 (*((reg32_t *)(PMC_BASE + PMC_PCKR2_OFF))) ///< Programmable clock 2 register address. - -#define PMC_CSS_MASK 0x00000003 ///< Clock selection mask. -#define PMC_CSS_SLOW_CLK 0x00000000 ///< Slow clock selected. -#define PMC_CSS_MAIN_CLK 0x00000001 ///< Main clock selected. -#define PMC_CSS_PLL_CLK 0x00000003 ///< PLL clock selected. - -#define PMC_PRES_MASK 0x0000001C ///< Clock prescaler mask. -#define PMC_PRES_SHIFT 2 ///< Clock prescaler LSB. -#define PMC_PRES_CLK 0x00000000 ///< Selected clock, not divided. -#define PMC_PRES_CLK_2 0x00000004 ///< Selected clock divided by 2. -#define PMC_PRES_CLK_4 0x00000008 ///< Selected clock divided by 4. -#define PMC_PRES_CLK_8 0x0000000C ///< Selected clock divided by 8. -#define PMC_PRES_CLK_16 0x00000010 ///< Selected clock divided by 16. -#define PMC_PRES_CLK_32 0x00000014 ///< Selected clock divided by 32. -#define PMC_PRES_CLK_64 0x00000018 ///< Selected clock divided by 64. -/*\}*/ - -/** Power Management Status and Interrupt Registers */ -/*\{*/ -#define PMC_IER_OFF 0x00000060 ///< Interrupt enable register offset. -#define PMC_IER (*((reg32_t *)(PMC_BASE + PMC_IER_OFF))) ///< Interrupt enable register address. -#define PMC_IDR_OFF 0x00000064 ///< Interrupt disable register offset. -#define PMC_IDR (*((reg32_t *)(PMC_BASE + PMC_IDR_OFF))) ///< Interrupt disable register address. -#define PMC_SR_OFF 0x00000068 ///< Status register offset. -#define PMC_SR (*((reg32_t *)(PMC_BASE + PMC_SR_OFF))) ///< Status register address. -#define PMC_IMR_OFF 0x0000006C ///< Interrupt mask register offset. -#define PMC_IMR (*((reg32_t *)(PMC_BASE + PMC_IMR_OFF))) ///< Interrupt mask register address. - -#define PMC_MOSCS 0 ///< Main oscillator. -#define PMC_LOCK 2 ///< PLL lock. -#define PMC_MCKRDY 3 ///< Master clock ready. -#define PMC_PCKRDY0 8 ///< Programmable clock 0 ready. -#define PMC_PCKRDY1 9 ///< Programmable clock 1 ready. -#define PMC_PCKRDY2 10 ///< Programmable clock 2 ready. -/*\}*/ - -#endif /* AT91_PMC_H */ diff --git a/cpu/arm/io/at91_pwm.h b/cpu/arm/io/at91_pwm.h deleted file mode 100644 index f4ae4c3c..00000000 --- a/cpu/arm/io/at91_pwm.h +++ /dev/null @@ -1,221 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91SAM7 Pulse Width Modulation Controller. - */ - -#ifndef AT91_PWM_H -#define AT91_PWM_H - -/** - * PWM Mode Register. - */ -/*\{*/ -#define PWM_MR_OFF 0x00000000 ///< PWM Mode Register offset. -#define PWM_MR (*((reg32_t *)(PWMC_BASE + PWM_MR_OFF))) ///< PWM Mode Register. -#define PWM_MR_DIVA_MASK 0x000000FF ///< PWM Mode Divide factor A Mask. -#define PWM_MR_DIVA_SHIFT 0 ///< PWM Mode Divide factor A LSB. -#define PWM_MR_DIVB_MASK 0x00FF0000 ///< PWM Mode Divide factor B Mask. -#define PWM_MR_DIVB_SHIFT 16 ///< PWM Mode Divide factor B LSB. - -#define PWM_MR_PREA_MASK 0x00000F00 ///< PWM Mode prescaler A Mask. -#define PWM_MR_PREA_SHIFT 8 ///< PWM Mode prescaler A LSB. -#define PWM_MR_PREB_MASK 0x0F000000 ///< PWM Mode prescaler B Mask. -#define PWM_MR_PREB_SHIFT 24 ///< PWM Mode prescaler B LSB. - -#define PWM_MR_PRE_MCK 0 ///< PWM Mode prescaler set to MCK. -#define PWM_MR_PRE_MCK_DIV2 1 ///< PWM Mode prescaler set to MCK/2. -#define PWM_MR_PRE_MCK_DIV4 2 ///< PWM Mode prescaler set to MCK/4. -#define PWM_MR_PRE_MCK_DIV8 3 ///< PWM Mode prescaler set to MCK/8. -#define PWM_MR_PRE_MCK_DIV16 4 ///< PWM Mode prescaler set to MCK/16. -#define PWM_MR_PRE_MCK_DIV32 5 ///< PWM Mode prescaler set to MCK/32. -#define PWM_MR_PRE_MCK_DIV64 6 ///< PWM Mode prescaler set to MCK/64. -#define PWM_MR_PRE_MCK_DIV128 7 ///< PWM Mode prescaler set to MCK/128. -#define PWM_MR_PRE_MCK_DIV256 8 ///< PWM Mode prescaler set to MCK/256. -#define PWM_MR_PRE_MCK_DIV512 9 ///< PWM Mode prescaler set to MCK/512. -#define PWM_MR_PRE_MCK_DIV1024 10 ///< PWM Mode prescaler set to MCK/1024. -/*\}*/ - -/** - * PWM Channel IDs. - */ -/*\{*/ -#define PWM_CHID_MASK 0x0000000F -#define PWM_CHID0 0 -#define PWM_CHID1 1 -#define PWM_CHID2 2 -#define PWM_CHID3 3 -/*\}*/ - -/** - * PWM Enable Register. - */ -/*\{*/ -#define PWM_ENA_OFF 0x00000004 ///< PWM Enable Register offset. -#define PWM_ENA (*((reg32_t *)(PWMC_BASE + PWM_ENA_OFF))) ///< PWM Enable Register. -/*\}*/ - -/** - * PWM Disable Register. - */ -/*\{*/ -#define PWM_DIS_OFF 0x00000008 ///< PWM Disable Register offset. -#define PWM_DIS (*((reg32_t *)(PWMC_BASE + PWM_DIS_OFF))) ///< PWM Disable Register. -/*\}*/ - -/** - * PWM Status Register. - */ -/*\{*/ -#define PWM_SR_OFF 0x0000000C ///< PWM Status Register offset. -#define PWM_SR (*((reg32_t *)(PWMC_BASE + PWM_SR_OFF))) ///< PWM Status Register. -/*\}*/ - -/** - * PWM Interrupt Enable Register. - */ -/*\{*/ -#define PWM_IER_OFF 0x00000010 ///< PWM Interrupt Enable Register offset. -#define PWM_IER (*((reg32_t *)(PWMC_BASE + PWM_IER_OFF))) ///< PWM Interrupt Enable Register. -/*\}*/ - -/** - * PWM Interrupt Disable Register. - */ -/*\{*/ -#define PWM_IDR_OFF 0x00000014 ///< PWM Interrupt Disable Register offset. -#define PWM_IDR (*((reg32_t *)(PWMC_BASE + PWM_IDR_OFF))) ///< PWM Interrupt Disable Register. -/*\}*/ - -/** - * PWM Interrupt Mask Register. - */ -/*\{*/ -#define PWM_IMR_OFF 0x00000018 ///< PWM Interrupt Mask Register offset. -#define PWM_IMR (*((reg32_t *)(PWMC_BASE + PWM_IMR_OFF))) ///< PWM Interrupt Mask Register. -/*\}*/ - -/** - * PWM Interrupt Status Register. - */ -/*\{*/ -#define PWM_ISR_OFF 0x0000001C ///< PWM Interrupt Status Register offset. -#define PWM_ISR (*((reg32_t *)(PWMC_BASE + PWM_ISR_OFF))) ///< PWM Interrupt Status Register. -/*\}*/ - -#define PWM_CH0_OFF 0x00000200 ///< PWM Channel 0 registers offset. -#define PWM_CH1_OFF 0x00000220 ///< PWM Channel 1 registers offset. -#define PWM_CH2_OFF 0x00000240 ///< PWM Channel 2 registers offset. -#define PWM_CH3_OFF 0x00000260 ///< PWM Channel 3 registers offset. - -/** - * PWM Channel Mode Register. - */ -/*\{*/ -#define PWM_CMR_OFF 0x00000000 ///< PWM Channel Mode Register offset. -#define PWM_CMR0 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Mode Register. -#define PWM_CMR1 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Mode Register. -#define PWM_CMR2 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Mode Register. -#define PWM_CMR3 (*((reg32_t *)(PWMC_BASE + PWM_CMR_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Mode Register. - -#define PWM_CPRE_MCK 0 ///< PWM Mode prescaler set to MCK. -#define PWM_CPRE_MCK_DIV2 1 ///< PWM Mode prescaler set to MCK/2. -#define PWM_CPRE_MCK_DIV4 2 ///< PWM Mode prescaler set to MCK/4. -#define PWM_CPRE_MCK_DIV8 3 ///< PWM Mode prescaler set to MCK/8. -#define PWM_CPRE_MCK_DIV16 4 ///< PWM Mode prescaler set to MCK/16. -#define PWM_CPRE_MCK_DIV32 5 ///< PWM Mode prescaler set to MCK/32. -#define PWM_CPRE_MCK_DIV64 6 ///< PWM Mode prescaler set to MCK/64. -#define PWM_CPRE_MCK_DIV128 7 ///< PWM Mode prescaler set to MCK/128. -#define PWM_CPRE_MCK_DIV256 8 ///< PWM Mode prescaler set to MCK/256. -#define PWM_CPRE_MCK_DIV512 9 ///< PWM Mode prescaler set to MCK/512. -#define PWM_CPRE_MCK_DIV1024 10 ///< PWM Mode prescaler set to MCK/1024. -#define PWM_CPRE_CLKA 11 ///< PWM Mode prescaler set to CLKA. -#define PWM_CPRE_CLKB 12 ///< PWM Mode prescaler set to CLKB. - -#define PWM_CALG 8 ///< PWM Mode channel alignment. -#define PWM_CPOL 9 ///< PWM Mode channel polarity. -#define PWM_CPD 10 ///< PWM Mode channel update period. -/*\}*/ - - -/** - * PWM Channel Duty Cycle Register. - */ -/*\{*/ -#define PWM_CDTY_OFF 0x00000004 ///< PWM Channel Duty Cycle Register offset. -#define PWM_CDTY0 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Duty Cycle Register. -#define PWM_CDTY1 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Duty Cycle Register. -#define PWM_CDTY2 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Duty Cycle Register. -#define PWM_CDTY3 (*((reg32_t *)(PWMC_BASE + PWM_CDTY_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Duty Cycle Register. -/*\}*/ - - -/** - * PWM Channel Period Register. - */ -/*\{*/ -#define PWM_CPRD_OFF 0x00000008 ///< PWM Channel Period Register offset. -#define PWM_CPRD0 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Period Register. -#define PWM_CPRD1 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Period Register. -#define PWM_CPRD2 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Period Register. -#define PWM_CPRD3 (*((reg32_t *)(PWMC_BASE + PWM_CPRD_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Period Register. -/*\}*/ - - -/** - * PWM Channel Counter Register. - */ -/*\{*/ -#define PWM_CCNT_OFF 0x0000000C ///< PWM Channel Counter Register offset. -#define PWM_CCNT0 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Counter Register. -#define PWM_CCNT1 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Counter Register. -#define PWM_CCNT2 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Counter Register. -#define PWM_CCNT3 (*((reg32_t *)(PWMC_BASE + PWM_CCNT_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Counter Register. -/*\}*/ - - -/** - * PWM Channel Update Register. - */ -/*\{*/ -#define PWM_CUPD_OFF 0x00000010 ///< PWM Channel Update Register offset. -#define PWM_CUPD0 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH0_OFF))) ///< PWM Channel 0 Update Register. -#define PWM_CUPD1 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH1_OFF))) ///< PWM Channel 1 Update Register. -#define PWM_CUPD2 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH2_OFF))) ///< PWM Channel 2 Update Register. -#define PWM_CUPD3 (*((reg32_t *)(PWMC_BASE + PWM_CUPD_OFF + PWM_CH3_OFF))) ///< PWM Channel 3 Update Register. -/*\}*/ - -#endif /* AT91_PWM_H */ diff --git a/cpu/arm/io/at91_rstc.h b/cpu/arm/io/at91_rstc.h deleted file mode 100644 index 96be7c34..00000000 --- a/cpu/arm/io/at91_rstc.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 reset controller. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_RTSC_H -#define AT91_RTSC_H - -/** Reset Controller Control Register */ -/*\{*/ -#define RSTC_CR (*((reg32_t *)(RSTC_BASE + 0x00))) ///< Reset controller control register address. -#define RSTC_PROCRST 0 ///< Processor reset. -#define RSTC_PERRST 2 ///< Peripheral reset. -#define RSTC_EXTRST 3 ///< External reset. -#define RSTC_KEY 0xA5000000 ///< Password. -/*\}*/ - -/** Reset Controller Status Register */ -/*\{*/ -#define RSTC_SR (*((reg32_t *)(RSTC_BASE + 0x04))) ///< Reset controller status register address. -#define RSTC_URSTS 0 ///< User reset status. -#define RSTC_BODSTS 1 ///< Brownout detection status. -#define RSTC_RSTTYP_MASK 0x00000700 ///< Reset type. -#define RSTC_RSTTYP_POWERUP 0x00000000 ///< Power-up reset. -//#define RSTC_RSTTYP_WAKEUP 0x00000100 ///< VDDCORE rising. -#define RSTC_RSTTYP_WATCHDOG 0x00000200 ///< Watchdog reset. -#define RSTC_RSTTYP_SOFTWARE 0x00000300 ///< Software reset. -#define RSTC_RSTTYP_USER 0x00000400 ///< User reset. -#define RSTC_RSTTYP_BROWNOUT 0x00000500 ///< Brownout reset. -#define RSTC_NRSTL 16 ///< NRST pin level. -#define RSTC_SRCMP 17 ///< Software reset command in progress. -/*\}*/ - -/** Reset Controller Mode Register */ -/*\{*/ -#define RSTC_MR (*((reg32_t *)(RSTC_BASE + 0x08))) ///< Reset controller mode register address. -#define RSTC_URSTEN 0 ///< User reset enable. -#define RSTC_URSTIEN 4 ///< User reset interrupt enable. -#define RSTC_ERSTL_MASK 0x00000F00 ///< External reset length. -#define RSTC_ERSTL_SHIFT 8 ///< Least significant bit of external reset length. -#define RSTC_BODIEN 16 ///< Brown-out detection interrupt enable. -/*\}*/ - - -#endif /* AT91_RTSC_H */ diff --git a/cpu/arm/io/at91_spi.h b/cpu/arm/io/at91_spi.h deleted file mode 100644 index 4766b75d..00000000 --- a/cpu/arm/io/at91_spi.h +++ /dev/null @@ -1,282 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91SAM7 SPI register definitions. - * This file is based on NUT/OS implementation. See license below. - - */ - -/* - * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - - */ - -#ifndef AT91_SPI_H -#define AT91_SPI_H - -/** - * SPI Control Register - */ -/*\{*/ -#define SPI_CR_OFF 0x00000000 ///< Control register offset. - -#define SPI_SPIEN 0 ///< SPI enable. -#define SPI_SPIDIS 1 ///< SPI disable. -#define SPI_SWRST 7 ///< Software reset. -#define SPI_LASTXFER 24 ///< Last transfer. -/*\}*/ - -/** - * SPI Mode Register - */ -/*\{*/ -#define SPI_MR_OFF 0x00000004 ///< Mode register offset. - -#define SPI_MSTR 0 ///< Master mode. -#define SPI_PS 1 ///< Peripheral select. -#define SPI_PCSDEC 2 ///< Chip select decode. -#define SPI_FDIV 3 ///< Clock selection. -#define SPI_MODFDIS 4 ///< Mode fault detection. -#define SPI_LLB 7 ///< Local loopback enable. -#define SPI_PCS 0x000F0000 ///< Peripheral chip select mask. -#define SPI_PCS_0 0x000E0000 ///< Peripheral chip select 0. -#define SPI_PCS_1 0x000D0000 ///< Peripheral chip select 1. -#define SPI_PCS_2 0x000B0000 ///< Peripheral chip select 2. -#define SPI_PCS_3 0x00070000 ///< Peripheral chip select 3. -#define SPI_PCS_SHIFT 16 ///< Least significant bit of peripheral chip select. -#define SPI_DLYBCS 0xFF000000 ///< Mask for delay between chip selects. -#define SPI_DLYBCS_SHIFT 24 ///< Least significant bit of delay between chip selects. -/*\}*/ - -/** - * SPI Receive Data Register - */ -/*\{*/ -#define SPI_RDR_OFF 0x00000008 ///< Receive data register offset. - -#define SPI_RD 0x0000FFFF ///< Receive data mask. -#define SPI_RD_SHIFT 0 ///< Least significant bit of receive data. -/*\}*/ - -/** - * SPI Transmit Data Register - */ -/*\{*/ -#define SPI_TDR_OFF 0x0000000C ///< Transmit data register offset. - -#define SPI_TD 0x0000FFFF ///< Transmit data mask. -#define SPI_TD_SHIFT 0 ///< Least significant bit of transmit data. -/*\}*/ - -/** - * SPI Status and Interrupt Register - */ -/*\{*/ -#define SPI_SR_OFF 0x00000010 ///< Status register offset. -#define SPI_IER_OFF 0x00000014 ///< Interrupt enable register offset. -#define SPI_IDR_OFF 0x00000018 ///< Interrupt disable register offset. -#define SPI_IMR_OFF 0x0000001C ///< Interrupt mask register offset. - -#define SPI_RDRF 0 ///< Receive data register full. -#define SPI_TDRE 1 ///< Transmit data register empty. -#define SPI_MODF 2 ///< Mode fault error. -#define SPI_OVRES 3 ///< Overrun error status. -#define SPI_ENDRX 4 ///< End of RX buffer. -#define SPI_ENDTX 5 ///< End of TX buffer. -#define SPI_RXBUFF 6 ///< RX buffer full. -#define SPI_TXBUFE 7 ///< TX buffer empty. -#define SPI_NSSR 8 ///< NSS rising. -#define SPI_TXEMPTY 9 ///< Transmission register empty. -#define SPI_SPIENS 16 ///< SPI enable status. -/*\}*/ - -/** - * SPI Chip Select Registers - */ -/*\{*/ -#define SPI_CSR0_OFF 0x00000030 ///< Chip select register 0 offset. -#define SPI_CSR1_OFF 0x00000034 ///< Chip select register 1 offset. -#define SPI_CSR2_OFF 0x00000038 ///< Chip select register 2 offset. -#define SPI_CSR3_OFF 0x0000003C ///< Chip select register 3 offset. - -#define SPI_CPOL 0 ///< Clock polarity. -#define SPI_NCPHA 1 ///< Clock phase. -#define SPI_CSAAT 3 ///< Chip select active after transfer. -#define SPI_BITS 0x000000F0 ///< Bits per transfer mask. -#define SPI_BITS_8 0x00000000 ///< 8 bits per transfer. -#define SPI_BITS_9 0x00000010 ///< 9 bits per transfer. -#define SPI_BITS_10 0x00000020 ///< 10 bits per transfer. -#define SPI_BITS_11 0x00000030 ///< 11 bits per transfer. -#define SPI_BITS_12 0x00000040 ///< 12 bits per transfer. -#define SPI_BITS_13 0x00000050 ///< 13 bits per transfer. -#define SPI_BITS_14 0x00000060 ///< 14 bits per transfer. -#define SPI_BITS_15 0x00000070 ///< 15 bits per transfer. -#define SPI_BITS_16 0x00000080 ///< 16 bits per transfer. -#define SPI_BITS_SHIFT 4 ///< Least significant bit of bits per transfer. -#define SPI_SCBR 0x0000FF00 ///< Serial clock baud rate mask. -#define SPI_SCBR_SHIFT 8 ///< Least significant bit of serial clock baud rate. -#define SPI_DLYBS 0x00FF0000 ///< Delay before SPCK mask. -#define SPI_DLYBS_SHIFT 16 ///< Least significant bit of delay before SPCK. -#define SPI_DLYBCT 0xFF000000 ///< Delay between consecutive transfers mask. -#define SPI_DLYBCT_SHIFT 24 ///< Least significant bit of delay between consecutive transfers. -/*\}*/ - -/** - * Single SPI Register Addresses - */ -/*\{*/ -#if defined(SPI_BASE) - #define SPI0_BASE SPI_BASE - #define SPI_CR SPI0_CR ///< SPI Control Register Write-only. - #define SPI_MR SPI0_MR ///< SPI Mode Register Read/Write Reset=0x0. - #define SPI_RDR SPI0_RDR ///< SPI Receive Data Register Read-only Reset=0x0. - #define SPI_TDR SPI0_TDR ///< SPI Transmit Data Register Write-only . - #define SPI_SR SPI0_SR ///< SPI Status Register Read-only Reset=0x000000F0. - #define SPI_IER SPI0_IER ///< SPI Interrupt Enable Register Write-only. - #define SPI_IDR SPI0_IDR ///< SPI Interrupt Disable Register Write-only. - #define SPI_IMR SPI0_IMR ///< SPI Interrupt Mask Register Read-only Reset=0x0. - #define SPI_CSR0 SPI0_CSR0 ///< SPI Chip Select Register 0 Read/Write Reset=0x0. - #define SPI_CSR1 SPI0_CSR1 ///< SPI Chip Select Register 1 Read/Write Reset=0x0. - #define SPI_CSR2 SPI0_CSR2 ///< SPI Chip Select Register 2 Read/Write Reset=0x0. - #define SPI_CSR3 SPI0_CSR3 ///< SPI Chip Select Register 3 Read/Write Reset=0x0. - #if defined(SPI_HAS_PDC) - #define SPI_RPR SPI0_RPR ///< PDC channel 0 receive pointer register. - #define SPI_RCR SPI0_RCR ///< PDC channel 0 receive counter register. - #define SPI_TPR SPI0_TPR ///< PDC channel 0 transmit pointer register. - #define SPI_TCR SPI0_TCR ///< PDC channel 0 transmit counter register. - #define SPI_RNPR SPI0_RNPR ///< PDC channel 0 receive next pointer register. - #define SPI_RNCR SPI0_RNCR ///< PDC channel 0 receive next counter register. - #define SPI_TNPR SPI0_TNPR ///< PDC channel 0 transmit next pointer register. - #define SPI_TNCR SPI0_TNCR ///< PDC channel 0 transmit next counter register. - #define SPI_PTCR SPI0_PTCR ///< PDC channel 0 transfer control register. - #define SPI_PTSR SPI0_PTSR ///< PDC channel 0 transfer status register. - #endif /* SPI_HAS_PDC */ -#endif /* SPI_BASE */ -/*\}*/ - -/** - * SPI 0 Register Addresses - */ -/*\{*/ -#if defined(SPI0_BASE) - #define SPI0_CR (*((reg32_t *)(SPI0_BASE + SPI_CR_OFF))) ///< SPI Control Register Write-only. - #define SPI0_MR (*((reg32_t *)(SPI0_BASE + SPI_MR_OFF))) ///< SPI Mode Register Read/Write Reset=0x0. - #define SPI0_RDR (*((reg32_t *)(SPI0_BASE + SPI_RDR_OFF))) ///< SPI Receive Data Register Read-only Reset=0x0. - #define SPI0_TDR (*((reg32_t *)(SPI0_BASE + SPI_TDR_OFF))) ///< SPI Transmit Data Register Write-only . - #define SPI0_SR (*((reg32_t *)(SPI0_BASE + SPI_SR_OFF))) ///< SPI Status Register Read-only Reset=0x000000F0. - #define SPI0_IER (*((reg32_t *)(SPI0_BASE + SPI_IER_OFF))) ///< SPI Interrupt Enable Register Write-only. - #define SPI0_IDR (*((reg32_t *)(SPI0_BASE + SPI_IDR_OFF))) ///< SPI Interrupt Disable Register Write-only. - #define SPI0_IMR (*((reg32_t *)(SPI0_BASE + SPI_IMR_OFF))) ///< SPI Interrupt Mask Register Read-only Reset=0x0. - #define SPI0_CSR0 (*((reg32_t *)(SPI0_BASE + SPI_CSR0_OFF))) ///< SPI Chip Select Register 0 Read/Write Reset=0x0. - #define SPI0_CSR1 (*((reg32_t *)(SPI0_BASE + SPI_CSR1_OFF))) ///< SPI Chip Select Register 1 Read/Write Reset=0x0. - #define SPI0_CSR2 (*((reg32_t *)(SPI0_BASE + SPI_CSR2_OFF))) ///< SPI Chip Select Register 2 Read/Write Reset=0x0. - #define SPI0_CSR3 (*((reg32_t *)(SPI0_BASE + SPI_CSR3_OFF))) ///< SPI Chip Select Register 3 Read/Write Reset=0x0. - #if defined(SPI_HAS_PDC) - #define SPI0_RPR (*((reg32_t *)(SPI0_BASE + PERIPH_RPR_OFF)) ///< PDC channel 0 receive pointer register. - #define SPI0_RCR (*((reg32_t *)(SPI0_BASE + PERIPH_RCR_OFF)) ///< PDC channel 0 receive counter register. - #define SPI0_TPR (*((reg32_t *)(SPI0_BASE + PERIPH_TPR_OFF)) ///< PDC channel 0 transmit pointer register. - #define SPI0_TCR (*((reg32_t *)(SPI0_BASE + PERIPH_TCR_OFF)) ///< PDC channel 0 transmit counter register. - #define SPI0_RNPR (*((reg32_t *)(SPI0_BASE + PERIPH_RNPR_OFF)) ///< PDC channel 0 receive next pointer register. - #define SPI0_RNCR (*((reg32_t *)(SPI0_BASE + PERIPH_RNCR_OFF)) ///< PDC channel 0 receive next counter register. - #define SPI0_TNPR (*((reg32_t *)(SPI0_BASE + PERIPH_TNPR_OFF)) ///< PDC channel 0 transmit next pointer register. - #define SPI0_TNCR (*((reg32_t *)(SPI0_BASE + PERIPH_TNCR_OFF)) ///< PDC channel 0 transmit next counter register. - #define SPI0_PTCR (*((reg32_t *)(SPI0_BASE + PERIPH_PTCR_OFF)) ///< PDC channel 0 transfer control register. - #define SPI0_PTSR (*((reg32_t *)(SPI0_BASE + PERIPH_PTSR_OFF)) ///< PDC channel 0 transfer status register. - #endif /* SPI_HAS_PDC */ -#endif /* SPI0_BASE */ -/*\}*/ - -/** - * SPI 1 Register Addresses - */ -/*\{*/ -#if defined(SPI1_BASE) - #define SPI1_CR (*((reg32_t *)(SPI1_BASE + SPI_CR_OFF))) ///< SPI Control Register Write-only. - #define SPI1_MR (*((reg32_t *)(SPI1_BASE + SPI_MR_OFF))) ///< SPI Mode Register Read/Write Reset=0x0. - #define SPI1_RDR (*((reg32_t *)(SPI1_BASE + SPI_RDR_OFF))) ///< SPI Receive Data Register Read-only Reset=0x0. - #define SPI1_TDR (*((reg32_t *)(SPI1_BASE + SPI_TDR_OFF))) ///< SPI Transmit Data Register Write-only . - #define SPI1_SR (*((reg32_t *)(SPI1_BASE + SPI_SR_OFF))) ///< SPI Status Register Read-only Reset=0x000000F0. - #define SPI1_IER (*((reg32_t *)(SPI1_BASE + SPI_IER_OFF))) ///< SPI Interrupt Enable Register Write-only. - #define SPI1_IDR (*((reg32_t *)(SPI1_BASE + SPI_IDR_OFF))) ///< SPI Interrupt Disable Register Write-only. - #define SPI1_IMR (*((reg32_t *)(SPI1_BASE + SPI_IMR_OFF))) ///< SPI Interrupt Mask Register Read-only Reset=0x0. - #define SPI1_CSR0 (*((reg32_t *)(SPI1_BASE + SPI_CSR0_OFF))) ///< SPI Chip Select Register 0 Read/Write Reset=0x0. - #define SPI1_CSR1 (*((reg32_t *)(SPI1_BASE + SPI_CSR1_OFF))) ///< SPI Chip Select Register 1 Read/Write Reset=0x0. - #define SPI1_CSR2 (*((reg32_t *)(SPI1_BASE + SPI_CSR2_OFF))) ///< SPI Chip Select Register 2 Read/Write Reset=0x0. - #define SPI1_CSR3 (*((reg32_t *)(SPI1_BASE + SPI_CSR3_OFF))) ///< SPI Chip Select Register 3 Read/Write Reset=0x0. - #if defined(SPI_HAS_PDC) - #define SPI1_RPR (*((reg32_t *)(SPI1_BASE + PERIPH_RPR_OFF))) ///< PDC channel 1 receive pointer register. - #define SPI1_RCR (*((reg32_t *)(SPI1_BASE + PERIPH_RCR_OFF))) ///< PDC channel 1 receive counter register. - #define SPI1_TPR (*((reg32_t *)(SPI1_BASE + PERIPH_TPR_OFF))) ///< PDC channel 1 transmit pointer register. - #define SPI1_TCR (*((reg32_t *)(SPI1_BASE + PERIPH_TCR_OFF))) ///< PDC channel 1 transmit counter register. - #define SPI1_RNPR (*((reg32_t *)(SPI1_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 1 receive next pointer register. - #define SPI1_RNCR (*((reg32_t *)(SPI1_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 1 receive next counter register. - #define SPI1_TNPR (*((reg32_t *)(SPI1_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 1 transmit next pointer register. - #define SPI1_TNCR (*((reg32_t *)(SPI1_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 1 transmit next counter register. - #define SPI1_PTCR (*((reg32_t *)(SPI1_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 1 transfer control register. - #define SPI1_PTSR (*((reg32_t *)(SPI1_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 1 transfer status register. - #endif /* SPI_HAS_PDC */ -#endif /* SPI1_BASE */ -/*\}*/ - -#endif /* AT91_SPI_H */ diff --git a/cpu/arm/io/at91_tc.h b/cpu/arm/io/at91_tc.h deleted file mode 100644 index 080d5881..00000000 --- a/cpu/arm/io/at91_tc.h +++ /dev/null @@ -1,321 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Daniele Basile - * - * AT91SAM7 Conunter timer definition. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_TC_H -#define AT91_TC_H - - -/** - * Timer Counter Control Register - */ -#define TC_TC0_OFF 0x00000000 ///< Channel 0 control register offset. -#define TC_TC1_OFF 0x00000040 ///< Channel 1 control register offset. -#define TC_TC2_OFF 0x00000080 ///< Channel 2 control register offset. -#define TC0_CCR (*((reg32_t *)(TC_BASE + TC_TC0_OFF))) ///< Channel 0 control register address. -#define TC1_CCR (*((reg32_t *)(TC_BASE + TC_TC1_OFF))) ///< Channel 1 control register address. -#define TC2_CCR (*((reg32_t *)(TC_BASE + TC_TC2_OFF))) ///< Channel 2 control register address. -#define TC_CLKEN 0 ///< Clock enable command. -#define TC_CLKDIS 1 ///< Clock disable command. -#define TC_SWTRG 2 ///< Software trigger command. - -/** - * Timer Counter Channel Mode Register - */ -#define TC_CMR_OFF 0x00000004 ///< Mode register offset. -#define TC0_CMR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_CMR_OFF))) ///< Channel 0 mode register address. -#define TC1_CMR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_CMR_OFF))) ///< Channel 1 mode register address. -#define TC2_CMR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_CMR_OFF))) ///< Channel 2 mode register address. - -#define TC_CLKS_MASK 0x00000007 ///< Clock selection mask. -#define TC_CLKS_MCK2 0x00000000 ///< Selects MCK / 2. -#define TC_CLKS_MCK8 0x00000001 ///< Selects MCK / 8. -#define TC_CLKS_MCK32 0x00000002 ///< Selects MCK / 32. -#define TC_CLKS_MCK128 0x00000003 ///< Selects MCK / 128. -#define TC_CLKS_MCK1024 0x00000004 ///< Selects MCK / 1024. -#define TC_CLKS_XC0 0x00000005 ///< Selects external clock 0. -#define TC_CLKS_XC1 0x00000006 ///< Selects external clock 1. -#define TC_CLKS_XC2 0x00000007 ///< Selects external clock 2. - -#define TC_CLKI 3 ///< Increments on falling edge. - -#define TC_BURST_MASK 0x00000030 ///< Burst signal selection mask. -#define TC_BURST_NONE 0x00000000 ///< Clock is not gated by an external signal. -#define TC_BUSRT_XC0 0x00000010 ///< ANDed with external clock 0. -#define TC_BURST_XC1 0x00000020 ///< ANDed with external clock 1. -#define TC_BURST_XC2 0x00000030 ///< ANDed with external clock 2. - - - -#define TC_WAVE 15 ///< Selects waveform mode. -//To select capture mode you must set TC_WAVE bit to 0. -//#define TC_CAPT 15 ///< Selects capture mode. - -/** - * Capture Mode - */ -#define TC_CPCTRG 14 ///< RC Compare Enable Trigger Enable. -#define TC_LDBSTOP 6 ///< Counter clock stopped on RB loading. -#define TC_LDBDIS 7 ///< Counter clock disabled on RB loading. - -#define TC_ETRGEDG_MASK 0x00000300 ///< External trigger edge selection mask. -#define TC_ETRGEDG_RISING_EDGE 0x00000100 ///< Trigger on external rising edge. -#define TC_ETRGEDG_FALLING_EDGE 0x00000200 ///< Trigger on external falling edge. -#define TC_ETRGEDG_BOTH_EDGE 0x00000300 ///< Trigger on both external edges. - -#define TC_ABETRG_MASK 0x00000400 ///< TIOA or TIOB external trigger selection mask. -#define TC_ABETRG_TIOA 10 ///< TIOA used as an external trigger. -//To use external trigger TIOB you must set TC_ABETRG_TIOA bit to 0. -//#define TC_ABETRG_TIOB 10 ///< TIOB used as an external trigger. - - -#define TC_LDRA_MASK 0x00030000 ///< RA loading selection mask. -#define TC_LDRA_RISING_EDGE 0x00010000 ///< Load RA on rising edge of TIOA. -#define TC_LDRA_FALLING_EDGE 0x00020000 ///< Load RA on falling edge of TIOA. -#define TC_LDRA_BOTH_EDGE 0x00030000 ///< Load RA on any edge of TIOA. - -#define TC_LDRB_MASK 0x000C0000 ///< RB loading selection mask. -#define TC_LDRB_RISING_EDGE 0x00040000 ///< Load RB on rising edge of TIOA. -#define TC_LDRB_FALLING_EDGE 0x00080000 ///< Load RB on falling edge of TIOA. -#define TC_LDRB_BOTH_EDGE 0x000C0000 ///< Load RB on any edge of TIOA. - - -/** - * Waveform Mode - */ -#define TC_CPCSTOP 6 ///< Counter clock stopped on RC compare. -#define TC_CPCDIS 7 ///< Counter clock disabled on RC compare. - -#define TC_EEVTEDG_MASK 0x00000300 ///< External event edge selection mask. -#define TC_EEVTEDG_RISING_EDGE 0x00000100 ///< External event on rising edge.. -#define TC_EEVTEDG_FALLING_EDGE 0x00000200 ///< External event on falling edge.. -#define TC_EEVTEDG_BOTH_EDGE 0x00000300 ///< External event on any edge.. - -#define TC_EEVT_MASK 0x00000C00 ///< External event selection mask. -#define TC_EEVT_TIOB 0x00000000 ///< TIOB selected as external event. -#define TC_EEVT_XC0 0x00000400 ///< XC0 selected as external event. -#define TC_EEVT_XC1 0x00000800 ///< XC1 selected as external event. -#define TC_EEVT_XC2 0x00000C00 ///< XC2 selected as external event. - -#define TC_ENETRG 12 ///< External event trigger enable. - -#define TC_WAVSEL_MASK 0x00006000 ///< Waveform selection mask. -#define TC_WAVSEL_UP_RC 0x00000000 ///< UP mode whitout automatic trigger on RC compare. -#define TC_WAVSEL_UP_RC_TRG 0x00004000 ///< UP mode whit automatic trigger on RC compare. -#define TC_WAVSEL_UPDOWN_RC 0x00002000 ///< UPDOWN mode whitout automatic trigger on RC compare. -#define TC_WAVSEL_UPDOWN_RC_TRG 0x00003000 ///< UPDOWN mode whit automatic trigger on RC compare. - - -#define TC_ACPA_MASK 0x00030000 ///< Masks RA compare effect on TIOA. -#define TC_ACPA_SET_OUTPUT 0x00010000 ///< RA compare sets TIOA. -#define TC_ACPA_CLEAR_OUTPUT 0x00020000 ///< RA compare clears TIOA. -#define TC_ACPA_TOGGLE_OUTPUT 0x00030000 ///< RA compare toggles TIOA. - -#define TC_ACPC_MASK 0x000C0000 ///< Masks RC compare effect on TIOA. -#define TC_ACPC_SET_OUTPUT 0x00040000 ///< RC compare sets TIOA. -#define TC_ACPC_CLEAR_OUTPUT 0x00080000 ///< RC compare clears TIOA. -#define TC_ACPC_TOGGLE_OUTPUT 0x000C0000 ///< RC compare toggles TIOA. - -#define TC_AEEVT_MASK 0x00300000 ///< Masks external event effect on TIOA. -#define TC_AEEVT_SET_OUTPUT 0x00100000 ///< External event sets TIOA. -#define TC_AEEVT_CLEAR_OUTPUT 0x00200000 ///< External event clears TIOA. -#define TC_AEEVT_TOGGLE_OUTPUT 0x00300000 ///< External event toggles TIOA. - -#define TC_ASWTRG_MASK 0x00C00000 ///< Masks software trigger effect on TIOA. -#define TC_ASWTRG_SET_OUTPUT 0x00400000 ///< Software trigger sets TIOA. -#define TC_ASWTRG_CLEAR_OUTPUT 0x00800000 ///< Software trigger clears TIOA. -#define TC_ASWTRG_TOGGLE_OUTPUT 0x00C00000 ///< Software trigger toggles TIOA. - -#define TC_BCPB_MASK 0x03000000 ///< Masks RB compare effect on TIOB. -#define TC_BCPB_SET_OUTPUT 0x01000000 ///< RB compare sets TIOB. -#define TC_BCPB_CLEAR_OUTPUT 0x02000000 ///< RB compare clears TIOB. -#define TC_BCPB_TOGGLE_OUTPUT 0x03000000 ///< RB compare toggles TIOB. - -#define TC_BCPC_MASK 0x0C000000 ///< Masks RC compare effect on TIOB. -#define TC_BCPC_SET_OUTPUT 0x04000000 ///< RC compare sets TIOB. -#define TC_BCPC_CLEAR_OUTPUT 0x08000000 ///< RC compare clears TIOB. -#define TC_BCPC_TOGGLE_OUTPUT 0x0C000000 ///< RC compare toggles TIOB. - -#define TC_BEEVT_MASK 0x30000000 ///< Masks external event effect on TIOB. -#define TC_BEEVT_SET_OUTPUT 0x10000000 ///< External event sets TIOB. -#define TC_BEEVT_CLEAR_OUTPUT 0x20000000 ///< External event clears TIOB. -#define TC_BEEVT_TOGGLE_OUTPUT 0x30000000 ///< External event toggles TIOB. - -#define TC_BSWTRG_MASK 0xC0000000 ///< Masks software trigger effect on TIOB. -#define TC_BSWTRG_SET_OUTPUT 0x40000000 ///< Software trigger sets TIOB. -#define TC_BSWTRG_CLEAR_OUTPUT 0x80000000 ///< Software trigger clears TIOB. -#define TC_BSWTRG_TOGGLE_OUTPUT 0xC0000000 ///< Software trigger toggles TIOB. - -/** - * Counter Value Register - */ -#define TC_CV_OFF 0x00000010 ///< Counter register value offset. -#define TC0_CV (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_CV_OFF))) ///< Counter 0 value. -#define TC1_CV (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_CV_OFF))) ///< Counter 1 value. -#define TC2_CV (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_CV_OFF))) ///< Counter 2 value. - -/** - * Timer Counter Register A - */ -#define TC_RA_OFF 0x00000014 ///< Register A offset. -#define TC0_RA (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RA_OFF))) ///< Channel 0 register A. -#define TC1_RA (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RA_OFF))) ///< Channel 1 register A. -#define TC2_RA (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RA_OFF))) ///< Channel 2 register A. - - -/** - * Timer Counter Register B - */ -#define TC_RB_OFF 0x00000018 ///< Register B offset. -#define TC0_RB (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RB_OFF))) ///< Channel 0 register B. -#define TC1_RB (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RB_OFF))) ///< Channel 1 register B. -#define TC2_RB (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RB_OFF))) ///< Channel 2 register B. - - -/** - * Timer Counter Register C - */ -#define TC_RC_OFF 0x0000001C ///< Register C offset. -#define TC0_RC (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_RC_OFF))) ///< Channel 0 register C. -#define TC1_RC (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_RC_OFF))) ///< Channel 1 register C. -#define TC2_RC (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_RC_OFF))) ///< Channel 2 register C. - - - -/** - * Timer Counter Status and Interrupt Registers - */ -#define TC_SR_OFF 0x00000020 ///< Status Register offset. -#define TC0_SR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_SR_OFF))) ///< Status register address. -#define TC1_SR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_SR_OFF))) ///< Status register address. -#define TC2_SR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_SR_OFF))) ///< Status register address. - -#define TC_IER_OFF 0x00000024 ///< Interrupt Enable Register offset. -#define TC0_IER (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IER_OFF))) ///< Channel 0 interrupt enable register address. -#define TC1_IER (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IER_OFF))) ///< Channel 1 interrupt enable register address. -#define TC2_IER (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IER_OFF))) ///< Channel 2 interrupt enable register address. - -#define TC_IDR_OFF 0x00000028 ///< Interrupt Disable Register offset. -#define TC0_IDR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IDR_OFF))) ///< Channel 0 interrupt disable register address. -#define TC1_IDR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IDR_OFF))) ///< Channel 1 interrupt disable register address. -#define TC2_IDR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IDR_OFF))) ///< Channel 2 interrupt disable register address. - -#define TC_IMR_OFF 0x0000002C ///< Interrupt Mask Register offset. -#define TC0_IMR (*((reg32_t *)(TC_BASE + TC_TC0_OFF + TC_IMR_OFF))) ///< Channel 0 interrupt mask register address. -#define TC1_IMR (*((reg32_t *)(TC_BASE + TC_TC1_OFF + TC_IMR_OFF))) ///< Channel 1 interrupt mask register address. -#define TC2_IMR (*((reg32_t *)(TC_BASE + TC_TC2_OFF + TC_IMR_OFF))) ///< Channel 2 interrupt mask register address. - -#define TC_COVFS 0 ///< Counter overflow flag. -#define TC_LOVRS 1 ///< Load overrun flag. -#define TC_CPAS 2 ///< RA compare flag. -#define TC_CPBS 3 ///< RB compare flag. -#define TC_CPCS 4 ///< RC compare flag. -#define TC_LDRAS 5 ///< RA loading flag. -#define TC_LDRBS 6 ///< RB loading flag. -#define TC_ETRGS 7 ///< External trigger flag. -#define TC_CLKSTA 16 ///< Clock enable flag. -#define TC_MTIOA 17 ///< TIOA flag. -#define TC_MTIOB 18 ///< TIOB flag. - - -/** - * Timer Counter Block Control Register - */ -#define TC_BCR_OFF 0x000000C0 ///< Block control register offset. -#define TC_BCR (*((reg32_t *)(TC_BASE + TC_BCR_OFF))) ///< Block control register address. -#define TC_SYNC 0 ///< Synchronisation trigger - - -/** - * Timer Counter Block Mode Register - */ -#define TC_BMR_OFF 0x000000C4 ///< Block mode register offset. -#define TC_BMR (*((reg32_t *)(TC_BASE + TC_BMR_OFF))) ///< Block mode register address. -#define TC_TC0XC0S 0x00000003 ///< External clock signal 0 selection mask. -#define TC_TCLK0XC0 0x00000000 ///< Selects TCLK0. -#define TC_NONEXC0 0x00000001 ///< None selected. -#define TC_TIOA1XC0 0x00000002 ///< Selects TIOA1. -#define TC_TIOA2XC0 0x00000003 ///< Selects TIOA2. - -#define TC_TC1XC1S 0x0000000C ///< External clock signal 1 selection mask. -#define TC_TCLK1XC1 0x00000000 ///< Selects TCLK1. -#define TC_NONEXC1 0x00000004 ///< None selected. -#define TC_TIOA0XC1 0x00000008 ///< Selects TIOA0. -#define TC_TIOA2XC1 0x0000000C ///< Selects TIOA2. - -#define TC_TC2XC2S 0x00000030 ///< External clock signal 2 selection mask. -#define TC_TCLK2XC2 0x00000000 ///< Selects TCLK2. -#define TC_NONEXC2 0x00000010 ///< None selected. -#define TC_TIOA0XC2 0x00000020 ///< Selects TIOA0. -#define TC_TIOA1XC2 0x00000030 ///< Selects TIOA1. - - -#endif /* AT91_TC_H */ diff --git a/cpu/arm/io/at91_twi.h b/cpu/arm/io/at91_twi.h deleted file mode 100644 index 1d7be6ab..00000000 --- a/cpu/arm/io/at91_twi.h +++ /dev/null @@ -1,191 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91SAM7 Two wire interface. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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 (*((reg32_t *)(INCLUDING NEGLIGENCE OR OTHERWISE))) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_TWI_H -#define AT91_TWI_H - - -/** - * TWI Control Register. - * \{ - */ -#define TWI_CR_OFF 0x00000000 ///< Control register offset. -#define TWI_CR (*((reg32_t *)(TWI_BASE + TWI_CR_OFF))) ///< Control register address. -#define TWI_START 0 ///< Send start condition. -#define TWI_STOP 1 ///< Send stop condition. -#define TWI_MSEN 2 ///< Enable master mode. -#define TWI_MSDIS 3 ///< Disable master mode. -/* -#define TWI_SVEN 4 ///< Enable slave mode. -#define TWI_SVDIS 5 ///< Disable slave mode. -*/ -#define TWI_SWRST 7 ///< Software reset. -/*\}*/ - -/** - * TWI Master Mode Register. - * \{ - */ -#define TWI_MMR_OFF 0x00000004 ///< Master mode register offset. -#define TWI_MMR (*((reg32_t *)(TWI_BASE + TWI_MMR_OFF))) ///< Master mode register address. -#define TWI_IADRSZ_SHIFT 8 ///< Internal device address size shift. -#define TWI_IADRSZ 0x00000300 ///< Internal device address size mask. -#define TWI_IADRSZ_NONE 0x00000000 ///< No internal device address. -#define TWI_IADRSZ_1BYTE 0x00000100 ///< One byte internal device address. -#define TWI_IADRSZ_2BYTE 0x00000200 ///< Two byte internal device address. -#define TWI_IADRSZ_3BYTE 0x00000300 ///< Three byte internal device address. -#define TWI_MREAD 12 ///< Master read direction. -#define TWI_DADR 0x007F0000 ///< Device address mask. -#define TWI_DADR_SHIFT 16 ///< Device address LSB. -/*\}*/ - -/** - * TWI Internal Address Register. - * \{ - */ -#define TWI_IADR_OFF 0x0000000C ///< Internal address register offset. -#define TWI_IADR (*((reg32_t *)(TWI_BASE + TWI_IADR_OFF))) ///< Internal address register address. -#define TWI_IADR_MASK 0x00FFFFFF ///< Internal address mask. -#define TWI_IADR_SHIFT 0 ///< Internal address LSB. -/*\}*/ - -/** - * TWI Clock Waveform Generator Register. - * \{ - */ -#define TWI_CWGR_OFF 0x00000010 ///< Clock waveform generator register offset. -#define TWI_CWGR (*((reg32_t *)(TWI_BASE + TWI_CWGR_OFF))) ///< Clock waveform generator register address. -#define TWI_CLDIV 0x000000FF ///< Clock low divider mask. -#define TWI_CLDIV_SHIFT 0 ///< Clock low divider LSB. -#define TWI_CHDIV 0x0000FF00 ///< Clock high divider mask. -#define TWI_CHDIV_SHIFT 8 ///< Clock high divider LSB. -#define TWI_CKDIV 0x00070000 ///< Clock divider mask. -#define TWI_CKDIV_SHIFT 16 ///< Clock divider LSB. -/*\}*/ - -/** - * TWI Status and Interrupt Registers. - * \{ - */ -#define TWI_SR_OFF 0x00000020 ///< Status register offset. -#define TWI_SR (*((reg32_t *)(TWI_BASE + TWI_SR_OFF))) ///< Status register address. - -#define TWI_IER_OFF 0x00000024 ///< Interrupt enable register offset. -#define TWI_IER (*((reg32_t *)(TWI_BASE + TWI_IER_OFF))) ///< Interrupt enable register address. - -#define TWI_IDR_OFF 0x00000028 ///< Interrupt disable register offset. -#define TWI_IDR (*((reg32_t *)(TWI_BASE + TWI_IDR_OFF))) ///< Interrupt disable register address. - -#define TWI_IMR_OFF 0x0000002C ///< Interrupt mask register offset. -#define TWI_IMR (*((reg32_t *)(TWI_BASE + TWI_IMR_OFF))) ///< Interrupt mask register address. - -#define TWI_TXCOMP 0 ///< Transmission completed. -#define TWI_RXRDY 1 ///< Receive holding register ready. -#define TWI_TXRDY 2 ///< Transmit holding register ready. - -/* -#define TWI_SVREAD 0x00000008 ///< Slave read. -#define TWI_SVACC 0x00000010 ///< Slave access. -#define TWI_GACC 0x00000020 ///< General call access. -*/ - -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 -#define TWI_OVRE 6 ///< Overrun error. -#define TWI_UNRE 7 ///< Underrun error. -#endif - -#define TWI_NACK 8 ///< Not acknowledged. -/* -#define TWI_ARBLST 0x00000200 ///< Arbitration lost. -#define TWI_SCLWS 0x00000400 ///< Clock wait state. -#define TWI_EOSACC 0x00000800 ///< End of slave access. -*/ -/*\}*/ - -/** - * TWI Receive Holding Register. - * \{ - */ -#define TWI_RHR_OFF 0x00000030 ///< Receive holding register offset. -#define TWI_RHR (*((reg32_t *)(TWI_BASE + TWI_RHR_OFF))) ///< Receive holding register address. -/*\}*/ - -/** - * TWI Transmit Holding Register. - * \{ - */ -#define TWI_THR_OFF 0x00000034 ///< Transmit holding register offset. -#define TWI_THR (*((reg32_t *)(TWI_BASE + TWI_THR_OFF))) ///< Transmit holding register address. -/*\}*/ - - -#endif /* AT91_TWI_H */ diff --git a/cpu/arm/io/at91_us.h b/cpu/arm/io/at91_us.h deleted file mode 100644 index 20541a76..00000000 --- a/cpu/arm/io/at91_us.h +++ /dev/null @@ -1,344 +0,0 @@ -/** - * \file - * - * - * \version $Id: at91_us.h 20544 2008-02-14 12:15:57Z batt $ - * - * \author Daniele Basile - * - * AT91 UART User interface. - * This file is based on NUT/OS implementation. See license below. - */ -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_US_H -#define AT91_US_H - -/** - * USART Control Register - */ -/*\{*/ -#define US_CR_OFF 0x00000000 ///< USART control register offset. -#define US0_CR (*((reg32_t *)(USART0_BASE + US_CR_OFF))) ///< Channel 0 control register address. -#define US1_CR (*((reg32_t *)(USART1_BASE + US_CR_OFF))) ///< Channel 1 control register address. -#define US_RSTRX 2 ///< Reset receiver. -#define US_RSTTX 3 ///< Reset transmitter. -#define US_RXEN 4 ///< Receiver enable. -#define US_RXDIS 5 ///< Receiver disable. -#define US_TXEN 6 ///< Transmitter enable. -#define US_TXDIS 7 ///< Transmitter disable. -#define US_RSTSTA 8 ///< Reset status bits. -#define US_STTBRK 9 ///< Start break. -#define US_STPBRK 10 ///< Stop break. -#define US_STTTO 11 ///< Start timeout. -#define US_SENDA 12 ///< Send next byte with address bit set. -#define US_RSTIT 13 ///< Reset interations. -#define US_RSTNAK 14 ///< Reset non acknowledge. -#define US_RETTO 15 ///< Rearm time out. -#define US_DTREN 16 ///< Data terminal ready enable. -#define US_DTRDIS 17 ///< Data terminal ready disable. -#define US_RTSEN 18 ///< Request to send enable. -#define US_RTSDIS 19 ///< Request to send disable. -/*\}*/ - -/** - * Mode Register - */ -/*\{*/ -#define US_MR_OFF 0x00000004 ///< USART mode register offset. -#define US0_MR (*((reg32_t *)(USART0_BASE + US_MR_OFF))) ///< Channel 0 mode register address. -#define US1_MR (*((reg32_t *)(USART1_BASE + US_MR_OFF))) ///< Channel 1 mode register address. - -#define US_USART_MODE_MASK 0x0000000F ///< USART mode mask. -#define US_USART_MODE_NORMA 0x00000000 ///< Normal. -#define US_USART_MODE_RS485 0x00000001 ///< RS485. -#define US_USART_MODE_HW_HDSH 0x00000002 ///< Hardware handshaking. -#define US_USART_MODE_MODEM 0x00000003 ///< Modem. -#define US_USART_MODE_ISO7816T0 0x00000004 ///< ISO7816 protocol: T=0. -#define US_USART_MODE_ISO7816T1 0x00000006 ///< ISO7816 protocol: T=1. -#define US_USART_MODE_IRDA 0x00000008 ///< IrDA. - -#define US_CLKS_MASK 0x00000030 ///< Clock selection mask. -#define US_CLKS_MCK 0x00000000 ///< Master clock. -#define US_CLKS_MCK8 0x00000010 ///< Master clock divided by 8. -#define US_CLKS_SCK 0x00000020 ///< External clock. -#define US_CLKS_SLCK 0x00000030 ///< Slow clock. - -#define US_CHRL_MASK 0x000000C0 ///< Masks data length. -#define US_CHRL_5 0x00000000 ///< 5 data bits. -#define US_CHRL_6 0x00000040 ///< 6 data bits. -#define US_CHRL_7 0x00000080 ///< 7 data bits. -#define US_CHRL_8 0x000000C0 ///< 8 data bits. - -#define US_SYNC 8 ///< Synchronous mode enable. - -#define US_PAR_MASK 0x00000E00 ///< Parity mode mask. -#define US_PAR_EVEN 0x00000000 ///< Even parity. -#define US_PAR_ODD 0x00000200 ///< Odd parity. -#define US_PAR_SPACE 0x00000400 ///< Space parity. -#define US_PAR_MARK 0x00000600 ///< Marked parity. -#define US_PAR_NO 0x00000800 ///< No parity. -#define US_PAR_MULTIDROP 0x00000C00 ///< Multi-drop mode. - -#define US_NBSTOP_MASK 0x00003000 ///< Masks stop bit length. -#define US_NBSTOP_1 0x00000000 ///< 1 stop bit. -#define US_NBSTOP_1_5 0x00001000 ///< 1.5 stop bits. -#define US_NBSTOP_2 0x00002000 ///< 2 stop bits. - -#define US_CHMODE_MASK 0x0000C000 ///< Channel mode mask. -#define US_CHMODE_NORMAL 0x00000000 ///< Normal mode. -#define US_CHMODE_AUTOMATIC_ECHO 0x00004000 ///< Automatic echo. -#define US_CHMODE_LOCAL_LOOPBACK 0x00008000 ///< Local loopback. -#define US_CHMODE_REMOTE_LOOPBACK 0x0000C000 ///< Remote loopback. - -#define US_MSBF 16 ///< Bit order. -#define US_MODE9 17 ///< 9 bit mode. -#define US_CLKO 18 ///< Clock output select. -#define US_OVER 19 ///< Oversampling mode. -#define US_INACK 20 ///< Inhibit non acknowledge. -#define US_DSNACK 21 ///< Disable successive nack. - -#define US_MAX_INTERATION_MASK 0x07000000 ///< Max numer of interation in mode ISO7816 T=0. - -#define US_FILTER 28 ///< Infrared receive line filter. - -/*\}*/ - -/** - * Status and Interrupt Register - */ -/*\{*/ -#define US_IER_OFF 0x00000008 ///< USART interrupt enable register offset. -#define US0_IER (*((reg32_t *)(USART0_BASE + US_IER_OFF))) ///< Channel 0 interrupt enable register address. -#define US1_IER (*((reg32_t *)(USART1_BASE + US_IER_OFF))) ///< Channel 1 interrupt enable register address. - -#define US_IDR_OFF 0x0000000C ///< USART interrupt disable register offset. -#define US0_IDR (*((reg32_t *)(USART0_BASE + US_IDR_OFF))) ///< Channel 0 interrupt disable register address. -#define US1_IDR (*((reg32_t *)(USART1_BASE + US_IDR_OFF))) ///< Channel 1 interrupt disable register address. - -#define US_IMR_OFF 0x00000010 ///< USART interrupt mask register offset. -#define US0_IMR (*((reg32_t *)(USART0_BASE + US_IMR_OFF))) ///< Channel 0 interrupt mask register address. -#define US1_IMR (*((reg32_t *)(USART1_BASE + US_IMR_OFF))) ///< Channel 1 interrupt mask register address. - -#define US_CSR_OFF 0x00000014 ///< USART status register offset. -#define US0_CSR (*((reg32_t *)(USART0_BASE + US_CSR_OFF))) ///< Channel 0 status register address. -#define US1_CSR (*((reg32_t *)(USART1_BASE + US_CSR_OFF))) ///< Channel 1 status register address. -#define US_CSR_RI 20 ///< Image of RI input. -#define US_CSR_DSR 21 ///< Image of DSR input. -#define US_CSR_DCD 22 ///< Image of DCD input. -#define US_CSR_CTS 23 ///< Image of CTS input. - -#define US_RXRDY 0 ///< Receiver ready. -#define US_TXRDY 1 ///< Transmitter ready. -#define US_RXBRK 2 ///< Receiver break. -#define US_ENDRX 3 ///< End of receiver PDC transfer. -#define US_ENDTX 4 ///< End of transmitter PDC transfer. -#define US_OVRE 5 ///< Overrun error. -#define US_FRAME 6 ///< Framing error. -#define US_PARE 7 ///< Parity error. -#define US_TIMEOUT 8 ///< Receiver timeout. -#define US_TXEMPTY 9 ///< Transmitter empty. -#define US_ITERATION 10 ///< Iteration interrupt enable. -#define US_TXBUFE 11 ///< Buffer empty interrupt enable. -#define US_RXBUFF 12 ///< Buffer full interrupt enable. -#define US_NACK 13 ///< Non acknowledge interrupt enable. -#define US_RIIC 16 ///< Ring indicator input change enable. -#define US_DSRIC 17 ///< Data set ready input change enable. -#define US_DCDIC 18 ///< Data carrier detect input change interrupt enable. -#define US_CTSIC 19 ///< Clear to send input change interrupt enable. - -/** - * Receiver Holding Register - */ -/*\{*/ -#define US_RHR_OFF 0x00000018 ///< USART receiver holding register offset. -#define US0_RHR (*((reg32_t *)(USART0_BASE + US_RHR_OFF))) ///< Channel 0 receiver holding register address. -#define US1_RHR (*((reg32_t *)(USART1_BASE + US_RHR_OFF))) ///< Channel 1 receiver holding register address. -#define US_RHR_RXCHR_MASK 0x000001FF ///< Last char received if US_RXRDY is set. -#define US_RHR_RXSYNH 15 ///< Received sync. -/*\}*/ - -/** - * Transmitter Holding Register - */ -/*\{*/ -#define US_THR_OFF 0x0000001C ///< USART transmitter holding register offset. -#define US0_THR (*((reg32_t *)(USART0_BASE + US_THR_OFF))) ///< Channel 0 transmitter holding register address. -#define US1_THR (*((reg32_t *)(USART1_BASE + US_THR_OFF))) ///< Channel 1 transmitter holding register address. -#define US_THR_TXCHR_MASK 0x000001FF ///< Next char to be trasmitted. -#define US_THR_TXSYNH 15 ///< Sync field to be trasmitted. -/*\}*/ - -/** - * Baud Rate Generator Register - */ -/*\{*/ -#define US_BRGR_OFF 0x00000020 ///< USART baud rate register offset. -#define US0_BRGR (*((reg32_t *)(USART0_BASE + US_BRGR_OFF))) ///< Channel 0 baud rate register address. -#define US1_BRGR (*((reg32_t *)(USART1_BASE + US_BRGR_OFF))) ///< Channel 1 baud rate register address. -/*\}*/ - -/** - * Receiver Timeout Register - */ -/*\{*/ -#define US_RTOR_OFF 0x00000024 ///< USART receiver timeout register offset. -#define US0_RTOR (*((reg32_t *)(USART0_BASE + US_RTOR_OFF))) ///< Channel 0 receiver timeout register address. -#define US1_RTOR (*((reg32_t *)(USART1_BASE + US_RTOR_OFF))) ///< Channel 1 receiver timeout register address. -/*\}*/ - -/** - * Transmitter Time Guard Register - */ -/*\{*/ -#define US_TTGR_OFF 0x00000028 ///< USART transmitter time guard register offset. -#define US0_TTGR (*((reg32_t *)(USART0_BASE + US_TTGR_OFF))) ///< Channel 0 transmitter time guard register address. -#define US1_TTGR (*((reg32_t *)(USART1_BASE + US_TTGR_OFF))) ///< Channel 1 transmitter time guard register address. -/*\}*/ - -/** - * FI DI Ratio Register -*/ -/*\{*/ -#define US_FIDI_OFF 0x00000040 ///< USART FI DI ratio register offset. -#define US0_FIDI (*((reg32_t *)(USART0_BASE + US_FIDI_OFF))) ///< Channel 0 FI DI ratio register address. -#define US1_FIDI (*((reg32_t *)(USART1_BASE + US_FIDI_OFF))) ///< Channel 1 FI DI ratio register address. -/*\}*/ - -/** - * Error Counter Register - */ -/*\{*/ -#define US_NER_OFF 0x00000044 ///< USART error counter register offset. -#define US0_NER (*((reg32_t *)(USART0_BASE + US_NER_OFF))) ///< Channel 0 error counter register address. -#define US1_NER (*((reg32_t *)(USART1_BASE + US_NER_OFF))) ///< Channel 1 error counter register address. -/*\}*/ - -/** - * IrDA Filter Register - */ -/*\{*/ -#define US_IF_OFF 0x0000004C ///< USART IrDA filter register offset. -#define US0_IF (*((reg32_t *)(USART0_BASE + US_IF_OFF))) ///< Channel 0 IrDA filter register address. -#define US1_IF (*((reg32_t *)(USART1_BASE + US_IF_OFF))) ///< Channel 1 IrDA filter register address. -/*\}*/ - -#if USART_HAS_PDC - - /** - * Receive Pointer Register - */ - /*\{*/ - #define US0_RPR (*((reg32_t *)(USART0_BASE + PERIPH_RPR_OFF))) ///< Channel 0 receive pointer register address. - #define US1_RPR (*((reg32_t *)(USART1_BASE + PERIPH_RPR_OFF))) ///< Channel 1 receive pointer register address. - /*\}*/ - - /** - * Receive Counter Register - */ - /*\{*/ - #define US0_RCR (*((reg32_t *)(USART0_BASE + PERIPH_RCR_OFF))) ///< Channel 0 receive counter register address. - #define US1_RCR (*((reg32_t *)(USART1_BASE + PERIPH_RCR_OFF))) ///< Channel 1 receive counter register address. - /*\}*/ - - /** - * Transmit Pointer Register - */ - /*\{*/ - #define US0_TPR (*((reg32_t *)(USART0_BASE + PERIPH_TPR_OFF))) ///< Channel 0 transmit pointer register address. - #define US1_TPR (*((reg32_t *)(USART1_BASE + PERIPH_TPR_OFF))) ///< Channel 1 transmit pointer register address. - /*\}*/ - - /** - * Transmit Counter Register - */ - /*\{*/ - #define US0_TCR (*((reg32_t *)(USART0_BASE + PERIPH_TCR_OFF))) ///< Channel 0 transmit counter register address. - #define US1_TCR (*((reg32_t *)(USART1_BASE + PERIPH_TCR_OFF))) ///< Channel 1 transmit counter register address. - /*\}*/ - - #if defined(PERIPH_RNPR_OFF) && defined(PERIPH_RNCR_OFF) - #define US0_RNPR (*((reg32_t *)(USART0_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 0 receive next pointer register. - #define US1_RNPR (*((reg32_t *)(USART1_BASE + PERIPH_RNPR_OFF))) ///< PDC channel 1 receive next pointer register. - #define US0_RNCR (*((reg32_t *)(USART0_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 0 receive next counter register. - #define US1_RNCR (*((reg32_t *)(USART1_BASE + PERIPH_RNCR_OFF))) ///< PDC channel 1 receive next counter register. - #endif - - #if defined(PERIPH_TNPR_OFF) && defined(PERIPH_TNCR_OFF) - #define US0_TNPR (*((reg32_t *)(USART0_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 0 transmit next pointer register. - #define US1_TNPR (*((reg32_t *)(USART1_BASE + PERIPH_TNPR_OFF))) ///< PDC channel 1 transmit next pointer register. - #define US0_TNCR (*((reg32_t *)(USART0_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 0 transmit next counter register. - #define US1_TNCR (*((reg32_t *)(USART1_BASE + PERIPH_TNCR_OFF))) ///< PDC channel 1 transmit next counter register. - #endif - - #if defined(PERIPH_PTCR_OFF) - #define US0_PTCR (*((reg32_t *)(USART0_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 0 transfer control register. - #define US1_PTCR (*((reg32_t *)(USART1_BASE + PERIPH_PTCR_OFF))) ///< PDC channel 1 transfer control register. - #endif - - #if defined(PERIPH_PTSR_OFF) - #define US0_PTSR (*((reg32_t *)(USART0_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 0 transfer status register. - #define US1_PTSR (*((reg32_t *)(USART1_BASE + PERIPH_PTSR_OFF))) ///< PDC channel 1 transfer status register. - #endif - -#endif /* USART_HAS_PDC */ - -#endif /* AT91_US_H */ diff --git a/cpu/arm/io/at91_wdt.h b/cpu/arm/io/at91_wdt.h deleted file mode 100644 index ed394665..00000000 --- a/cpu/arm/io/at91_wdt.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * - * AT91 Watchdog. - * This file is based on NUT/OS implementation. See license below. - */ - - -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91_WDT_H -#define AT91_WDT_H - - -/** Watch Dog Control Register */ -/*\{*/ -#define WDT_CR_OFF 0x00000000 ///< Watchdog control register offset. -#define WDT_CR (*((reg32_t *)(WDT_BASE + WDT_CR_OFF))) ///< Watchdog control register address. -#define WDT_WDRSTT 0 ///< Watchdog restart. -#define WDT_KEY 0xA5000000 ///< Watchdog password. -/*\}*/ - -/** Watch Dog Mode Register */ -/*\{*/ -#define WDT_MR_OFF 0x00000004 ///< Mode register offset. -#define WDT_MR (*((reg32_t *)(WDT_BASE + WDT_MR_OFF))) ///< Mode register address. -#define WDT_WDV_MASK 0x00000FFF ///< Counter value mask. -#define WDT_WDV_SHIFT 0 ///< Counter value LSB. -#define WDT_WDFIEN 12 ///< Fault interrupt enable. -#define WDT_WDRSTEN 13 ///< Reset enable. -#define WDT_WDRPROC 14 ///< Eset processor enable. -#define WDT_WDDIS 15 ///< Watchdog disable. -#define WDT_WDD_MASK 0x0FFF0000 ///< Delta value mask. -#define WDT_WDD_SHIFT 16 ///< Delta value LSB. -#define WDT_WDDBGHLT 28 ///< Watchdog debug halt. -#define WDT_WDIDLEHLT 29 ///< Watchdog idle halt. -/*\}*/ - -/** Watch Dog Status Register */ -/*\{*/ -#define WDT_SR_OFF 0x00000008 ///< Status register offset. -#define WDT_SR (*((reg32_t *)(WDT_BASE + WDT_SR_OFF))) ///< Status register address. -#define WDT_WDUNF 0 ///< Watchdog underflow. -#define WDT_WDERR 1 ///< Watchdog error. -/*\}*/ - - -#endif /* AT91_WDT_H */ diff --git a/cpu/arm/io/at91sam7.h b/cpu/arm/io/at91sam7.h deleted file mode 100644 index 978c9e34..00000000 --- a/cpu/arm/io/at91sam7.h +++ /dev/null @@ -1,341 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Francesco Sacchi - * \author Daniele Basile - * - * AT91SAM7 register definitions. - * This file is based on NUT/OS implementation. See license below. - */ - -/* - * Copyright (C) 2006-2007 by egnite Software GmbH. 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 of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE - * SOFTWARE GMBH 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. - * - * For additional information see http://www.ethernut.de/ - */ - -#ifndef AT91SAM7_H -#define AT91SAM7_H - -#include - -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 || CPU_ARM_AT91SAM7S256 - #define FLASH_BASE 0x100000UL - #define RAM_BASE 0x200000UL - - #define TC_BASE 0xFFFA0000 ///< Timer/counter base address. - #define UDP_BASE 0xFFFB0000 ///< USB device port base address. - #define TWI_BASE 0xFFFB8000 ///< Two-wire interface base address. - #define USART0_BASE 0xFFFC0000 ///< USART 0 base address. - #define USART1_BASE 0xFFFC4000 ///< USART 1 base address. - #define PWMC_BASE 0xFFFCC000 ///< PWM controller base address. - #define SSC_BASE 0xFFFD4000 ///< Serial synchronous controller base address. - #define ADC_BASE 0xFFFD8000 ///< ADC base address. - - #define AIC_BASE 0xFFFFF000 ///< AIC base address. - #define DBGU_BASE 0xFFFFF200 ///< DBGU base address. - #define PIOA_BASE 0xFFFFF400 ///< PIO A base address. - #define PMC_BASE 0xFFFFFC00 ///< PMC base address. - #define RSTC_BASE 0xFFFFFD00 ///< Resect controller register base address. - #define RTT_BASE 0xFFFFFD20 ///< Realtime timer base address. - #define PIT_BASE 0xFFFFFD30 ///< Periodic interval timer base address. - #define WDT_BASE 0xFFFFFD40 ///< Watch Dog register base address. - #define VREG_BASE 0xFFFFFD60 ///< Voltage regulator mode controller base address. - #define MC_BASE 0xFFFFFF00 ///< Memory controller base. - - #if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define CAN_BASE 0xFFFD0000 ///< PWM controller base address. - #define EMAC_BASE 0xFFFDC000 ///< Ethernet MAC address. - #define SPI0_BASE 0xFFFE0000 ///< SPI0 base address. - #define SPI1_BASE 0xFFFE4000 ///< SPI1 base address. - #define PIOB_BASE 0xFFFFF600 ///< PIO base address. - #endif - - #if CPU_ARM_AT91SAM7S256 - #define SPI_BASE 0xFFFE0000 ///< SPI0 base address. - #endif - - #define PIO_HAS_MULTIDRIVER 1 - #define PIO_HAS_PULLUP 1 - #define PIO_HAS_PERIPHERALSELECT 1 - #define PIO_HAS_OUTPUTWRITEENABLE 1 - - #define DBGU_HAS_PDC 1 - #define SPI_HAS_PDC 1 - #define SSC_HAS_PDC 1 - #define USART_HAS_PDC 1 - -#else - #error No base addrese register definition for selected ARM CPU - -#endif - -#include "at91_aic.h" -#include "at91_pit.h" -#include "at91_pmc.h" -#include "at91_mc.h" -#include "at91_wdt.h" -#include "at91_rstc.h" -#include "at91_pio.h" -#include "at91_us.h" -#include "at91_dbgu.h" -#include "at91_tc.h" -#include "at91_adc.h" -#include "at91_pwm.h" -#include "at91_spi.h" -#include "at91_twi.h" -//TODO: add other peripherals - -/** - * Peripheral Identifiers and Interrupts - *\{ - */ -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7S256 || CPU_ARM_AT91SAM7X128 - #define FIQ_ID 0 ///< Fast interrupt ID. - #define SYSC_ID 1 ///< System controller interrupt. - #define US0_ID 6 ///< USART 0 ID. - #define US1_ID 7 ///< USART 1 ID. - #define SSC_ID 8 ///< Synchronous serial controller ID. - #define TWI_ID 9 ///< Two-wire interface ID. - #define PWMC_ID 10 ///< PWM controller ID. - #define UDP_ID 11 ///< USB device port ID. - #define TC0_ID 12 ///< Timer 0 ID. - #define TC1_ID 13 ///< Timer 1 ID. - #define TC2_ID 14 ///< Timer 2 ID. - - #define IRQ0_ID 30 ///< External interrupt 0 ID. - #define IRQ1_ID 31 ///< External interrupt 1 ID. - - #if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define PIOA_ID 2 ///< Parallel A I/O controller ID. - #define PIOB_ID 3 ///< Parallel B I/O controller ID. - #define SPI0_ID 4 ///< Serial peripheral interface 0 ID. - #define SPI1_ID 5 ///< Serial peripheral interface 1 ID. - #define CAN_ID 15 ///< CAN controller ID. - #define EMAC_ID 16 ///< Ethernet MAC ID. - #define ADC_ID 17 ///< Analog to digital converter ID. - /* 18-29 Reserved */ - - #endif - - #if CPU_ARM_AT91SAM7S256 - #define PIOA_ID 2 ///< Parallel I/O controller ID. - /* ID 3 is reserved */ - #define ADC_ID 4 ///< Analog to digital converter ID. - #define SPI_ID 5 ///< Serial peripheral interface ID. - #define SPI0_ID SPI_ID ///< Alias - #endif - -#else - #error No peripheral ID and interrupts definition for selected ARM CPU - -#endif -/*\}*/ - -/** - * USART & DEBUG pin names - *\{ - */ -#if CPU_ARM_AT91SAM7S256 - #define RXD0 5 - #define TXD0 6 - #define RXD1 21 - #define TXD1 22 - #define DTXD 10 - #define DRXD 9 -#elif CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define RXD0 0 // PA0 - #define TXD0 1 // PA1 - #define RXD1 5 // PA5 - #define TXD1 6 // PA6 - #define DTXD 28 // PA28 - #define DRXD 27 // PA27 -#else - #error No USART & debug pin names definition for selected ARM CPU -#endif -/*\}*/ - -/** - * SPI pins name - *\{ - */ -#if CPU_ARM_AT91SAM7S256 - #define SPI0_NPCS0 11 // Same as NSS pin. - #define SPI0_MISO 12 - #define SPI0_MOSI 13 - #define SPI0_SPCK 14 - -#elif CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define SPI0_NPCS0 12 // Same as NSS pin. PA12 - #define SPI0_NPCS1 13 // PA13 - #define SPI0_NPCS2 14 // PA14 - #define SPI0_NPCS3 15 // PA15 - #define SPI0_MISO 16 // PA16 - #define SPI0_MOSI 17 // PA17 - #define SPI0_SPCK 18 // PA18 - - #define SPI1_NPCS0 21 // Same as NSS pin. PA21 - #define SPI1_NPCS1 25 // PA25 - #define SPI1_NPCS2 26 // PA26 - #define SPI1_NPCS3 29 // PA29 - #define SPI1_MISO 24 // PA24 - #define SPI1_MOSI 23 // PA23 - #define SPI1_SPCK 22 // PA22 - -#else - #error No SPI pins name definition for selected ARM CPU - -#endif -/*\}*/ - -/** - * Timer counter pins definition. - *\{ - */ -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define TIOA0 23 // PB23 - #define TIOB0 24 // PB24 - #define TIOA1 25 // PB25 - #define TIOB1 26 // PB26 - #define TIOA2 27 // PB27 - #define TIOB2 28 // PB28 - -#elif CPU_ARM_AT91SAM7S256 - #define TIOA0 0 // PA0 - #define TIOB0 1 // PA1 - #define TIOA1 15 // PA15 - #define TIOB1 16 // PA16 - #define TIOA2 26 // PA26 - #define TIOB2 27 // PA27 - -#else - #error No Timer Conter pins name definition for selected ARM CPU - -#endif -/*\}*/ - -/** - * PWM pins definition. - *\{ - */ -#define PWM_PIO_FUNCTION_A 1 - -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #if PWM_PIO_FUNCTION_A - #define PWM0 19 // PB19 - #define PWM1 20 // PB20 - #define PWM2 21 // PB21 - #define PWM3 22 // PB22 - #else - #define PWM0 27 // PB27 - #define PWM1 28 // PB28 - #define PWM2 29 // PB29 - #define PWM3 30 // PB30 - #endif - - -#elif CPU_ARM_AT91SAM7S256 - #define PWM0 11 // PA11 - #define PWM1 12 // PA12 - #define PWM2 13 // PA13 - #define PWM3 14 // PA14 - -#else - #error No PWM pins name definition for selected ARM CPU - -#endif -/*\}*/ - -/** - * TWI pins definition. - *\{ - */ -#if CPU_ARM_AT91SAM7X256 || CPU_ARM_AT91SAM7X128 - #define TWD 10 - #define TWCK 11 -#else - #error No TWI pin names definition for selected ARM CPU -#endif - -/** - * ADC pins definition. - *\{ - */ -#if CPU_ARM_AT91SAM7X256 - #define ADTRG 18 // PB18 - #define AD0 23 // PB27 - #define AD1 24 // PB28 - #define AD2 25 // PB29 - #define AD3 26 // PB30 - -#elif CPU_ARM_AT91SAM7S256 - #define ADTRG 18 // PA8 - #define AD0 0 // PA17 - #define AD1 1 // PA18 - #define AD2 15 // PA19 - #define AD3 16 // PA20 - -#else - #error No Timer Conter pin names definition for selected ARM CPU - -#endif -/*\}*/ - -#endif /* AT91SAM7_H */ diff --git a/cpu/arm/scripts/at91sam7_256_ram.ld b/cpu/arm/scripts/at91sam7_256_ram.ld deleted file mode 100644 index 40c07c95..00000000 --- a/cpu/arm/scripts/at91sam7_256_ram.ld +++ /dev/null @@ -1,143 +0,0 @@ -/** - * \file - * - * - * \version $Id: sysirq_at91.c 18273 2007-10-11 14:53:02Z batt $ - * - * \author Daniele Basile - * - * \brief Script linker for Atmel AT91SAM7_256 family processors. - * - */ - - -ENTRY(_init) -SEARCH_DIR(.) -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) - -/* - * Define memory configuration for AT91SAM7_256 family - */ -MEMORY -{ - rom(rx) : org = 0x00100000, len = 256k - ram(rwx) : org = 0x00200000, len = 64k -} - - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * Allocate section memory - */ -SECTIONS -{ - .text : - { - KEEP(*(.vectors)); - . = ALIGN (4); - KEEP(*(.init)); - . = ALIGN (4); - *(.rodata .rodata.*); - . = ALIGN (4); - *(.text .text.*); - . = ALIGN (4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - } > ram - - _etext = .; - PROVIDE (__etext = .); - - .data : AT (__etext) - { - PROVIDE (__data_start = .); - *(.data .data.*) - . = ALIGN (4); - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss .bss.*) - . = ALIGN(4); - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - } > ram - - /* - * Allocated stack at the end of bss section. - * Data heap is allocate at end of stack. - */ - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - - PROVIDE (__stack_end = .); - - PROVIDE (__heap_start = .); -} diff --git a/cpu/arm/scripts/at91sam7_256_rom.ld b/cpu/arm/scripts/at91sam7_256_rom.ld deleted file mode 100644 index 815aa423..00000000 --- a/cpu/arm/scripts/at91sam7_256_rom.ld +++ /dev/null @@ -1,143 +0,0 @@ -/** - * \file - * - * - * \version $Id: sysirq_at91.c 18273 2007-10-11 14:53:02Z batt $ - * - * \author Daniele Basile - * - * \brief Script linker for Atmel AT91SAM7_256 family processors. - * - */ - - -ENTRY(_init) -SEARCH_DIR(.) -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) - -/* - * Define memory configuration for AT91SAM7_256 family - */ -MEMORY -{ - rom(rx) : org = 0x00100000, len = 256k - ram(rwx) : org = 0x00200000, len = 64k -} - - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * Allocate section memory - */ -SECTIONS -{ - .text : - { - KEEP(*(.vectors)); - . = ALIGN (4); - KEEP(*(.init)); - . = ALIGN (4); - *(.rodata .rodata.*); - . = ALIGN (4); - *(.text .text.*); - . = ALIGN (4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - } > rom - - _etext = .; - PROVIDE (__etext = .); - - .data : AT (__etext) - { - PROVIDE (__data_start = .); - *(.data .data.*) - . = ALIGN (4); - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss .bss.*) - . = ALIGN(4); - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - } > ram - - /* - * Allocated stack at the end of bss section. - * Data heap is allocate at end of stack. - */ - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - - PROVIDE (__stack_end = .); - - PROVIDE (__heap_start = .); -} diff --git a/cpu/arm/scripts/at91sam7_ram.gdb b/cpu/arm/scripts/at91sam7_ram.gdb deleted file mode 100644 index a5006bd9..00000000 --- a/cpu/arm/scripts/at91sam7_ram.gdb +++ /dev/null @@ -1,36 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -#monitor arm7_9 force_hw_bkpts enable -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -#Remap RAM to address 0 -monitor mww 0xFFFFFF00 0x00000001 -monitor sleep 100 - -break main -load -continue diff --git a/cpu/arm/scripts/at91sam7_rom.gdb b/cpu/arm/scripts/at91sam7_rom.gdb deleted file mode 100644 index dcecec96..00000000 --- a/cpu/arm/scripts/at91sam7_rom.gdb +++ /dev/null @@ -1,36 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -#monitor arm7_9 sw_bkpts enable -monitor arm7_9 force_hw_bkpts enable -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -#Remap RAM to address 0 -#monitor mww 0xFFFFFF00 0x00000001 -#monitor sleep 100 - -break main -load -continue diff --git a/cpu/arm/scripts/openocd_at91sam7_flash.script b/cpu/arm/scripts/openocd_at91sam7_flash.script deleted file mode 100644 index 98e93821..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_flash.script +++ /dev/null @@ -1,38 +0,0 @@ -# -# The following command wills be executed on -# reset (because of run_and_init in the config-file) -# - halt target -# - init ecr -# - flash content of file main.bin into target-memory -# - shutdown openocd -# -# created by Martin Thomas -# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects -# based on information from Dominic Rath -# - -halt -sleep 10 - -# Init - taken form the script openocd_at91sam7_ecr.script -mww 0xfffffd44 0x00008000 # disable watchdog -mww 0xfffffd08 0xa5000001 # enable user reset -mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator -sleep 10 -mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz -sleep 10 -mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz -sleep 10 -mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) -# arm7_9 force_hw_bkpts enable # program resides in flash - -# AT91SAM7 flash command-"batch" -# adapted by Martin Thomas based on information from Dominic Rath - Thanks -arm7_9 dcc_downloads enable -sleep 10 -poll -flash probe 0 -flash write 0 ../../../images/at91sam7.bin 0x0 -reset run -sleep 10 -#shutdown diff --git a/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg b/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg deleted file mode 100644 index b8f7ba16..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_ftdi_ram.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# -# Flash AT91SAM7S memory using openocd -# and a FTDI FT2232-based JTAG-interface -# -# created by Martin Thomas -# based on information from Dominic Rath -# - -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag_device 4 0x1 0xf 0xe - -#target configuration -daemon_startup reset - -#target -#target arm7tdmi -target arm7tdmi little run_and_init 0 arm7tdmi -run_and_halt_time 0 30 - -# flash-options AT91 -target_script 0 reset openocd_at91sam7_reset.script -working_area 0 0x00200000 0x10000 nobackup -flash bank at91sam7 0 0 0 0 0 - -# Information: -# erase command (telnet-interface) for complete flash: -# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) -# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 -# set/clear NVM-Bits: -# at91sam7 gpnvm -# disable locking from SAM-BA -# flash protect 0 0 1 off - -# For more information about the configuration files, take a look at: -# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg b/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg deleted file mode 100755 index 2c52f8ef..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_ftdi_ram_win.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# -# Flash AT91SAM7S memory using openocd -# and a FTDI FT2232-based JTAG-interface -# -# created by Martin Thomas -# based on information from Dominic Rath -# - -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag_device 4 0x1 0xf 0xe - -#target configuration -daemon_startup reset - -#target -#target arm7tdmi -target arm7tdmi little run_and_init 0 arm7tdmi -run_and_halt_time 0 30 - -# flash-options AT91 -target_script 0 reset openocd_at91sam7_reset.script -working_area 0 0x00200000 0x10000 nobackup -flash bank at91sam7 0 0 0 0 0 - -# Information: -# erase command (telnet-interface) for complete flash: -# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) -# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 -# set/clear NVM-Bits: -# at91sam7 gpnvm -# disable locking from SAM-BA -# flash protect 0 0 1 off - -# For more information about the configuration files, take a look at: -# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg b/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg deleted file mode 100644 index bb0602a1..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_ftdi_rom.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# -# Flash AT91SAM7S memory using openocd -# and a FTDI FT2232-based JTAG-interface -# -# created by Martin Thomas -# based on information from Dominic Rath -# - -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag_device 4 0x1 0xf 0xe - -#target configuration -daemon_startup reset - -#target -#target arm7tdmi -target arm7tdmi little run_and_init 0 arm7tdmi -run_and_halt_time 0 30 - -# flash-options AT91 -target_script 0 reset openocd_at91sam7_flash.script -working_area 0 0x00100000 0x40000 nobackup -flash bank at91sam7 0 0 0 0 0 - -# Information: -# erase command (telnet-interface) for complete flash: -# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) -# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 -# set/clear NVM-Bits: -# at91sam7 gpnvm -# disable locking from SAM-BA -# flash protect 0 0 1 off - -# For more information about the configuration files, take a look at: -# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg b/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg deleted file mode 100755 index 31ad4c86..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_ftdi_rom_win.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# -# Flash AT91SAM7S memory using openocd -# and a FTDI FT2232-based JTAG-interface -# -# created by Martin Thomas -# based on information from Dominic Rath -# - -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag_device 4 0x1 0xf 0xe - -#target configuration -daemon_startup reset - -#target -#target arm7tdmi -target arm7tdmi little run_and_init 0 arm7tdmi -run_and_halt_time 0 30 - -# flash-options AT91 -target_script 0 reset openocd_at91sam7_flash.script -working_area 0 0x00100000 0x40000 nobackup -flash bank at91sam7 0 0 0 0 0 - -# Information: -# erase command (telnet-interface) for complete flash: -# flash erase 0 numlockbits-1 (can be seen from output of flash info 0) -# SAM7S64 with 16 lockbits and bank 0: flash erase 0 0 15 -# set/clear NVM-Bits: -# at91sam7 gpnvm -# disable locking from SAM-BA -# flash protect 0 0 1 off - -# For more information about the configuration files, take a look at: -# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger diff --git a/cpu/arm/scripts/openocd_at91sam7_reset.script b/cpu/arm/scripts/openocd_at91sam7_reset.script deleted file mode 100644 index ff609b01..00000000 --- a/cpu/arm/scripts/openocd_at91sam7_reset.script +++ /dev/null @@ -1,17 +0,0 @@ -# -# Init - taken form the script openocd_at91sam7_ecr.script -# -# I take this script from the following page: -# -# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html -# -mww 0xfffffd44 0x00008000 # disable watchdog -mww 0xfffffd08 0xa5000001 # enable user reset -mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator -sleep 10 -mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz -sleep 10 -mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz -sleep 10 -mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) -sleep 100 diff --git a/cpu/arm/scripts/openocd_ram.bat b/cpu/arm/scripts/openocd_ram.bat deleted file mode 100755 index d17124f7..00000000 --- a/cpu/arm/scripts/openocd_ram.bat +++ /dev/null @@ -1 +0,0 @@ -openocd-ftd2xx.exe -f openocd_at91sam7_ftdi_ram_win.cfg diff --git a/cpu/arm/scripts/openocd_rom.bat b/cpu/arm/scripts/openocd_rom.bat deleted file mode 100755 index d9e6b251..00000000 --- a/cpu/arm/scripts/openocd_rom.bat +++ /dev/null @@ -1 +0,0 @@ -openocd-ftd2xx.exe -f openocd_at91sam7_ftdi_rom_win.cfg diff --git a/cpu/attr.h b/cpu/attr.h deleted file mode 100644 index ce6e4ae3..00000000 --- a/cpu/attr.h +++ /dev/null @@ -1,350 +0,0 @@ -/** - * \file - * - * - * \brief CPU-specific attributes. - * - * \author Giovanni Bajo - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * \author Francesco Sacchi - */ -#ifndef CPU_ATTR_H -#define CPU_ATTR_H - -#include "detect.h" -#include /* for uintXX_t */ -#include /* ARCH_EMUL */ - -#include "appconfig.h" // CONFIG_FAST_MEM - -/** - * \name Macros for determining CPU endianness. - * \{ - */ -#define CPU_BIG_ENDIAN 0x1234 -#define CPU_LITTLE_ENDIAN 0x3412 /* Look twice, pal. This is not a bug. */ -/*\}*/ - -/** Macro to include cpu-specific versions of the headers. */ -#define CPU_HEADER(module) PP_STRINGIZE(drv/PP_CAT3(module, _, CPU_ID).h) - -/** Macro to include cpu-specific versions of implementation files. */ -#define CPU_CSOURCE(module) PP_STRINGIZE(drv/PP_CAT3(module, _, CPU_ID).c) - - -#if CPU_I196 - - #define NOP nop_instruction() - - #define CPU_REG_BITS 16 - #define CPU_REGS_CNT 16 - #define CPU_STACK_GROWS_UPWARD 0 - #define CPU_SP_ON_EMPTY_SLOT 0 - #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN - #define CPU_HARVARD 0 - -#elif CPU_X86 - - #define NOP asm volatile ("nop") - - #define CPU_REGS_CNT 7 - #define CPU_SAVED_REGS_CNT 7 - #define CPU_STACK_GROWS_UPWARD 0 - #define CPU_SP_ON_EMPTY_SLOT 0 - #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN - #define CPU_HARVARD 0 - - #if CPU_X86_64 - #define CPU_REG_BITS 64 - - #ifdef __WIN64__ - /* WIN64 is an IL32-P64 weirdo. */ - #define SIZEOF_LONG 4 - #endif - #else - #define CPU_REG_BITS 32 - #endif - -#elif CPU_ARM - - /* Register counts include SREG too */ - #define CPU_REG_BITS 32 - #define CPU_REGS_CNT 16 - #define CPU_SAVED_REGS_CNT 9 - #define CPU_STACK_GROWS_UPWARD 0 - #define CPU_SP_ON_EMPTY_SLOT 0 - #define CPU_HARVARD 0 - - #ifdef __IAR_SYSTEMS_ICC__ - #warning Check CPU_BYTE_ORDER - #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN) - - #define NOP __no_operation() - - #else /* GCC and compatibles */ - - #if defined(__ARMEB__) - #define CPU_BYTE_ORDER CPU_BIG_ENDIAN - #elif defined(__ARMEL__) - #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN - #else - #error Unable to detect ARM endianness! - #endif - - #define NOP asm volatile ("mov r0,r0" ::) - - /** - * Initialization value for registers in stack frame. - * The register index is not directly corrispondent to CPU - * register numbers, but is related to how are pushed to - * stack (\see asm_switch_context). - * Index (CPU_SAVED_REGS_CNT - 1) is the CPSR register, - * the initial value is set to: - * - All flags (N, Z, C, V) set to 0. - * - IRQ and FIQ enabled. - * - ARM state. - * - CPU in Supervisor Mode (SVC). - */ - #define CPU_REG_INIT_VALUE(reg) (reg == (CPU_SAVED_REGS_CNT - 1) ? 0x13 : 0) - - #if CONFIG_FAST_MEM - /** - * Function attribute for use with performance critical code. - * - * On the AT91 family, code residing in flash has wait states. - * Moving functions to the data section is a quick & dirty way - * to get them transparently copied to SRAM for zero-wait-state - * operation. - */ - #define FAST_FUNC __attribute__((section(".data"))) - - /** - * Data attribute to move constant data to fast memory storage. - * - * \see FAST_FUNC - */ - #define FAST_RODATA __attribute__((section(".data"))) - - #else // !CONFIG_FAST_MEM - #define FAST_RODATA /**/ - #define FAST_FUNC /**/ - #endif - - /** - * Function attribute to declare an interrupt service routine. - */ - #define ISR_FUNC __attribute__((interrupt)) - - #endif /* !__IAR_SYSTEMS_ICC_ */ - -#elif CPU_PPC - #define NOP asm volatile ("nop" ::) - - /* Register counts include SREG too */ - #define CPU_REG_BITS (CPU_PPC32 ? 32 : 64) - #define CPU_REGS_CNT FIXME - #define CPU_SAVED_REGS_CNT FIXME - #define CPU_STACK_GROWS_UPWARD 0 //FIXME - #define CPU_SP_ON_EMPTY_SLOT 0 //FIXME - #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN) - #define CPU_HARVARD 0 - -#elif CPU_DSP56K - - #define NOP asm(nop) - - #define CPU_REG_BITS 16 - #define CPU_REGS_CNT FIXME - #define CPU_SAVED_REGS_CNT 8 - #define CPU_STACK_GROWS_UPWARD 1 - #define CPU_SP_ON_EMPTY_SLOT 0 - #define CPU_BYTE_ORDER CPU_BIG_ENDIAN - #define CPU_HARVARD 1 - - /* Memory is word-addessed in the DSP56K */ - #define CPU_BITS_PER_CHAR 16 - #define SIZEOF_SHORT 1 - #define SIZEOF_INT 1 - #define SIZEOF_LONG 2 - #define SIZEOF_PTR 1 - -#elif CPU_AVR - - #define NOP asm volatile ("nop" ::) - - /* Register counts include SREG too */ - #define CPU_REG_BITS 8 - #define CPU_REGS_CNT 33 - #define CPU_SAVED_REGS_CNT 19 - #define CPU_STACK_GROWS_UPWARD 0 - #define CPU_SP_ON_EMPTY_SLOT 1 - #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN - #define CPU_HARVARD 1 - - /** - * Initialization value for registers in stack frame. - * The register index is not directly corrispondent to CPU - * register numbers. Index 0 is the SREG register: the initial - * value is all 0 but the interrupt bit (bit 7). - */ - #define CPU_REG_INIT_VALUE(reg) (reg == 0 ? 0x80 : 0) - -#else - #error No CPU_... defined. -#endif - -/// Default for macro not defined in the right arch section -#ifndef CPU_REG_INIT_VALUE - #define CPU_REG_INIT_VALUE(reg) 0 -#endif - - -#ifndef CPU_STACK_GROWS_UPWARD - #error CPU_STACK_GROWS_UPWARD should have been defined to either 0 or 1 -#endif - -#ifndef CPU_SP_ON_EMPTY_SLOT - #error CPU_SP_ON_EMPTY_SLOT should have been defined to either 0 or 1 -#endif - -/* - * Support stack handling peculiarities of a few CPUs. - * - * Most processors let their stack grow downward and - * keep SP pointing at the last pushed value. - */ -#if !CPU_STACK_GROWS_UPWARD - #if !CPU_SP_ON_EMPTY_SLOT - /* Most microprocessors (x86, m68k...) */ - #define CPU_PUSH_WORD(sp, data) \ - do { *--(sp) = (data); } while (0) - #define CPU_POP_WORD(sp) \ - (*(sp)++) - #else - /* AVR insanity */ - #define CPU_PUSH_WORD(sp, data) \ - do { *(sp)-- = (data); } while (0) - #define CPU_POP_WORD(sp) \ - (*++(sp)) - #endif - -#else /* CPU_STACK_GROWS_UPWARD */ - - #if !CPU_SP_ON_EMPTY_SLOT - /* DSP56K and other weirdos */ - #define CPU_PUSH_WORD(sp, data) \ - do { *++(sp) = (cpustack_t)(data); } while (0) - #define CPU_POP_WORD(sp) \ - (*(sp)--) - #else - #error I bet you cannot find a CPU like this - #endif -#endif - - -#if CPU_DSP56K - /* - * DSP56k pushes both PC and SR to the stack in the JSR instruction, but - * RTS discards SR while returning (it does not restore it). So we push - * 0 to fake the same context. - */ - #define CPU_PUSH_CALL_CONTEXT(sp, func) \ - do { \ - CPU_PUSH_WORD((sp), (func)); \ - CPU_PUSH_WORD((sp), 0x100); \ - } while (0); - -#elif CPU_AVR - /* - * In AVR, the addresses are pushed into the stack as little-endian, while - * memory accesses are big-endian (actually, it's a 8-bit CPU, so there is - * no natural endianess). - */ - #define CPU_PUSH_CALL_CONTEXT(sp, func) \ - do { \ - uint16_t funcaddr = (uint16_t)(func); \ - CPU_PUSH_WORD((sp), funcaddr); \ - CPU_PUSH_WORD((sp), funcaddr>>8); \ - } while (0) - - /* - * If the kernel is in idle-spinning, the processor executes: - * - * IRQ_ENABLE; - * CPU_IDLE; - * IRQ_DISABLE; - * - * IRQ_ENABLE is translated in asm as "sei" and IRQ_DISABLE as "cli". - * We could define CPU_IDLE to expand to none, so the resulting - * asm code would be: - * - * sei; - * cli; - * - * But Atmel datasheet states: - * "When using the SEI instruction to enable interrupts, - * the instruction following SEI will be executed *before* - * any pending interrupts", so "cli" is executed before any - * pending interrupt with the result that IRQs will *NOT* - * be enabled! - * To ensure that IRQ will run a NOP is required. - */ - #define CPU_IDLE NOP - -#else - #define CPU_PUSH_CALL_CONTEXT(sp, func) \ - CPU_PUSH_WORD((sp), (cpustack_t)(func)) -#endif - -/** - * \def CPU_IDLE - * - * \brief Invoked by the scheduler to stop the CPU when idle. - * - * This hook can be redefined to put the CPU in low-power mode, or to - * profile system load with an external strobe, or to save CPU cycles - * in hosted environments such as emulators. - */ -#ifndef CPU_IDLE - #if defined(ARCH_EMUL) && (ARCH & ARCH_EMUL) - /* This emulator hook should yield the CPU to the host. */ - EXTERN_C_BEGIN - void emul_idle(void); - EXTERN_C_END - #define CPU_IDLE emul_idle() - #else /* !ARCH_EMUL */ - #define CPU_IDLE do { /* nothing */ } while (0) - #endif /* !ARCH_EMUL */ -#endif /* !CPU_IDLE */ - -#endif /* CPU_ATTR_H */ diff --git a/cpu/avr/drv/adc_avr.c b/cpu/avr/drv/adc_avr.c deleted file mode 100644 index e57b04bf..00000000 --- a/cpu/avr/drv/adc_avr.c +++ /dev/null @@ -1,153 +0,0 @@ -/*! - * \file - * - * - * \version $Id$ - * - * \brief ADC hardware-specific definition - * - * \version $Id$ - * \author Francesco Sacchi - */ - -#include "adc_avr.h" - -#include -#include - -#include -#include - -#include -#include - -#define ADC_AVR_AREF 0 -#define ADC_AVR_AVCC 1 -#define ADC_AVR_INT256 2 - -#if CONFIG_KERNEL - #include - #include - #include - #include - - - #if !CONFIG_KERN_SIGNALS - #error Signals must be active to use ADC with kernel - #endif - - /* Signal adc convertion end */ - #define SIG_ADC_COMPLETE SIG_SINGLE - - /* ADC waiting process */ - static struct Process *adc_process; - - /** - * ADC ISR. - * Simply signal the adc process that convertion is complete. - */ - ISR(ADC_vect) - { - sig_signal(adc_process, SIG_ADC_COMPLETE); - } -#endif /* CONFIG_KERNEL */ - -/** - * Select mux channel \a ch. - * \todo only first 8 channels are selectable! - */ -INLINE void adc_hw_select_ch(uint8_t ch) -{ - /* Set to 0 all mux registers */ - ADMUX &= ~(BV(MUX3) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0)); - - /* Select channel, only first 8 channel modes are supported for now */ - ADMUX |= (ch & 0x07); -} - - -/** - * Start an ADC convertion. - * If a kernel is present, preempt until convertion is complete, otherwise - * a busy wait on ADCS bit is done. - */ -INLINE uint16_t adc_hw_read(void) -{ - // Ensure another convertion is not running. - ASSERT(!(ADCSRA & BV(ADSC))); - - // Start convertion - ADCSRA |= BV(ADSC); - - #if CONFIG_KERNEL - // Ensure IRQs enabled. - ASSERT(IRQ_ENABLED()); - adc_process = proc_current(); - sig_wait(SIG_ADC_COMPLETE); - #else - //Wait in polling until is done - while (ADCSRA & BV(ADSC)) ; - #endif - - return(ADC); -} - -/** - * Init ADC hardware. - */ -INLINE void adc_hw_init(void) -{ - /* - * Select channel 0 as default, - * result right adjusted. - */ - ADMUX = 0; - - #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF - /* External voltage at AREF as analog ref source */ - /* None */ - #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC - /* AVCC as analog ref source */ - ADMUX |= BV(REFS0); - #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256 - /* Internal 2.56V as ref source */ - ADMUX |= BV(REFS1) | BV(REFS0); - #else - #error Unsupported ADC ref value. - #endif - - /* Disable Auto trigger source: ADC in Free running mode. */ - ADCSRB = 0; - - /* Enable ADC, disable autotrigger mode. */ - ADCSRA = BV(ADEN); - - #if CONFIG_KERNEL - MOD_CHECK(proc); - ADCSRA |= BV(ADIE); - #endif - - /* Set convertion frequency */ - #if CONFIG_ADC_AVR_DIVISOR == 2 - ADCSRA |= BV(ADPS0); - #elif CONFIG_ADC_AVR_DIVISOR == 4 - ADCSRA |= BV(ADPS1); - #elif CONFIG_ADC_AVR_DIVISOR == 8 - ADCSRA |= BV(ADPS1) | BV(ADPS0); - #elif CONFIG_ADC_AVR_DIVISOR == 16 - ADCSRA |= BV(ADPS2); - #elif CONFIG_ADC_AVR_DIVISOR == 32 - ADCSRA |= BV(ADPS2) | BV(ADPS0); - #elif CONFIG_ADC_AVR_DIVISOR == 64 - ADCSRA |= BV(ADPS2) | BV(ADPS1); - #elif CONFIG_ADC_AVR_DIVISOR == 128 - ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0); - #else - #error Unsupported ADC prescaler value. - #endif - - /* Start a convertion to init ADC hw */ - adc_hw_read(); -} diff --git a/cpu/avr/drv/adc_avr.h b/cpu/avr/drv/adc_avr.h deleted file mode 100644 index ddd2ce72..00000000 --- a/cpu/avr/drv/adc_avr.h +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * \file - * - * - * \version $Id$ - * - * \brief ADC hardware-specific definition - * - * \version $Id$ - * \author Francesco Sacchi - */ - -#ifndef DRV_ADC_AVR_H -#define DRV_ADC_AVR_H - -#define ADC_MUX_MAXCH 7 -#define ADC_BITS 10 - -#endif /* DRV_ADC_AVR_H */ diff --git a/cpu/avr/drv/flash_avr.c b/cpu/avr/drv/flash_avr.c deleted file mode 100644 index b461d95d..00000000 --- a/cpu/avr/drv/flash_avr.c +++ /dev/null @@ -1,296 +0,0 @@ -/** - * \file - * - * - * \brief Self programming routines. - * - * \version $Id$ - * \author Francesco Sacchi - * \author Daniele Basile - * - * This module implements a kfile-like access for Atmel avr - * internal flash. - * Internal flash writing access is controlled by BOOTSZ fuses, check - * datasheet for details. - */ - -#include "flash_avr.h" - -#include -#include -#include - -#include // MIN() -#include -#include -#include - -#include - -#include - -#include - -/** - * Definition of type for avr flash module. - */ -typedef uint16_t avr_page_addr_t; -typedef uint16_t avr_page_t; - -/** - * Temporary buffer cointaing data block to - * write on flash. - */ -static uint8_t page_buf[SPM_PAGESIZE]; - -/** - * Flag for checking if current page is modified. - */ -bool page_modified; - -/** - * Current buffered page. - */ -static avr_page_t curr_page = 0; - -/* - * Private avr flush funtion. - * - * Write current buffered page in flash memory (if modified). - * This function erase flash memory page before writing. - * - * This function is only use internaly in this module. - */ -static void flash_avr_flush(void) -{ - if (page_modified) - { - kprintf("Flushing page %d\n", curr_page); - - // Wait while the SPM instruction is busy. - boot_spm_busy_wait(); - - kprintf("Filling temparary page buffer..."); - - // Fill the temporary buffer of the AVR - for (avr_page_addr_t page_addr = 0; page_addr < SPM_PAGESIZE; page_addr += 2) - { - uint16_t word = ((uint16_t)page_buf[page_addr + 1] << 8) | page_buf[page_addr]; - - ATOMIC(boot_page_fill(page_addr, word)); - } - kprintf("Done.\n"); - - wdt_reset(); - - kprintf("Erasing page, addr %u...", curr_page * SPM_PAGESIZE); - - /* Page erase */ - ATOMIC(boot_page_erase(curr_page * SPM_PAGESIZE)); - - /* Wait until the memory is erased. */ - boot_spm_busy_wait(); - - kprintf("Done.\n"); - kprintf("Writing page, addr %u...", curr_page * SPM_PAGESIZE); - - /* Store buffer in flash page. */ - ATOMIC(boot_page_write(curr_page * SPM_PAGESIZE)); - boot_spm_busy_wait(); // Wait while the SPM instruction is busy. - - /* - * Reenable RWW-section again. We need this if we want to jump back - * to the application after bootloading. - */ - ATOMIC(boot_rww_enable()); - - page_modified = false; - kprintf("Done.\n"); - } -} - - -/** - * Flush avr flash function. - * - * Write current buffered page in flash memory (if modified). - * This function erase flash memory page before writing. - */ -static int flash_avr_kfileFlush(struct KFile * fd) -{ - KFILE_ASSERT_GENERIC(fd); - (void)fd; - flash_avr_flush(); - return 0; -} - - -/** - * Check current page and if \a page is different, load it in - * temporary buffer. - */ -static void flash_avr_loadPage(avr_page_t page) -{ - if (page != curr_page) - { - flash_avr_flush(); - // Load page - memcpy_P(page_buf, (const char *)(page * SPM_PAGESIZE), SPM_PAGESIZE); - curr_page = page; - kprintf("Loaded page %d\n", curr_page); - } -} - -/** - * Write program memory. - * Write \a size bytes from buffer \a _buf to file \a fd - * \note Write operations are buffered. - */ -static size_t flash_avr_write(struct KFile *fd, const void *_buf, size_t size) -{ - KFILE_ASSERT_GENERIC(fd); - const uint8_t *buf =(const uint8_t *)_buf; - - avr_page_t page; - avr_page_addr_t page_addr; - size_t total_write = 0; - - ASSERT(fd->seek_pos + size <= fd->size); - size = MIN((uint32_t)size, fd->size - fd->seek_pos); - - kprintf("Writing at pos[%u]\n", fd->seek_pos); - while (size) - { - page = fd->seek_pos / SPM_PAGESIZE; - page_addr = fd->seek_pos % SPM_PAGESIZE; - - flash_avr_loadPage(page); - - size_t wr_len = MIN(size, SPM_PAGESIZE - page_addr); - memcpy(page_buf + page_addr, buf, wr_len); - page_modified = true; - - buf += wr_len; - fd->seek_pos += wr_len; - size -= wr_len; - total_write += wr_len; - } - kprintf("written %u bytes\n", total_write); - return total_write; -} - -/** - * Open flash file \a fd - * \a name and \a mode are unused, cause flash memory is - * threated like one file. - */ -static void flash_avr_open(struct KFile *fd) -{ - KFILE_ASSERT_GENERIC(fd); - curr_page = 0; - memcpy_P(page_buf, (const char *)(curr_page * SPM_PAGESIZE), SPM_PAGESIZE); - - fd->seek_pos = 0; - fd->size = (uint16_t)(FLASHEND - CONFIG_BOOT_SIZE + 1); - page_modified = false; - - kprintf("Flash file opened\n"); -} - -/** - * Close file \a fd - */ -static int flash_avr_close(UNUSED_ARG(struct KFile *,fd)) -{ - KFILE_ASSERT_GENERIC(fd); - flash_avr_flush(); - kprintf("Flash file closed\n"); - return 0; -} - -/** - * Reopen file \a fd - */ -static struct KFile *flash_avr_reopen(struct KFile *fd) -{ - KFILE_ASSERT_GENERIC(fd); - flash_avr_close(fd); - flash_avr_open(fd); - return fd; -} - - -/** - * Read from file \a fd \a size bytes and put it in buffer \a buf - * \return the number of bytes read. - */ -static size_t flash_avr_read(struct KFile *fd, void *buf, size_t size) -{ - KFILE_ASSERT_GENERIC(fd); - ASSERT(fd->seek_pos + size <= fd->size); - size = MIN((uint32_t)size, fd->size - fd->seek_pos); - - kprintf("Reading at pos[%u]\n", fd->seek_pos); - // Flush current buffered page (if modified). - flash_avr_flush(); - - /* - * AVR pointers are 16 bits wide, this hack is needed to avoid - * compiler warning, cause fd->seek_pos is a 32bit offset. - */ - const uint8_t *pgm_addr = (const uint8_t *)0; - pgm_addr += fd->seek_pos; - - memcpy_P(buf, pgm_addr, size); - fd->seek_pos += size; - kprintf("Read %u bytes\n", size); - return size; -} - -/** - * Init AVR flash read/write file. - */ -void flash_avr_init(struct KFile *fd) -{ - memset(fd, 0, sizeof(*fd)); - DB(fd->_type = KFT_GENERIC); - - // Set up flash programming functions. - fd->reopen = flash_avr_reopen; - fd->close = flash_avr_close; - fd->read = flash_avr_read; - fd->write = flash_avr_write; - fd->seek = kfile_genericSeek; - fd->flush = flash_avr_kfileFlush; - - flash_avr_open(fd); -} - diff --git a/cpu/avr/drv/flash_avr.h b/cpu/avr/drv/flash_avr.h deleted file mode 100644 index 7b4317d9..00000000 --- a/cpu/avr/drv/flash_avr.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * \file - * - * - * \brief Self programming routines (interface). - * - * \version $Id$ - * \author Francesco Sacchi - * \author Daniele Basile - */ - -#ifndef DRV_FLASH_AVR_H -#define DRV_FLASH_AVR_H - -#include -#include - -bool flash_avr_test(void); -void flash_avr_init(struct KFile *fd); - - -#endif /* DRV_FLASH_AVR_H */ diff --git a/cpu/avr/drv/kdebug_avr.c b/cpu/avr/drv/kdebug_avr.c deleted file mode 100644 index 35d0645d..00000000 --- a/cpu/avr/drv/kdebug_avr.c +++ /dev/null @@ -1,255 +0,0 @@ -/** - * \file - * - * - * \brief AVR debug support (implementation). - * - * \version $Id$ - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * \author Francesco Sacchi - */ - -#include -#include -#include /* for BV(), DIV_ROUND */ -#include -#include /* for CLOCK_FREQ */ -#include /* Required for bus macros overrides */ - -#include - -#if CONFIG_KDEBUG_PORT == 0 - - /* - * Support for special bus policies or external transceivers - * on UART0 (to be overridden in "hw_ser.h"). - * - * HACK: if we don't set TXEN, kdbg disables the transmitter - * after each output statement until the serial driver - * is initialized. These glitches confuse the debug - * terminal that ends up printing some trash. - */ - #ifndef KDBG_UART0_BUS_INIT - #define KDBG_UART0_BUS_INIT do { \ - UCSR0B = BV(TXEN0); \ - } while (0) - #endif - #ifndef KDBG_UART0_BUS_RX - #define KDBG_UART0_BUS_RX do {} while (0) - #endif - #ifndef KDBG_UART0_BUS_TX - #define KDBG_UART0_BUS_TX do {} while (0) - #endif - - #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA168 - #define UCR UCSR0B - #define UDR UDR0 - #define USR UCSR0A - #elif CPU_AVR_ATMEGA8 - #define UCR UCSRB - #define USR UCSRA - #else - #error Unknown CPU - #endif - - #define KDBG_WAIT_READY() do { loop_until_bit_is_set(USR, UDRE0); } while(0) - #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(USR, TXC0); } while(0) - - /* - * We must clear the TXC flag before sending a new character to allow - * KDBG_WAIT_TXDONE() to work properly. - * - * BUG: if KDBG_WRITE_CHAR() is called after the TXC flag is set by hardware, - * a new TXC could be generated after we've cleared it and before the new - * character is written to UDR. On a 485 bus, the transceiver will be put - * in RX mode while still transmitting the last char. - */ - #define KDBG_WRITE_CHAR(c) do { USR |= BV(TXC0); UDR = (c); } while(0) - - #define KDBG_MASK_IRQ(old) do { \ - (old) = UCR; \ - UCR |= BV(TXEN0); \ - UCR &= ~(BV(TXCIE0) | BV(UDRIE0)); \ - KDBG_UART0_BUS_TX; \ - } while(0) - - #define KDBG_RESTORE_IRQ(old) do { \ - KDBG_WAIT_TXDONE(); \ - KDBG_UART0_BUS_RX; \ - UCR = (old); \ - } while(0) - - typedef uint8_t kdbg_irqsave_t; - -#elif CONFIG_KDEBUG_PORT == 1 - - /* - * Support for special bus policies or external transceivers - * on UART1 (to be overridden in "hw_ser.h"). - * - * HACK: if we don't set TXEN, kdbg disables the transmitter - * after each output statement until the serial driver - * is initialized. These glitches confuse the debug - * terminal that ends up printing some trash. - */ - #ifndef KDBG_UART1_BUS_INIT - #define KDBG_UART1_BUS_INIT do { \ - UCSR1B = BV(TXEN1); \ - } while (0) - #endif - #ifndef KDBG_UART1_BUS_RX - #define KDBG_UART1_BUS_RX do {} while (0) - #endif - #ifndef KDBG_UART1_BUS_TX - #define KDBG_UART1_BUS_TX do {} while (0) - #endif - - #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR1A, UDRE1); } while(0) - #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR1A, TXC1); } while(0) - #define KDBG_WRITE_CHAR(c) do { UCSR1A |= BV(TXC1); UDR1 = (c); } while(0) - - #define KDBG_MASK_IRQ(old) do { \ - (old) = UCSR1B; \ - UCSR1B |= BV(TXEN1); \ - UCSR1B &= ~(BV(TXCIE1) | BV(UDRIE1)); \ - KDBG_UART1_BUS_TX; \ - } while(0) - - #define KDBG_RESTORE_IRQ(old) do { \ - KDBG_WAIT_TXDONE(); \ - KDBG_UART1_BUS_RX; \ - UCSR1B = (old); \ - } while(0) - - typedef uint8_t kdbg_irqsave_t; - -/* - * Special debug port for BitBanged Serial see below for details... - */ -#elif CONFIG_KDEBUG_PORT == 666 - #include "hw_ser.h" - #define KDBG_WAIT_READY() do { /*nop*/ } while(0) - #define KDBG_WRITE_CHAR(c) _kdebug_bitbang_putchar((c)) - #define KDBG_MASK_IRQ(old) do { IRQ_SAVE_DISABLE((old)); } while(0) - #define KDBG_RESTORE_IRQ(old) do { IRQ_RESTORE((old)); } while(0) - typedef cpuflags_t kdbg_irqsave_t; - - #define KDBG_DELAY (((CLOCK_FREQ + CONFIG_KDEBUG_BAUDRATE / 2) / CONFIG_KDEBUG_BAUDRATE) + 7) / 14 - - static void _kdebug_bitbang_delay(void) - { - unsigned long i; - - for (i = 0; i < KDBG_DELAY; i++) - { - NOP; - NOP; - NOP; - NOP; - NOP; - } - } - - /** - * Putchar for BITBANG serial debug console. - * Sometimes, we can't permit to use a whole serial for debugging purpose. - * Since debug console is in output only it is usefull to use a single generic I/O pin for debug. - * This is achieved by this simple function, that shift out the data like a UART, but - * in software :) - * The only requirement is that SER_BITBANG_* macros will be defined somewhere (usually hw_ser.h) - * \note All interrupts are disabled during debug prints! - */ - static void _kdebug_bitbang_putchar(char c) - { - int i; - uint16_t data = c; - - /* Add stop bit */ - data |= 0x0100; - - /* Add start bit*/ - data <<= 1; - - /* Shift out data */ - uint16_t shift = 1; - for (i = 0; i < 10; i++) - { - if (data & shift) - SER_BITBANG_HIGH; - else - SER_BITBANG_LOW; - _kdebug_bitbang_delay(); - shift <<= 1; - } - } -#else - #error CONFIG_KDEBUG_PORT should be either 0, 1 or 666 -#endif - - -INLINE void kdbg_hw_init(void) -{ - #if CONFIG_KDEBUG_PORT == 666 - SER_BITBANG_INIT; - #else /* CONFIG_KDEBUG_PORT != 666 */ - /* Compute the baud rate */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1; - - #if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128) - #if CONFIG_KDEBUG_PORT == 0 - UBRR0H = (uint8_t)(period>>8); - UBRR0L = (uint8_t)period; - KDBG_UART0_BUS_INIT; - #elif CONFIG_KDEBUG_PORT == 1 - UBRR1H = (uint8_t)(period>>8); - UBRR1L = (uint8_t)period; - KDBG_UART1_BUS_INIT; - #else - #error CONFIG_KDEBUG_PORT must be either 0 or 1 - #endif - - #elif CPU_AVR_ATMEGA168 - UBRR0H = (uint8_t)(period>>8); - UBRR0L = (uint8_t)period; - KDBG_UART0_BUS_INIT; - #elif CPU_AVR_ATMEGA8 - UBRRH = (uint8_t)(period>>8); - UBRRL = (uint8_t)period; - #elif CPU_AVR_ATMEGA103 - UBRR = (uint8_t)period; - KDBG_UART0_BUS_INIT; - #else - #error Unknown CPU - #endif - #endif /* CONFIG_KDEBUG_PORT == 666 */ -} diff --git a/cpu/avr/drv/lcd_32122a_avr.c b/cpu/avr/drv/lcd_32122a_avr.c deleted file mode 100644 index f635d414..00000000 --- a/cpu/avr/drv/lcd_32122a_avr.c +++ /dev/null @@ -1,522 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * - * \brief Displaytech 32122A LCD driver - */ - -#include "lcd_32122a_avr.h" -#include -#include - -#include -#include -#include -#include /* BV() */ -#include - -#include -#include -#include - -/* Configuration sanity checks */ -#if !defined(CONFIG_LCD_SOFTINT_REFRESH) || (CONFIG_LCD_SOFTINT_REFRESH != 0 && CONFIG_LCD_SOFTINT_REFRESH != 1) - #error CONFIG_LCD_SOFTINT_REFRESH must be defined to either 0 or 1 -#endif -#if !defined(CONFIG_LCD_SOFTINT_REFRESH) || (CONFIG_LCD_SOFTINT_REFRESH != 0 && CONFIG_LCD_SOFTINT_REFRESH != 1) - #error CONFIG_LCD_SOFTINT_REFRESH must be defined to either 0 or 1 -#endif - - -#if CONFIG_LCD_SOFTINT_REFRESH - - /** Interval between softint driven lcd refresh */ -# define LCD_REFRESH_INTERVAL 20 /* 20ms -> 50fps */ - -#endif /* CONFIG_LCD_SOFTINT_REFRESH */ - -/** Number of LCD pages */ -#define LCD_PAGES 4 - -/** Width of an LCD page */ -#define LCD_PAGESIZE (LCD_WIDTH / 2) - -/** - * \name LCD I/O pins/ports - * @{ - */ -#define LCD_PF_DB0 PF4 -#define LCD_PF_DB1 PF5 -#define LCD_PF_DB2 PF6 -#define LCD_PF_DB3 PF7 -#define LCD_PD_DB4 PD4 -#define LCD_PD_DB5 PD5 -#define LCD_PD_DB6 PD6 -#define LCD_PD_DB7 PD7 -#define LCD_PB_A0 PB0 -#define LCD_PE_RW PE7 -#define LCD_PE_E1 PE2 -#define LCD_PE_E2 PE6 -/*@}*/ - -/** - * \name DB high nibble (DB[4-7]) - * @{ - */ -#define LCD_DATA_HI_PORT PORTD -#define LCD_DATA_HI_PIN PIND -#define LCD_DATA_HI_DDR DDRD -#define LCD_DATA_HI_SHIFT 0 -#define LCD_DATA_HI_MASK 0xF0 -/*@}*/ - -/** - * \name DB low nibble (DB[0-3]) - * @{ - */ -#define LCD_DATA_LO_PORT PORTF -#define LCD_DATA_LO_PIN PINF -#define LCD_DATA_LO_DDR DDRF -#define LCD_DATA_LO_SHIFT 4 -#define LCD_DATA_LO_MASK 0xF0 -/*@}*/ - -/** - * \name LCD bus control macros - * @{ - */ -#define LCD_CLR_A0 (PORTB &= ~BV(LCD_PB_A0)) -#define LCD_SET_A0 (PORTB |= BV(LCD_PB_A0)) -#define LCD_CLR_RD (PORTE &= ~BV(LCD_PE_RW)) -#define LCD_SET_RD (PORTE |= BV(LCD_PE_RW)) -#define LCD_CLR_E1 (PORTE &= ~BV(LCD_PE_E1)) -#define LCD_SET_E1 (PORTE |= BV(LCD_PE_E1)) -#define LCD_CLR_E2 (PORTE &= ~BV(LCD_PE_E2)) -#define LCD_SET_E2 (PORTE |= BV(LCD_PE_E2)) -#define LCD_SET_E(x) (PORTE |= (x)) -#define LCD_CLR_E(x) (PORTE &= ~(x)) -/*@}*/ - -/** - * \name Chip select bits for LCD_SET_E() - * @{ - */ -#define LCDF_E1 (BV(LCD_PE_E1)) -#define LCDF_E2 (BV(LCD_PE_E2)) -/*@}*/ - -/** Read from the LCD data bus (DB[0-7]) */ -#define LCD_READ ( \ - ((LCD_DATA_LO_PIN & LCD_DATA_LO_MASK) >> LCD_DATA_LO_SHIFT) | \ - ((LCD_DATA_HI_PIN & LCD_DATA_HI_MASK) >> LCD_DATA_HI_SHIFT) \ - ) - -/** Write to the LCD data bus (DB[0-7]) */ -#define LCD_WRITE(d) \ - do { \ - LCD_DATA_LO_PORT = (LCD_DATA_LO_PORT & ~LCD_DATA_LO_MASK) | (((d)<-- - */ - LCD_WRITE(cmd); - //LCD_DB_OUT; - LCD_CLR_A0; - LCD_SET_E(chip); - LCD_DELAY_WRITE; - LCD_CLR_E(chip); - LCD_SET_A0; - //LCD_DB_IN; -} - - -static inline uint8_t lcd_read(uint8_t chip) -{ - uint8_t data; - - WAIT_LCD; - - /** - * \code - * __________________ - * A0 __/ \__ - * ____________ - * R/W __/ \__ - * _______ - * E1 _____/ \____ - * - * DATA -------<=====>---- - * - * \endcode - */ - LCD_DB_IN; - //LCD_SET_A0; - LCD_SET_RD; - LCD_SET_E(chip); - LCD_DELAY_READ; - data = LCD_READ; - LCD_CLR_E(chip); - LCD_CLR_RD; - //LCD_CLR_A0; - LCD_DB_OUT; - - return data; -} - - -static inline void lcd_write(uint8_t c, uint8_t chip) -{ - WAIT_LCD; - - /** - * \code - * __________________ - * A0 ___/ \___ - * - * R/W __________________ - * ______ - * E1 _____/ \_____ - * - * DATA -<==============>- - * - * \endcode - */ - LCD_WRITE(c); - //LCD_DB_OUT; - //LCD_SET_A0; - LCD_SET_E(chip); - LCD_DELAY_WRITE; - LCD_CLR_E(chip); - //LCD_CLR_A0; - //LCD_DB_IN; -} - - -/** - * Set LCD contrast PWM. - */ -void lcd_setPwm(int duty) -{ - ASSERT(duty >= LCD_MIN_PWM); - ASSERT(duty <= LCD_MAX_PWM); - - OCR3C = duty; -} - - -static void lcd_clear(void) -{ - uint8_t page, j; - - for (page = 0; page < LCD_PAGES; ++page) - { - lcd_cmd(LCD_CMD_COLADDR | 0, LCDF_E1 | LCDF_E2); - lcd_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); - for (j = 0; j < LCD_PAGESIZE; j++) - lcd_write(0, LCDF_E1 | LCDF_E2); - } -} - - -static void lcd_writeRaster(const uint8_t *raster) -{ - uint8_t page, rows; - const uint8_t *right_raster; - - CHECK_WALL(wall_before_raster); - CHECK_WALL(wall_after_raster); - - for (page = 0; page < LCD_PAGES; ++page) - { - lcd_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); - lcd_cmd(LCD_CMD_COLADDR | 0, LCDF_E1 | LCDF_E2); - - /* Super optimized lamer loop */ - right_raster = raster + LCD_PAGESIZE; - rows = LCD_PAGESIZE; - do - { - lcd_write(*raster++, LCDF_E1); - lcd_write(*right_raster++, LCDF_E2); - } - while (--rows); - raster = right_raster; - } -} - -/** - * Update the LCD display with data from the provided bitmap. - */ -void lcd_blitBitmap(Bitmap *bm) -{ - MOD_CHECK(lcd); - lcd_writeRaster(bm->raster); -} - - -#if CONFIG_LCD_SOFTINT_REFRESH - -static void lcd_refreshSoftint(void) -{ - lcd_blit_bitmap(&lcd_bitmap); - timer_add(lcd_refresh_timer); -} - -#endif /* CONFIG_LCD_SOFTINT_REFRESH */ - - -/** - * Initialize LCD subsystem. - * - * \note The PWM used for LCD contrast is initialized in drv/pwm.c - * because it is the same PWM used for output attenuation. - */ -void lcd_init(void) -{ - MOD_CHECK(timer); - - // FIXME: interrupts are already disabled when we get here?!? - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - PORTB |= BV(LCD_PB_A0); - DDRB |= BV(LCD_PB_A0); - - PORTE &= ~(BV(LCD_PE_RW) | BV(LCD_PE_E1) | BV(LCD_PE_E2)); - DDRE |= BV(LCD_PE_RW) | BV(LCD_PE_E1) | BV(LCD_PE_E2); - -/* LCD hw reset - LCD_RESET_PORT |= BV(LCD_RESET_BIT); - LCD_RESET_DDR |= BV(LCD_RESET_BIT); - LCD_DELAY_WRITE; - LCD_DELAY_WRITE; - LCD_RESET_PORT &= ~BV(LCD_RESET_BIT); - LCD_DELAY_WRITE; - LCD_DELAY_WRITE; - LCD_RESET_PORT |= BV(LCD_RESET_BIT); -*/ - /* - * Data bus is in output state most of the time: - * LCD r/w functions assume it is left in output state - */ - LCD_DB_OUT; - - // Wait for RST line to stabilize at Vcc. - IRQ_ENABLE; - timer_delay(20); - IRQ_SAVE_DISABLE(flags); - - lcd_cmd(LCD_CMD_RESET, LCDF_E1 | LCDF_E2); - lcd_cmd(LCD_CMD_DISPLAY_ON, LCDF_E1 | LCDF_E2); - lcd_cmd(LCD_CMD_STARTLINE | 0, LCDF_E1 | LCDF_E2); - - /* Initialize anti-corruption walls for raster */ - INIT_WALL(wall_before_raster); - INIT_WALL(wall_after_raster); - - IRQ_RESTORE(flags); - - lcd_clear(); - lcd_setpwm(LCD_DEF_PWM); - - gfx_bitmapInit(&lcd_bitmap, lcd_raster, LCD_WIDTH, LCD_HEIGHT); - gfx_bitmapClear(&lcd_bitmap); - -#if CONFIG_LCD_SOFTINT_REFRESH - - /* Init IRQ driven LCD refresh */ - lcd_refresh_timer = timer_new(); - ASSERT(lcd_refresh_timer != NULL); - INITEVENT_INT(&lcd_refresh_timer->expire, (Hook)lcd_refresh_softint, 0); - lcd_refresh_timer->delay = LCD_REFRESH_INTERVAL; - timer_add(lcd_refresh_timer); - -#endif /* CONFIG_LCD_SOFTINT_REFRESH */ - - MOD_INIT(lcd); -} diff --git a/cpu/avr/drv/lcd_32122a_avr.h b/cpu/avr/drv/lcd_32122a_avr.h deleted file mode 100644 index 1d23b190..00000000 --- a/cpu/avr/drv/lcd_32122a_avr.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * - * \brief Displaytech 32122A LCD driver - */ - -/*#* - *#* $Log$ - *#* Revision 1.6 2006/07/19 12:56:25 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.5 2006/04/27 05:40:11 bernie - *#* Naming convention fixes; Partial merge from project_grl. - *#* - *#* Revision 1.4 2006/02/15 09:13:16 bernie - *#* Switch to BITMAP_FMT_PLANAR_V_LSB. - *#* - *#* Revision 1.3 2006/02/10 12:33:51 bernie - *#* Make emulator display a bit larger. - *#* - *#* Revision 1.2 2006/01/17 22:59:48 bernie - *#* Hardcode a different display size. - *#* - *#* Revision 1.1 2006/01/16 03:50:57 bernie - *#* Import into DevLib. - *#*/ - -#ifndef LCD_32122A_AVR_H -#define LCD_32122A_AVR_H - -/* Predefined LCD PWM contrast values */ -#define LCD_DEF_PWM 145 -#define LCD_MAX_PWM 505 -#define LCD_MIN_PWM 130 - -/* Display bitmap dims */ -#define LCD_WIDTH 122 -#define LCD_HEIGHT 32 - -/* fwd decl */ -struct Bitmap; - -extern struct Bitmap lcd_bitmap; - -void lcd_init(void); -void lcd_setPwm(int duty); -void lcd_blitBitmap(struct Bitmap *bm); - -#endif /* LCD_32122A_AVR_H */ diff --git a/cpu/avr/drv/ser_avr.c b/cpu/avr/drv/ser_avr.c deleted file mode 100644 index e9e1f5ec..00000000 --- a/cpu/avr/drv/ser_avr.c +++ /dev/null @@ -1,965 +0,0 @@ -/** - * \file - * - * - * \brief AVR UART and SPI I/O driver - * - * Rationale for project_ks hardware. - * - * The serial 0 on the board_kf board is used to communicate with the - * smart card, which has the TX and RX lines connected together. To - * allow the smart card to drive the RX line of the CPU the CPU TX has - * to be in a high impedance state. - * Whenever a transmission is done and there is nothing more to send - * the transmitter is turn off. The output pin is held in input with - * pull-up enabled, to avoid capturing noise from the nearby RX line. - * - * The line on the KBus port must keep sending data, even when - * there is nothing to transmit, because a burst data transfer - * generates noise on the audio channels. - * This is accomplished using the multiprocessor mode of the - * ATmega64/128 serial. - * - * The receiver keeps the MPCM bit always on. When useful data - * is trasmitted the address bit is set. The receiver hardware - * consider the frame as address info and receive it. - * When useless fill bytes are sent the address bit is cleared - * and the receiver will ignore them, avoiding useless triggering - * of RXC interrupt. - * - * \version $Id$ - * \author Bernardo Innocenti - * \author Stefano Fedrigo - */ - -#include -#include - -#include /* Required for bus macros overrides */ -#include /* CLOCK_FREQ */ -#include - -#include /* DIV_ROUND */ -#include -#include -#include - -#include -#if defined(__AVR_LIBC_VERSION__) && (__AVR_LIBC_VERSION__ >= 10400UL) - #include -#else - #include -#endif - - -#if !CONFIG_SER_HWHANDSHAKE - /** - * \name Hardware handshake (RTS/CTS). - * \{ - */ - #define RTS_ON do {} while (0) - #define RTS_OFF do {} while (0) - #define IS_CTS_ON true - #define EIMSKF_CTS 0 /**< Dummy value, must be overridden */ - /*\}*/ -#endif - -#if CPU_AVR_ATMEGA1281 - #define BIT_RXCIE0 RXCIE0 - #define BIT_RXEN0 RXEN0 - #define BIT_TXEN0 TXEN0 - #define BIT_UDRIE0 UDRIE0 - - #define BIT_RXCIE1 RXCIE1 - #define BIT_RXEN1 RXEN1 - #define BIT_TXEN1 TXEN1 - #define BIT_UDRIE1 UDRIE1 -#else - #define BIT_RXCIE0 RXCIE - #define BIT_RXEN0 RXEN - #define BIT_TXEN0 TXEN - #define BIT_UDRIE0 UDRIE - - #define BIT_RXCIE1 RXCIE - #define BIT_RXEN1 RXEN - #define BIT_TXEN1 TXEN - #define BIT_UDRIE1 UDRIE -#endif - - -/** - * \name Overridable serial bus hooks - * - * These can be redefined in hw.h to implement - * special bus policies such as half-duplex, 485, etc. - * - * - * \code - * TXBEGIN TXCHAR TXEND TXOFF - * | __________|__________ | | - * | | | | | | | | | - * v v v v v v v v v - * ______ __ __ __ __ __ __ ________________ - * \/ \/ \/ \/ \/ \/ \/ - * ______/\__/\__/\__/\__/\__/\__/ - * - * \endcode - * - * \{ - */ -#ifndef SER_UART0_BUS_TXINIT - /** - * Default TXINIT macro - invoked in uart0_init() - * - * - Enable both the receiver and the transmitter - * - Enable only the RX complete interrupt - */ - #define SER_UART0_BUS_TXINIT do { \ - UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ - } while (0) -#endif - -#ifndef SER_UART0_BUS_TXBEGIN - /** - * Invoked before starting a transmission - * - * - Enable both the receiver and the transmitter - * - Enable both the RX complete and UDR empty interrupts - */ - #define SER_UART0_BUS_TXBEGIN do { \ - UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ - } while (0) -#endif - -#ifndef SER_UART0_BUS_TXCHAR - /** - * Invoked to send one character. - */ - #define SER_UART0_BUS_TXCHAR(c) do { \ - UDR0 = (c); \ - } while (0) -#endif - -#ifndef SER_UART0_BUS_TXEND - /** - * Invoked as soon as the txfifo becomes empty - * - * - Keep both the receiver and the transmitter enabled - * - Keep the RX complete interrupt enabled - * - Disable the UDR empty interrupt - */ - #define SER_UART0_BUS_TXEND do { \ - UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ - } while (0) -#endif - -#ifndef SER_UART0_BUS_TXOFF - /** - * \def SER_UART0_BUS_TXOFF - * - * Invoked after the last character has been transmitted - * - * The default is no action. - */ - #ifdef __doxygen__ - #define SER_UART0_BUS_TXOFF - #endif -#endif - -#ifndef SER_UART1_BUS_TXINIT - /** \sa SER_UART0_BUS_TXINIT */ - #define SER_UART1_BUS_TXINIT do { \ - UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ - } while (0) -#endif -#ifndef SER_UART1_BUS_TXBEGIN - /** \sa SER_UART0_BUS_TXBEGIN */ - #define SER_UART1_BUS_TXBEGIN do { \ - UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ - } while (0) -#endif -#ifndef SER_UART1_BUS_TXCHAR - /** \sa SER_UART0_BUS_TXCHAR */ - #define SER_UART1_BUS_TXCHAR(c) do { \ - UDR1 = (c); \ - } while (0) -#endif -#ifndef SER_UART1_BUS_TXEND - /** \sa SER_UART0_BUS_TXEND */ - #define SER_UART1_BUS_TXEND do { \ - UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \ - } while (0) -#endif -#ifndef SER_UART1_BUS_TXOFF - /** - * \def SER_UART1_BUS_TXOFF - * - * \see SER_UART0_BUS_TXOFF - */ - #ifdef __doxygen__ - #define SER_UART1_BUS_TXOFF - #endif -#endif -/*\}*/ - - -/** - * \name Overridable SPI hooks - * - * These can be redefined in hw.h to implement - * special bus policies such as slave select pin handling, etc. - * - * \{ - */ -#ifndef SER_SPI_BUS_TXINIT - /** - * Default TXINIT macro - invoked in spi_init() - * The default is no action. - */ - #define SER_SPI_BUS_TXINIT -#endif - -#ifndef SER_SPI_BUS_TXCLOSE - /** - * Invoked after the last character has been transmitted. - * The default is no action. - */ - #define SER_SPI_BUS_TXCLOSE -#endif -/*\}*/ - - -/* SPI port and pin configuration */ -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281 - #define SPI_PORT PORTB - #define SPI_DDR DDRB - #define SPI_SS_BIT PB0 - #define SPI_SCK_BIT PB1 - #define SPI_MOSI_BIT PB2 - #define SPI_MISO_BIT PB3 -#elif CPU_AVR_ATMEGA8 - #define SPI_PORT PORTB - #define SPI_DDR DDRB - #define SPI_SS_BIT PB2 - #define SPI_SCK_BIT PB5 - #define SPI_MOSI_BIT PB3 - #define SPI_MISO_BIT PB4 -#else - #error Unknown architecture -#endif - -/* USART register definitions */ -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 - #define AVR_HAS_UART1 1 -#elif CPU_AVR_ATMEGA8 - #define AVR_HAS_UART1 0 - #define UCSR0A UCSRA - #define UCSR0B UCSRB - #define UCSR0C UCSRC - #define UDR0 UDR - #define UBRR0L UBRRL - #define UBRR0H UBRRH - #define SIG_UART0_DATA SIG_UART_DATA - #define SIG_UART0_RECV SIG_UART_RECV - #define SIG_UART0_TRANS SIG_UART_TRANS -#elif CPU_AVR_ATMEGA103 - #define AVR_HAS_UART1 0 - #define UCSR0B UCR - #define UDR0 UDR - #define UCSR0A USR - #define UBRR0L UBRR - #define SIG_UART0_DATA SIG_UART_DATA - #define SIG_UART0_RECV SIG_UART_RECV - #define SIG_UART0_TRANS SIG_UART_TRANS -#else - #error Unknown architecture -#endif - - -/** - * \def CONFIG_SER_STROBE - * - * This is a debug facility that can be used to - * monitor SER interrupt activity on an external pin. - * - * To use strobes, redefine the macros SER_STROBE_ON, - * SER_STROBE_OFF and SER_STROBE_INIT and set - * CONFIG_SER_STROBE to 1. - */ -#if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE - #define SER_STROBE_ON do {/*nop*/} while(0) - #define SER_STROBE_OFF do {/*nop*/} while(0) - #define SER_STROBE_INIT do {/*nop*/} while(0) -#endif - - -/* From the high-level serial driver */ -extern struct Serial ser_handles[SER_CNT]; - -/* TX and RX buffers */ -static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; -static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; -#if AVR_HAS_UART1 - static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; - static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; -#endif -static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE]; -static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE]; - - -/** - * Internal hardware state structure - * - * The \a sending variable is true while the transmission - * interrupt is retriggering itself. - * - * For the USARTs the \a sending flag is useful for taking specific - * actions before sending a burst of data, at the start of a trasmission - * but not before every char sent. - * - * For the SPI, this flag is necessary because the SPI sends and receives - * bytes at the same time and the SPI IRQ is unique for send/receive. - * The only way to start transmission is to write data in SPDR (this - * is done by spi_starttx()). We do this *only* if a transfer is - * not already started. - */ -struct AvrSerial -{ - struct SerialHardware hw; - volatile bool sending; -}; - - -/* - * These are to trick GCC into *not* using absolute addressing mode - * when accessing ser_handles, which is very expensive. - * - * Accessing through these pointers generates much shorter - * (and hopefully faster) code. - */ -struct Serial *ser_uart0 = &ser_handles[SER_UART0]; -#if AVR_HAS_UART1 -struct Serial *ser_uart1 = &ser_handles[SER_UART1]; -#endif -struct Serial *ser_spi = &ser_handles[SER_SPI]; - - - -/* - * Callbacks - */ -static void uart0_init( - UNUSED_ARG(struct SerialHardware *, _hw), - UNUSED_ARG(struct Serial *, ser)) -{ - SER_UART0_BUS_TXINIT; - RTS_ON; - SER_STROBE_INIT; -} - -static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - UCSR0B = 0; -} - -static void uart0_enabletxirq(struct SerialHardware *_hw) -{ - struct AvrSerial *hw = (struct AvrSerial *)_hw; - - /* - * WARNING: racy code here! The tx interrupt sets hw->sending to false - * when it runs with an empty fifo. The order of statements in the - * if-block matters. - */ - if (!hw->sending) - { - hw->sending = true; - SER_UART0_BUS_TXBEGIN; - } -} - -static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; - -#if !CPU_AVR_ATMEGA103 - UBRR0H = (period) >> 8; -#endif - UBRR0L = (period); - - //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) -} - -static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) -{ -#if !CPU_AVR_ATMEGA103 - UCSR0C = (UCSR0C & ~(BV(UPM01) | BV(UPM00))) | ((parity) << UPM00); -#endif -} - -#if AVR_HAS_UART1 - -static void uart1_init( - UNUSED_ARG(struct SerialHardware *, _hw), - UNUSED_ARG(struct Serial *, ser)) -{ - SER_UART1_BUS_TXINIT; - RTS_ON; - SER_STROBE_INIT; -} - -static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - UCSR1B = 0; -} - -static void uart1_enabletxirq(struct SerialHardware *_hw) -{ - struct AvrSerial *hw = (struct AvrSerial *)_hw; - - /* - * WARNING: racy code here! The tx interrupt - * sets hw->sending to false when it runs with - * an empty fifo. The order of the statements - * in the if-block matters. - */ - if (!hw->sending) - { - hw->sending = true; - SER_UART1_BUS_TXBEGIN; - } -} - -static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) -{ - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; - - UBRR1H = (period) >> 8; - UBRR1L = (period); - - //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);) -} - -static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) -{ - UCSR1C = (UCSR1C & ~(BV(UPM11) | BV(UPM10))) | ((parity) << UPM10); -} - -#endif // AVR_HAS_UART1 - -static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser)) -{ - /* - * Set MOSI and SCK ports out, MISO in. - * - * The ATmega64/128 datasheet explicitly states that the input/output - * state of the SPI pins is not significant, as when the SPI is - * active the I/O port are overrided. - * This is *blatantly FALSE*. - * - * Moreover, the MISO pin on the board_kc *must* be in high impedance - * state even when the SPI is off, because the line is wired together - * with the KBus serial RX, and the transmitter of the slave boards - * would be unable to drive the line. - */ - ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT))); - - /* - * If the SPI master mode is activated and the SS pin is in input and tied low, - * the SPI hardware will automatically switch to slave mode! - * For proper communication this pins should therefore be: - * - as output - * - as input but tied high forever! - * This driver set the pin as output. - */ - #warning SPI SS pin set as output for proper operation, check schematics for possible conflicts. - ATOMIC(SPI_DDR |= BV(SPI_SS_BIT)); - - ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT)); - /* Enable SPI, IRQ on, Master */ - SPCR = BV(SPE) | BV(SPIE) | BV(MSTR); - - /* Set data order */ - #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST - SPCR |= BV(DORD); - #endif - - /* Set SPI clock rate */ - #if CONFIG_SPI_CLOCK_DIV == 128 - SPCR |= (BV(SPR1) | BV(SPR0)); - #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32) - SPCR |= BV(SPR1); - #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8) - SPCR |= BV(SPR0); - #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2) - // SPR0 & SDPR1 both at 0 - #else - #error Unsupported SPI clock division factor. - #endif - - /* Set SPI2X bit (spi double frequency) */ - #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \ - || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4) - SPSR &= ~BV(SPI2X); - #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2) - SPSR |= BV(SPI2X); - #else - #error Unsupported SPI clock division factor. - #endif - - /* Set clock polarity */ - #if CONFIG_SPI_CLOCK_POL == 1 - SPCR |= BV(CPOL); - #endif - - /* Set clock phase */ - #if CONFIG_SPI_CLOCK_PHASE == 1 - SPCR |= BV(CPHA); - #endif - SER_SPI_BUS_TXINIT; - - SER_STROBE_INIT; -} - -static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw)) -{ - SPCR = 0; - - SER_SPI_BUS_TXCLOSE; - - /* Set all pins as inputs */ - ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT))); -} - -static void spi_starttx(struct SerialHardware *_hw) -{ - struct AvrSerial *hw = (struct AvrSerial *)_hw; - - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Send data only if the SPI is not already transmitting */ - if (!hw->sending && !fifo_isempty(&ser_spi->txfifo)) - { - hw->sending = true; - SPDR = fifo_pop(&ser_spi->txfifo); - } - - IRQ_RESTORE(flags); -} - -static void spi_setbaudrate( - UNUSED_ARG(struct SerialHardware *, _hw), - UNUSED_ARG(unsigned long, rate)) -{ - // nop -} - -static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity)) -{ - // nop -} - -static bool tx_sending(struct SerialHardware* _hw) -{ - struct AvrSerial *hw = (struct AvrSerial *)_hw; - return hw->sending; -} - - - -// FIXME: move into compiler.h? Ditch? -#if COMPILER_C99 - #define C99INIT(name,val) .name = val -#elif defined(__GNUC__) - #define C99INIT(name,val) name: val -#else - #warning No designated initializers, double check your code - #define C99INIT(name,val) (val) -#endif - -/* - * High-level interface data structures - */ -static const struct SerialHardwareVT UART0_VT = -{ - C99INIT(init, uart0_init), - C99INIT(cleanup, uart0_cleanup), - C99INIT(setBaudrate, uart0_setbaudrate), - C99INIT(setParity, uart0_setparity), - C99INIT(txStart, uart0_enabletxirq), - C99INIT(txSending, tx_sending), -}; - -#if AVR_HAS_UART1 -static const struct SerialHardwareVT UART1_VT = -{ - C99INIT(init, uart1_init), - C99INIT(cleanup, uart1_cleanup), - C99INIT(setBaudrate, uart1_setbaudrate), - C99INIT(setParity, uart1_setparity), - C99INIT(txStart, uart1_enabletxirq), - C99INIT(txSending, tx_sending), -}; -#endif // AVR_HAS_UART1 - -static const struct SerialHardwareVT SPI_VT = -{ - C99INIT(init, spi_init), - C99INIT(cleanup, spi_cleanup), - C99INIT(setBaudrate, spi_setbaudrate), - C99INIT(setParity, spi_setparity), - C99INIT(txStart, spi_starttx), - C99INIT(txSending, tx_sending), -}; - -static struct AvrSerial UARTDescs[SER_CNT] = -{ - { - C99INIT(hw, /**/) { - C99INIT(table, &UART0_VT), - C99INIT(txbuffer, uart0_txbuffer), - C99INIT(rxbuffer, uart0_rxbuffer), - C99INIT(txbuffer_size, sizeof(uart0_txbuffer)), - C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)), - }, - C99INIT(sending, false), - }, -#if AVR_HAS_UART1 - { - C99INIT(hw, /**/) { - C99INIT(table, &UART1_VT), - C99INIT(txbuffer, uart1_txbuffer), - C99INIT(rxbuffer, uart1_rxbuffer), - C99INIT(txbuffer_size, sizeof(uart1_txbuffer)), - C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)), - }, - C99INIT(sending, false), - }, -#endif - { - C99INIT(hw, /**/) { - C99INIT(table, &SPI_VT), - C99INIT(txbuffer, spi_txbuffer), - C99INIT(rxbuffer, spi_rxbuffer), - C99INIT(txbuffer_size, sizeof(spi_txbuffer)), - C99INIT(rxbuffer_size, sizeof(spi_rxbuffer)), - }, - C99INIT(sending, false), - } -}; - -struct SerialHardware *ser_hw_getdesc(int unit) -{ - ASSERT(unit < SER_CNT); - return &UARTDescs[unit].hw; -} - - -/* - * Interrupt handlers - */ - -#if CONFIG_SER_HWHANDSHAKE - -/// This interrupt is triggered when the CTS line goes high -SIGNAL(SIG_CTS) -{ - // Re-enable UDR empty interrupt and TX, then disable CTS interrupt - UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); - EIMSK &= ~EIMSKF_CTS; -} - -#endif // CONFIG_SER_HWHANDSHAKE - - -/** - * Serial 0 TX interrupt handler - */ -SIGNAL(USART0_UDRE_vect) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; - - if (fifo_isempty(txfifo)) - { - SER_UART0_BUS_TXEND; -#ifndef SER_UART0_BUS_TXOFF - UARTDescs[SER_UART0].sending = false; -#endif - } -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 - else if (!IS_CTS_ON) - { - // Disable rx interrupt and tx, enable CTS interrupt - // UNTESTED - UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN); - EIFR |= EIMSKF_CTS; - EIMSK |= EIMSKF_CTS; - } -#endif - else - { - char c = fifo_pop(txfifo); - SER_UART0_BUS_TXCHAR(c); - } - - SER_STROBE_OFF; -} - -#ifdef SER_UART0_BUS_TXOFF -/** - * Serial port 0 TX complete interrupt handler. - * - * This IRQ is usually disabled. The UDR-empty interrupt - * enables it when there's no more data to transmit. - * We need to wait until the last character has been - * transmitted before switching the 485 transceiver to - * receive mode. - * - * The txfifo might have been refilled by putchar() while - * we were waiting for the transmission complete interrupt. - * In this case, we must restart the UDR empty interrupt, - * otherwise we'd stop the serial port with some data - * still pending in the buffer. - */ -SIGNAL(SIG_UART0_TRANS) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart0->txfifo; - if (fifo_isempty(txfifo)) - { - SER_UART0_BUS_TXOFF; - UARTDescs[SER_UART0].sending = false; - } - else - UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); - - SER_STROBE_OFF; -} -#endif /* SER_UART0_BUS_TXOFF */ - - -#if AVR_HAS_UART1 - -/** - * Serial 1 TX interrupt handler - */ -SIGNAL(USART1_UDRE_vect) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; - - if (fifo_isempty(txfifo)) - { - SER_UART1_BUS_TXEND; -#ifndef SER_UART1_BUS_TXOFF - UARTDescs[SER_UART1].sending = false; -#endif - } -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 - else if (!IS_CTS_ON) - { - // Disable rx interrupt and tx, enable CTS interrupt - // UNTESTED - UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN); - EIFR |= EIMSKF_CTS; - EIMSK |= EIMSKF_CTS; - } -#endif - else - { - char c = fifo_pop(txfifo); - SER_UART1_BUS_TXCHAR(c); - } - - SER_STROBE_OFF; -} - -#ifdef SER_UART1_BUS_TXOFF -/** - * Serial port 1 TX complete interrupt handler. - * - * \sa port 0 TX complete handler. - */ -SIGNAL(SIG_UART1_TRANS) -{ - SER_STROBE_ON; - - struct FIFOBuffer * const txfifo = &ser_uart1->txfifo; - if (fifo_isempty(txfifo)) - { - SER_UART1_BUS_TXOFF; - UARTDescs[SER_UART1].sending = false; - } - else - UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); - - SER_STROBE_OFF; -} -#endif /* SER_UART1_BUS_TXOFF */ - -#endif // AVR_HAS_UART1 - - -/** - * Serial 0 RX complete interrupt handler. - * - * This handler is interruptible. - * Interrupt are reenabled as soon as recv complete interrupt is - * disabled. Using INTERRUPT() is troublesome when the serial - * is heavily loaded, because an interrupt could be retriggered - * when executing the handler prologue before RXCIE is disabled. - * - * \note The code that re-enables interrupts is commented out - * because in some nasty cases the interrupt is retriggered. - * This is probably due to the RXC flag being set before - * RXCIE is cleared. Unfortunately the RXC flag is read-only - * and can't be cleared by code. - */ -SIGNAL(USART0_RX_vect) -{ - SER_STROBE_ON; - - /* Disable Recv complete IRQ */ - //UCSR0B &= ~BV(RXCIE); - //IRQ_ENABLE; - - /* Should be read before UDR */ - ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); - - /* To clear the RXC flag we must _always_ read the UDR even when we're - * not going to accept the incoming data, otherwise a new interrupt - * will occur once the handler terminates. - */ - char c = UDR0; - struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo; - - if (fifo_isfull(rxfifo)) - ser_uart0->status |= SERRF_RXFIFOOVERRUN; - else - { - fifo_push(rxfifo, c); -#if CONFIG_SER_HWHANDSHAKE - if (fifo_isfull(rxfifo)) - RTS_OFF; -#endif - } - - /* Reenable receive complete int */ - //IRQ_DISABLE; - //UCSR0B |= BV(RXCIE); - - SER_STROBE_OFF; -} - - -#if AVR_HAS_UART1 - -/** - * Serial 1 RX complete interrupt handler. - * - * This handler is interruptible. - * Interrupt are reenabled as soon as recv complete interrupt is - * disabled. Using INTERRUPT() is troublesome when the serial - * is heavily loaded, because an interrupt could be retriggered - * when executing the handler prologue before RXCIE is disabled. - * - * \see SIGNAL(USART1_RX_vect) - */ -SIGNAL(USART1_RX_vect) -{ - SER_STROBE_ON; - - /* Disable Recv complete IRQ */ - //UCSR1B &= ~BV(RXCIE); - //IRQ_ENABLE; - - /* Should be read before UDR */ - ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); - - /* To avoid an IRQ storm, we must _always_ read the UDR even when we're - * not going to accept the incoming data - */ - char c = UDR1; - struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo; - //ASSERT_VALID_FIFO(rxfifo); - - if (UNLIKELY(fifo_isfull(rxfifo))) - ser_uart1->status |= SERRF_RXFIFOOVERRUN; - else - { - fifo_push(rxfifo, c); -#if CONFIG_SER_HWHANDSHAKE - if (fifo_isfull(rxfifo)) - RTS_OFF; -#endif - } - /* Re-enable receive complete int */ - //IRQ_DISABLE; - //UCSR1B |= BV(RXCIE); - - SER_STROBE_OFF; -} - -#endif // AVR_HAS_UART1 - - -/** - * SPI interrupt handler - */ -SIGNAL(SIG_SPI) -{ - SER_STROBE_ON; - - /* Read incoming byte. */ - if (!fifo_isfull(&ser_spi->rxfifo)) - fifo_push(&ser_spi->rxfifo, SPDR); - /* - * FIXME - else - ser_spi->status |= SERRF_RXFIFOOVERRUN; - */ - - /* Send */ - if (!fifo_isempty(&ser_spi->txfifo)) - SPDR = fifo_pop(&ser_spi->txfifo); - else - UARTDescs[SER_SPI].sending = false; - - SER_STROBE_OFF; -} diff --git a/cpu/avr/drv/ser_avr.h b/cpu/avr/drv/ser_avr.h deleted file mode 100644 index 4b5518b4..00000000 --- a/cpu/avr/drv/ser_avr.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * \file - * - * - * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ - * - * \author Daniele Basile - * - * \brief Low-level serial module for AVR (interface). - */ - -#ifndef DRV_SER_AVR_H -#define DRV_SER_AVR_H - -#include /* BV() */ -#include /* uint32_t */ - -typedef uint8_t serstatus_t; - -/* Software errors */ -#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ -#define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */ -#define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */ - -/* -* Hardware errors. -* These flags map directly to the AVR UART Status Register (USR). -*/ -#define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */ -#define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */ -#define SERRF_PARITYERROR BV(7) /**< Parity error */ -#define SERRF_NOISEERROR 0 /**< Unsupported */ - - -/** - * \name Serial hw numbers - * - * \{ - */ -enum -{ -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 - SER_UART0, - SER_UART1, - SER_SPI, -#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8 - SER_UART0, - SER_SPI, -#else - #error unknown architecture -#endif - SER_CNT /**< Number of serial ports */ -}; -/*\}*/ - -#endif /* DRV_SER_AVR_H */ diff --git a/cpu/avr/drv/ser_simple_avr.c b/cpu/avr/drv/ser_simple_avr.c deleted file mode 100644 index d71ce585..00000000 --- a/cpu/avr/drv/ser_simple_avr.c +++ /dev/null @@ -1,194 +0,0 @@ -/** - * \file - * - * - * \brief Simple serial I/O driver - * - * \version $Id$ - * \author Francesco Sacchi - */ - -/*#* - *#* $Log$ - *#* Revision 1.2 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.1 2005/04/12 01:37:50 bernie - *#* Import into DevLib. - *#* - *#* Revision 1.7 2005/01/23 12:24:27 bernie - *#* Include macros.h for BV(). - *#* - *#* Revision 1.6 2004/10/20 13:40:54 batt - *#* Put {} instead of ; after while loop. - *#* - *#* Revision 1.5 2004/10/20 13:39:40 batt - *#* Reformat. - *#* - *#* Revision 1.4 2004/10/20 13:30:02 batt - *#* Optimization of UCSR0C writing - *#* - *#* Revision 1.3 2004/10/14 15:55:32 batt - *#* Add ser_purge. - *#* - *#* Revision 1.2 2004/10/14 14:46:59 batt - *#* Change baudrate calculation. - *#* - *#* Revision 1.1 2004/10/13 16:35:36 batt - *#* New (simple) serial driver. - *#*/ -#include "ser_simple.h" - -#include -#include -#include /* BV() */ -#include - -#include - -/** - * Send a character over the serial line. - * - * \return the character sent. - */ -int _ser_putchar(int c) -{ - /* Disable Rx to avoid echo*/ - UCSR0B &= ~BV(RXEN); - /* Enable tx*/ - UCSR0B |= BV(TXEN); - /* Prepare transmission */ - UDR0 = c; - /* Wait until byte sent */ - while (!(UCSR0A & BV(TXC))) {} - /* Disable tx to avoid short circuit when tx and rx share the same wire. */ - UCSR0B &= ~BV(TXEN); - /* Enable Rx */ - UCSR0B |= BV(RXEN); - /* Delete TRANSMIT_COMPLETE_BIT flag */ - UCSR0A |= BV(TXC); - return c; -} - - -/** - * Get a character from the serial line. - * If ther is no character in the buffer this function wait until - * one is received (no timeout). - * - * \return the character received. - */ -int _ser_getchar(void) -{ - /* Wait for data */ - while (!(UCSR0A & BV(RXC))) {} - return UDR0; - -} - - -/** - * Get a character from the receiver buffer - * If the buffer is empty, ser_getchar_nowait() returns - * immediatly EOF. - */ -int _ser_getchar_nowait(void) -{ - if (!(UCSR0A & BV(RXC))) return EOF; - else return UDR0; -} - -void _ser_settimeouts(void) -{ -} - -/** - * Set the baudrate. - */ -void _ser_setbaudrate(unsigned long rate) -{ - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; - - UBRR0H = (period) >> 8; - UBRR0L = (period); -} - -/** - * Send a string. - */ -int _ser_print(const char *s) -{ - while(*s) _ser_putchar(*s++); - return 0; -} - - -void _ser_setparity(int parity) -{ - /* Set the new parity */ - UCSR0C |= (UCSR0C & ~(BV(UPM1) | BV(UPM0))) | (parity << UPM0); -} - -/** - * Dummy functions. - */ -void _ser_purge(void) -{ - while (_ser_getchar_nowait() != EOF) {} -} - -/** - * Initialize serial. - */ -struct Serial * _ser_open(void) -{ - /* - * Set Rx and Tx pins as input to avoid short - * circuit when serial is disabled. - */ - DDRE &= ~(BV(PE0)|BV(PE1)); - PORTE &= ~BV(PE0); - PORTE |= BV(PE1); - /* Enable only Rx section */ - UCSR0B = BV(RXEN); - return NULL; -} - - -/** - * Clean up serial port, disabling the associated hardware. - */ -void _ser_close(void) -{ - /* Disable Rx & Tx. */ - UCSR0B &= ~(BV(RXEN) | BV(TXEN)); -} diff --git a/cpu/avr/drv/ser_simple_avr.h b/cpu/avr/drv/ser_simple_avr.h deleted file mode 100644 index ec4cf604..00000000 --- a/cpu/avr/drv/ser_simple_avr.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * \file - * - * - * \brief Simple serial I/O driver - * - * \version $Id$ - * \author Bernardo Innocenti - * \author Francesco Sacchi - */ - -/*#* - *#* $Log$ - *#* Revision 1.2 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.1 2005/04/12 01:37:50 bernie - *#* Import into DevLib. - *#* - *#* Revision 1.5 2004/10/20 13:37:49 batt - *#* Change testing of simple serial instead of ARCH_BOOT in sc driver. - *#* - *#* Revision 1.4 2004/10/15 12:22:04 batt - *#* Readd ';' in setstatus macro. - *#* - *#* Revision 1.3 2004/10/15 12:13:57 batt - *#* Correct \brief header. - *#* - *#* Revision 1.2 2004/10/15 11:54:21 batt - *#* Reformat. - *#* - *#* Revision 1.1 2004/10/13 16:35:36 batt - *#* New (simple) serial driver. - *#* - *#* - */ -#ifndef SER_SIMPLE_H -#define SER_SIMPLE_H - -/* For checking which serial driver is linked */ -#define SER_SIMPLE - -#include -#include - - -#if 0 -#if CPU_AVR - typedef uint8_t serstatus_t; - - /* Software errors */ - #define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ - #define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */ - #define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */ - - /* Hardware errors */ - #define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */ - #define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */ - #define SERRF_PARITYERROR BV(7) /**< Parity error */ -#else - #error unknown architecture -#endif -/*\}*/ - -/** - * \name Serial hw numbers - * - * \{ - */ -enum -{ -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 - SER_UART0, - SER_UART1, - SER_SPI, -#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8 - SER_UART0, - SER_SPI, -#else - #error unknown architecture -#endif - SER_CNT /**< Number of serial ports */ -}; -/*\}*/ -#endif - -/** \name Parity settings for ser_setparity() */ -/*\{*/ -#define SER_PARITY_NONE 0 -#define SER_PARITY_EVEN 2 -#define SER_PARITY_ODD 3 -/*\}*/ - - -/** Serial handle structure */ -struct Serial; - -/* Function prototypes */ -extern int _ser_putchar(int c); -extern int _ser_getchar(void); -extern int _ser_getchar_nowait(void); -/* -extern int ser_write(struct Serial *port, const void *buf, size_t len); -extern int ser_read(struct Serial *port, void *buf, size_t size); - -extern int ser_printf(struct Serial *port, const char *format, ...) FORMAT(__printf__, 2, 3); - -extern int ser_gets(struct Serial *port, char *buf, int size); -extern int ser_gets_echo(struct Serial *port, char *buf, int size, bool echo); -*/ -extern int _ser_print(const char *s); - -extern void _ser_setbaudrate(unsigned long rate); -extern void _ser_setparity(int parity); -extern void _ser_settimeouts(void); -extern void _ser_setstatus(void); -/* -extern void ser_resync(struct Serial *port, time_t delay); -extern void ser_drain(struct Serial *port); -*/ -extern void _ser_purge(void); -extern struct Serial *_ser_open(void); -extern void _ser_close(void); - -/** - * \name Functions implemented as macros - * - * \{ - */ -#define ser_putchar(c, port) _ser_putchar(c) -#define ser_getchar(port) _ser_getchar() -#define ser_getchar_nowait(port) _ser_getchar_nowait() -#define ser_print(port, s) _ser_print(s) -#define ser_setbaudrate(port, y) _ser_setbaudrate(y) -#define ser_setparity(port, par) _ser_setparity(par) -#define ser_settimeouts(port, y, z) _ser_settimeouts() -#define ser_purge(port) _ser_purge() -#define ser_open(port) _ser_open() -#define ser_getstatus(h) 0 -#define ser_setstatus(h, x) do {(void)(x);} while(0) -/* \} */ - -#endif /* SER_SIMPLE_H */ diff --git a/cpu/avr/drv/sipo.c b/cpu/avr/drv/sipo.c deleted file mode 100644 index 014f9463..00000000 --- a/cpu/avr/drv/sipo.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Andrea Grandi - * - * \brief SIPO Module - * - * The SIPO module trasform a serial input in - * a parallel output. Please check hw_sipo.h - * file to customize hardware relative parameters. - * - */ - -#include -#include "sipo.h" - -Serial *sipo_port; - -/** Initialize the SIPO port */ -void sipo_init(void) -{ - CLOCK_LOW; - SET_SOUT_LOW; - LOAD_LOW; - SET_SCK_OUT; - SET_SOUT_OUT; - LOAD_INIT; - sipo_putchar(0x0); - OE_OUT; - OE_LOW; -} - -/** Write a char in the SIPO port and manage the LOAD pin */ -void sipo_putchar(uint8_t c) -{ - for(int i = 0; i <= 7; i++) - { - if((c & BV(i)) == 0) - SET_SOUT_LOW; - else - SET_SOUT_HIGH; - - CLOCK_PULSE; - } - - LOAD_HIGH; - LOAD_LOW; -} - diff --git a/cpu/avr/drv/sipo.h b/cpu/avr/drv/sipo.h deleted file mode 100644 index 15df226a..00000000 --- a/cpu/avr/drv/sipo.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * \file - * - * - * \brief Macro for SIPO_H - * - * - * \version $Id$ - * - * \author Andrea Grandi - */ - -#ifndef SIPO_H -#define SIPO_H - -#include -#include - -void sipo_init(void); -void sipo_putchar(uint8_t c); - -#endif // SIPO_H - diff --git a/cpu/avr/drv/timer_avr.c b/cpu/avr/drv/timer_avr.c deleted file mode 100644 index 4fd82f53..00000000 --- a/cpu/avr/drv/timer_avr.c +++ /dev/null @@ -1,245 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * \author Francesco Sacchi - * - * \brief Low-level timer module for AVR (implementation). - */ - -#include -#include // BV() - -#include -#include - -#include -#include - -#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 - #define REG_TIFR0 TIFR0 - #define REG_TIFR2 TIFR2 - - #define REG_TIMSK0 TIMSK0 - #define REG_TIMSK2 TIMSK2 - - #define REG_TCCR2A TCCR2A - #define REG_TCCR2B TCCR2B - - #define REG_OCR2A OCR2A - - #define BIT_OCF0A OCF0A - #define BIT_OCF2A OCF2A - - #define BIT_OCIE0A OCIE0A - #define BIT_OCIE2A OCIE2A -#else - #define REG_TIFR0 TIFR - #define REG_TIFR2 TIFR - - #define REG_TIMSK0 TIMSK - #define REG_TIMSK2 TIMSK - - #define REG_TCCR2A TCCR2 - #define REG_TCCR2B TCCR2 - - #define REG_OCR2A OCR2 - - #define BIT_OCF0A OCF0 - #define BIT_OCF2A OCF2 - - #define BIT_OCIE0A OCIE0 - #define BIT_OCIE2A OCIE2 -#endif - - -/** HW dependent timer initialization */ -#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0) - - static void timer_hw_init(void) - { - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Reset Timer flags */ - REG_TIFR0 = BV(BIT_OCF0A) | BV(TOV0); - - /* Setup Timer/Counter interrupt */ - ASSR = 0x00; /* Internal system clock */ - TCCR0 = BV(WGM01) /* Clear on Compare match */ - #if TIMER_PRESCALER == 64 - | BV(CS02) - #else - #error Unsupported value of TIMER_PRESCALER - #endif - ; - TCNT0 = 0x00; /* Initialization of Timer/Counter */ - OCR0 = OCR_DIVISOR; /* Timer/Counter Output Compare Register */ - - /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */ - REG_TIMSK0 &= ~BV(TOIE0); - REG_TIMSK0 |= BV(OCIE0); - - IRQ_RESTORE(flags); - } - - INLINE hptime_t timer_hw_hpread(void) - { - return TCNT0; - } - -#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1) - - static void timer_hw_init(void) - { - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Reset Timer overflow flag */ - TIFR |= BV(TOV1); - - /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */ - #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9) - TCCR1A |= BV(WGM11); - TCCR1A &= ~BV(WGM10); - TCCR1B |= BV(WGM12) | BV(CS10); - TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12)); - /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */ - #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8) - TCCR1A |= BV(WGM10); - TCCR1A &= ~BV(WGM11); - TCCR1B |= BV(WGM12) | BV(CS10); - TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12)); - #else - #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS - #endif - - TCNT1 = 0x00; /* initialization of Timer/Counter */ - - /* Enable timer interrupt: Timer/Counter1 Overflow */ - TIMSK |= BV(TOIE1); - - IRQ_RESTORE(flags); - } - - INLINE hptime_t timer_hw_hpread(void) - { - return TCNT1; - } - -#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2) - static void timer_hw_init(void) - { - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Reset Timer flags */ - REG_TIFR2 = BV(BIT_OCF2A) | BV(TOV2); - - /* Setup Timer/Counter interrupt */ - REG_TCCR2A = 0; // TCCR2 reg could be separate or a unique register with both A & B values, this is needed to - REG_TCCR2B = 0; // ensure correct initialization. - - REG_TCCR2A = BV(WGM21); - #if TIMER_PRESCALER == 64 - #if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 - // ATMega1281 & ATMega168 have undocumented differences in timer2 prescaler! - REG_TCCR2B |= BV(CS22); - #else - REG_TCCR2B |= BV(CS21) | BV(CS20); - #endif - #else - #error Unsupported value of TIMER_PRESCALER - #endif - - /* Clear on Compare match & prescaler = 64, internal sys clock. - When changing prescaler change TIMER_HW_HPTICKS_PER_SEC too */ - TCNT2 = 0x00; /* initialization of Timer/Counter */ - REG_OCR2A = OCR_DIVISOR; /* Timer/Counter Output Compare Register */ - - /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */ - REG_TIMSK2 &= ~BV(TOIE2); - REG_TIMSK2 |= BV(BIT_OCIE2A); - - IRQ_RESTORE(flags); - } - - INLINE hptime_t timer_hw_hpread(void) - { - return TCNT2; - } -#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3) - - static void timer_hw_init(void) - { - cpuflags_t flags; - IRQ_SAVE_DISABLE(flags); - - /* Reset Timer overflow flag */ - TIFR |= BV(TOV3); - - /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */ - #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9) - TCCR3A |= BV(WGM31); - TCCR3A &= ~BV(WGM30); - TCCR3B |= BV(WGM32) | BV(CS30); - TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32)); - /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */ - #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8) - TCCR3A |= BV(WGM30); - TCCR3A &= ~BV(WGM31); - TCCR3B |= BV(WGM32) | BV(CS30); - TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32)); - #else - #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS - #endif - - TCNT3 = 0x00; /* initialization of Timer/Counter */ - - /* Enable timer interrupt: Timer/Counter3 Overflow */ - /* ATTENTION! TOIE3 is only on ETIMSK, not TIMSK */ - ETIMSK |= BV(TOIE3); - - IRQ_RESTORE(flags); - } - - INLINE hptime_t timer_hw_hpread(void) - { - return TCNT3; - } - -#else - #error Unimplemented value for CONFIG_TIMER -#endif /* CONFIG_TIMER */ - diff --git a/cpu/avr/drv/timer_avr.h b/cpu/avr/drv/timer_avr.h deleted file mode 100644 index 74414263..00000000 --- a/cpu/avr/drv/timer_avr.h +++ /dev/null @@ -1,186 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * \author Francesco Sacchi - * - * \brief Low-level timer module for AVR (interface). - */ - -/*#* - *#* $Log$ - *#* Revision 1.32 2007/10/08 12:14:32 batt - *#* Fix some review issues. - *#* - *#* Revision 1.31 2007/10/07 12:30:55 batt - *#* Add default timer for AVR. - *#* - *#* Revision 1.30 2007/06/07 14:35:12 batt - *#* Merge from project_ks. - *#* - *#* Revision 1.29 2007/03/21 11:01:36 batt - *#* Add missing support for ATMega1281. - *#* - *#* Revision 1.28 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.27 2006/05/18 00:38:24 bernie - *#* Use hw_cpu.h instead of ubiquitous hw.h. - *#* - *#* Revision 1.26 2006/02/21 21:28:02 bernie - *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. - *#* - *#* Revision 1.25 2005/07/19 07:26:37 bernie - *#* Refactor to decouple timer ticks from milliseconds. - *#* - *#* Revision 1.24 2005/04/11 19:10:28 bernie - *#* Include top-level headers from cfg/ subdir. - *#* - *#* Revision 1.23 2005/03/01 23:24:51 bernie - *#* Tweaks for avr-libc 1.2.x. - *#* - *#* Revision 1.21 2004/12/13 12:07:06 bernie - *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE. - *#* - *#* Revision 1.20 2004/11/16 20:59:46 bernie - *#* Include explicitly. - *#* - *#* Revision 1.19 2004/10/19 08:56:41 bernie - *#* TIMER_STROBE_ON, TIMER_STROBE_OFF, TIMER_STROBE_INIT: Move from timer_avr.h to timer.h, where they really belong. - *#* - *#* Revision 1.18 2004/09/20 03:31:03 bernie - *#* Fix racy racy code. - *#*/ -#ifndef DRV_TIMER_AVR_H -#define DRV_TIMER_AVR_H - -#include /* CONFIG_TIMER */ -#include /* uint8_t */ -#include /* DIV_ROUND */ -#include /* CLOCK_FREQ */ - -/** - * \name Values for CONFIG_TIMER. - * - * Select which hardware timer interrupt to use for system clock and softtimers. - * \note The timer 1 overflow mode set the timer as a 24 kHz PWM. - * - * \{ - */ -#define TIMER_ON_OUTPUT_COMPARE0 1 -#define TIMER_ON_OVERFLOW1 2 -#define TIMER_ON_OUTPUT_COMPARE2 3 -#define TIMER_ON_OVERFLOW3 4 - -#define TIMER_DEFAULT TIMER_ON_OUTPUT_COMPARE0 ///< Default system timer -/* \} */ - -/* - * Hardware dependent timer initialization. - */ -#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0) - - #define TIMER_PRESCALER 64 - #define TIMER_HW_BITS 8 - #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE0) - #define TIMER_TICKS_PER_SEC 1000 - #define TIMER_HW_CNT OCR_DIVISOR - - /// Type of time expressed in ticks of the hardware high-precision timer - typedef uint8_t hptime_t; - -#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1) - - #define TIMER_PRESCALER 1 - #define TIMER_HW_BITS 8 - /** This value is the maximum in overflow based timers. */ - #define TIMER_HW_CNT (1 << TIMER_HW_BITS) - #define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW1) - #define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT) - - /// Type of time expressed in ticks of the hardware high precision timer - typedef uint16_t hptime_t; - -#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2) - - #define TIMER_PRESCALER 64 - #define TIMER_HW_BITS 8 - #if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168 - #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE2A) - #else - #define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE2) - #endif - #define TIMER_TICKS_PER_SEC 1000 - /** Value for OCR register in output-compare based timers. */ - #define TIMER_HW_CNT OCR_DIVISOR - - - /// Type of time expressed in ticks of the hardware high precision timer - typedef uint8_t hptime_t; - -#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3) - - #define TIMER_PRESCALER 1 - #define TIMER_HW_BITS 8 - /** This value is the maximum in overflow based timers. */ - #define TIMER_HW_CNT (1 << TIMER_HW_BITS) - #define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW3) - #define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT) - - /// Type of time expressed in ticks of the hardware high precision timer - typedef uint16_t hptime_t; -#else - - #error Unimplemented value for CONFIG_TIMER -#endif /* CONFIG_TIMER */ - - -/** Frequency of the hardware high precision timer. */ -#define TIMER_HW_HPTICKS_PER_SEC DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER) - -/** - * System timer: additional division after the prescaler - * 12288000 / 64 / 192 (0..191) = 1 ms - */ -#define OCR_DIVISOR (DIV_ROUND(DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC) - 1) - -/** Not needed, IRQ timer flag cleared automatically */ -#define timer_hw_irq() do {} while (0) - -/** Not needed, timer IRQ handler called only for timer source */ -#define timer_hw_triggered() (true) - - -#endif /* DRV_TIMER_AVR_H */ diff --git a/cpu/avr/drv/timer_simple_avr.c b/cpu/avr/drv/timer_simple_avr.c deleted file mode 100644 index 2c076414..00000000 --- a/cpu/avr/drv/timer_simple_avr.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * \file - * - * - * \brief Some simple delay routines. - * - * Simple serial driver - * \version $Id$ - * \author Francesco Sacchi - */ - -/*#* - *#* $Log$ - *#* Revision 1.2 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.1 2005/04/12 01:37:50 bernie - *#* Import into DevLib. - *#* - *#* Revision 1.8 2005/04/12 01:18:09 bernie - *#* time_t -> mtime_t. - *#* - *#* Revision 1.7 2005/03/20 04:18:41 bernie - *#* Fixes for CONFIG_WATCHDOG == 0. - *#* - *#* Revision 1.6 2004/10/27 09:38:07 aleph - *#* Bootloader working with watchdog enabled - *#* - *#* Revision 1.5 2004/10/20 10:00:37 customer_pw - *#* Add newline at eof - *#* - *#* Revision 1.4 2004/10/14 14:13:09 batt - *#* Add comment. - *#* - *#* Revision 1.3 2004/10/14 13:29:20 batt - *#* Fix 0ms delay bug. - *#* - *#* Revision 1.2 2004/10/13 17:53:05 batt - *#* Delay with hw timer. - *#* - *#* Revision 1.1 2004/10/13 16:36:32 batt - *#* Simplified timer delay routines. - *#* - *#*/ -#include "hw.h" -#include "timer_simple.h" -#include -#include -#include -#include /* BV() */ - -#include - - -#define MS_PER_SEC 1000UL -#define TIMER_PRESCALER 64UL -#define TIMER_DELAY_1MS (255 - CLOCK_FREQ / TIMER_PRESCALER / MS_PER_SEC) - -/** - * Wait \a time ms using timer 0. - * - */ -void timer_delay(mtime_t time) -{ - /* Set timer clock to clock_freq/64 */ - TCCR0 = BV(CS02); - - while (time--) - { - /* Initialize timer counter register */ - TCNT0 = TIMER_DELAY_1MS; - /* Clear overflow bit. */ - TIFR |= BV(TOV0); - /* Wait overflow. */ - while (!(TIFR & BV(TOV0))); -#if CONFIG_WATCHDOG - wdt_reset(); -#endif - } -} diff --git a/cpu/avr/drv/timer_simple_avr.h b/cpu/avr/drv/timer_simple_avr.h deleted file mode 100644 index 4815389e..00000000 --- a/cpu/avr/drv/timer_simple_avr.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * \file - * - * - * \brief Simple delay routine - * - * \version $Id$ - * \author Francesco Sacchi - */ - -/*#* - *#* $Log$ - *#* Revision 1.2 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.1 2005/04/12 01:37:50 bernie - *#* Import into DevLib. - *#* - *#* Revision 1.2 2005/04/12 01:18:09 bernie - *#* time_t -> mtime_t. - *#* - *#* Revision 1.1 2004/10/13 16:36:32 batt - *#* Simplified timer delay routines. - *#* - *#* - */ -#ifndef TIMER_SIMPLE_H -#include - -extern void timer_delay(mtime_t time); -#define TIMER_SIMPLE_H - -#endif /* TIMER_SIMPLE_H */ diff --git a/cpu/avr/drv/twi_avr.c b/cpu/avr/drv/twi_avr.c deleted file mode 100644 index bd4fcfd7..00000000 --- a/cpu/avr/drv/twi_avr.c +++ /dev/null @@ -1,266 +0,0 @@ -/** - * \file - * - * - * \brief Driver for the AVR ATMega TWI (implementation) - * - * \version $Id$ - * - * \author Stefano Fedrigo - * \author Bernardo Innocenti - */ - -#include "twi.h" - -#include -#include -#include -#include // BV() -#include /* CLOCK_FREQ */ -#include - -#include - - -/* Wait for TWINT flag set: bus is ready */ -#define WAIT_TWI_READY do {} while (!(TWCR & BV(TWINT))) - -#define READ_BIT BV(0) - - -/** - * Send START condition on the bus. - * - * \return true on success, false otherwise. - */ -static bool twi_start(void) -{ - TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN); - WAIT_TWI_READY; - - if (TW_STATUS == TW_START || TW_STATUS == TW_REP_START) - return true; - - kprintf("!TW_(REP)START: %x\n", TWSR); - return false; -} - - -/** - * Send START condition and select slave for write. - * \c id is the device id comprehensive of address left shifted by 1. - * The LSB of \c id is ignored and reset to 0 for write operation. - * - * \return true on success, false otherwise. - */ -bool twi_start_w(uint8_t id) -{ - /* - * Loop on the select write sequence: when the eeprom is busy - * writing previously sent data it will reply to the SLA_W - * control byte with a NACK. In this case, we must - * keep trying until the eeprom responds with an ACK. - */ - while (twi_start()) - { - TWDR = id & ~READ_BIT; - TWCR = BV(TWINT) | BV(TWEN); - WAIT_TWI_READY; - - if (TW_STATUS == TW_MT_SLA_ACK) - return true; - else if (TW_STATUS != TW_MT_SLA_NACK) - { - kprintf("!TW_MT_SLA_(N)ACK: %x\n", TWSR); - break; - } - } - - return false; -} - - -/** - * Send START condition and select slave for read. - * \c id is the device id comprehensive of address left shifted by 1. - * The LSB of \c id is ignored and set to 1 for read operation. - * - * \return true on success, false otherwise. - */ -bool twi_start_r(uint8_t id) -{ - if (twi_start()) - { - TWDR = id | READ_BIT; - TWCR = BV(TWINT) | BV(TWEN); - WAIT_TWI_READY; - - if (TW_STATUS == TW_MR_SLA_ACK) - return true; - - kprintf("!TW_MR_SLA_ACK: %x\n", TWSR); - } - - return false; -} - - -/** - * Send STOP condition. - */ -void twi_stop(void) -{ - TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO); -} - - -/** - * Put a single byte in master transmitter mode - * to the selected slave device through the TWI bus. - * - * \return true on success, false on error. - */ -bool twi_put(const uint8_t data) -{ - TWDR = data; - TWCR = BV(TWINT) | BV(TWEN); - WAIT_TWI_READY; - if (TW_STATUS != TW_MT_DATA_ACK) - { - kprintf("!TW_MT_DATA_ACK: %x\n", TWSR); - return false; - } - return true; -} - - -/** - * Send a sequence of bytes in master transmitter mode - * to the selected slave device through the TWI bus. - * - * \return true on success, false on error. - */ -bool twi_send(const void *_buf, size_t count) -{ - const uint8_t *buf = (const uint8_t *)_buf; - - while (count--) - { - if (!twi_put(*buf++)) - return false; - } - return true; -} - - -/** - * Receive a sequence of one or more bytes from the - * selected slave device in master receive mode through - * the TWI bus. - * - * Received data is placed in \c buf. - * - * \return true on success, false on error - */ -bool twi_recv(void *_buf, size_t count) -{ - uint8_t *buf = (uint8_t *)_buf; - - /* - * When reading the last byte the TWEA bit is not - * set, and the eeprom should answer with NACK - */ - while (count--) - { - TWCR = BV(TWINT) | BV(TWEN) | (count ? BV(TWEA) : 0); - WAIT_TWI_READY; - - if (count) - { - if (TW_STATUS != TW_MR_DATA_ACK) - { - kprintf("!TW_MR_DATA_ACK: %x\n", TWSR); - return false; - } - } - else - { - if (TW_STATUS != TW_MR_DATA_NACK) - { - kprintf("!TW_MR_DATA_NACK: %x\n", TWSR); - return false; - } - } - *buf++ = TWDR; - } - - return true; -} - - -/** - * Initialize TWI module. - */ -void twi_init(void) -{ - ATOMIC( - /* - * This is pretty useless according to AVR's datasheet, - * but it helps us driving the TWI data lines on boards - * where the bus pull-up resistors are missing. This is - * probably due to some unwanted interaction between the - * port pin and the TWI lines. - */ -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 - PORTD |= BV(PD0) | BV(PD1); - DDRD |= BV(PD0) | BV(PD1); -#elif CPU_AVR_ATMEGA8 - PORTC |= BV(PC4) | BV(PC5); - DDRC |= BV(PC4) | BV(PC5); -#else - #error Unsupported architecture -#endif - - /* - * Set speed: - * F = CLOCK_FREQ / (16 + 2*TWBR * 4^TWPS) - */ - #ifndef CONFIG_TWI_FREQ - #warning Using default value of 300000L for CONFIG_TWI_FREQ - #define CONFIG_TWI_FREQ 300000L /* ~300 kHz */ - #endif - #define TWI_PRESC 1 /* 4 ^ TWPS */ - - TWBR = (CLOCK_FREQ / (2 * CONFIG_TWI_FREQ * TWI_PRESC)) - (8 / TWI_PRESC); - TWSR = 0; - TWCR = BV(TWEN); - ); -} diff --git a/cpu/avr/drv/twi_avr.h b/cpu/avr/drv/twi_avr.h deleted file mode 100644 index a55cf64b..00000000 --- a/cpu/avr/drv/twi_avr.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Stefano Fedrigo - * \author Bernardo Innocenti - * - * \brief Driver for the AVR ATMega TWI (interface) - */ - -/*#* - *#* $Log$ - *#* Revision 1.5 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.4 2006/03/20 17:49:49 bernie - *#* Make the TWI driver more generic to work with devices other than EEPROMS. - *#* - *#* Revision 1.3 2005/04/11 19:10:28 bernie - *#* Include top-level headers from cfg/ subdir. - *#* - *#* Revision 1.2 2005/02/18 11:19:52 bernie - *#* Update copyright info. - *#* - *#*/ -#ifndef DRV_TWI_H -#define DRV_TWI_H - -#include - -bool twi_start_w(uint8_t id); -bool twi_start_r(uint8_t id); -void twi_stop(void); -bool twi_put(const uint8_t data); -bool twi_send(const void *_buf, size_t count); -bool twi_recv(void *_buf, size_t count); -void twi_init(void); - -#endif /* DRV_EEPROM_H */ diff --git a/cpu/detect.h b/cpu/detect.h deleted file mode 100644 index af2ecd07..00000000 --- a/cpu/detect.h +++ /dev/null @@ -1,238 +0,0 @@ -/** - * \file - * - * - * \brief CPU detection through special preprocessor macros - */ -#ifndef CPU_DETECT_H -#define CPU_DETECT_H - -#if defined(__arm__) /* GCC */ \ - || defined(__ARM4TM__) /* IAR: defined for all cores >= 4tm */ - #define CPU_ARM 1 - #define CPU_ID arm - - // AT91SAM7S core family - #if defined(__ARM_AT91SAM7S32__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7S32 1 - #else - #define CPU_ARM_AT91SAM7S32 0 - #endif - - #if defined(__ARM_AT91SAM7S64__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7S64 1 - #else - #define CPU_ARM_AT91SAM7S64 0 - #endif - - #if defined(__ARM_AT91SAM7S128__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7S128 1 - #else - #define CPU_ARM_AT91SAM7S128 0 - #endif - - #if defined(__ARM_AT91SAM7S256__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7S256 1 - #else - #define CPU_ARM_AT91SAM7S256 0 - #endif - - // AT91SAM7X core family - #if defined(__ARM_AT91SAM7X128__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7X128 1 - #else - #define CPU_ARM_AT91SAM7X128 0 - #endif - - #if defined(__ARM_AT91SAM7X256__) - #define CPU_ARM_AT91 1 - #define CPU_ARM_AT91SAM7X256 1 - #else - #define CPU_ARM_AT91SAM7X256 0 - #endif - - - #if defined(CPU_ARM_AT91) - #if CPU_ARM_AT91SAM7S32 + CPU_ARM_AT91SAM7S64 \ - + CPU_ARM_AT91SAM7S128 + CPU_ARM_AT91SAM7S256 \ - + CPU_ARM_AT91SAM7X128 + CPU_ARM_AT91SAM7X256 != 1 - #error ARM CPU configuration error - #endif - - /* #elif Add other ARM families here */ - #else - #define CPU_ATM_AT91 0 - #endif - - - #if CPU_ARM_AT91 + 0 /* Add other ARM families here */ != 1 - #error ARM CPU configuration error - #endif -#else - #define CPU_ARM 0 - - /* ARM Families */ - #define CPU_ARM_AT91 0 - - /* ARM CPUs */ - #define CPU_ARM_AT91SAM7S32 0 - #define CPU_ARM_AT91SAM7S64 0 - #define CPU_ARM_AT91SAM7S128 0 - #define CPU_ARM_AT91SAM7S256 0 - #define CPU_ARM_AT91SAM7X128 0 - #define CPU_ARM_AT91SAM7X256 0 -#endif - -#if (defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)) \ - && !defined(__ARM4TM__) /* IAR: if not ARM assume I196 */ - #warning Assuming CPU is I196 - #define CPU_I196 1 - #define CPU_ID i196 -#else - #define CPU_I196 0 -#endif - -#if defined(__i386__) /* GCC */ \ - || (defined(_M_IX86) && !defined(_WIN64)) /* MSVC */ - #define CPU_X86 1 - #define CPU_X86_32 1 - #define CPU_X86_64 0 - #define CPU_ID x86 -#elif defined(__x86_64__) /* GCC */ \ - || (defined(_M_IX86) && defined(_WIN64)) /* MSVC */ - #define CPU_X86 1 - #define CPU_X86_32 0 - #define CPU_X86_64 1 - #define CPU_ID x86 -#else - #define CPU_X86 0 - #define CPU_I386 0 - #define CPU_X86_64 0 -#endif - -#if defined (_ARCH_PPC) || defined(_ARCH_PPC64) - #define CPU_PPC 1 - #define CPU_ID ppc - #if defined(_ARCH_PPC) - #define CPU_PPC32 1 - #else - #define CPU_PPC32 0 - #endif - #if defined(_ARCH_PPC64) - #define CPU_PPC64 1 - #else - #define CPU_PPC64 0 - #endif -#else - #define CPU_PPC 0 - #define CPU_PPC32 0 - #define CPU_PPC64 0 -#endif - -#if defined(__m56800E__) || defined(__m56800__) - #define CPU_DSP56K 1 - #define CPU_ID dsp56k -#else - #define CPU_DSP56K 0 -#endif - -#if defined (__AVR__) - #define CPU_AVR 1 - #define CPU_ID avr - - #if defined(__AVR_ATmega64__) - #define CPU_AVR_ATMEGA64 1 - #else - #define CPU_AVR_ATMEGA64 0 - #endif - - #if defined(__AVR_ATmega103__) - #define CPU_AVR_ATMEGA103 1 - #else - #define CPU_AVR_ATMEGA103 0 - #endif - - #if defined(__AVR_ATmega128__) - #define CPU_AVR_ATMEGA128 1 - #else - #define CPU_AVR_ATMEGA128 0 - #endif - - #if defined(__AVR_ATmega8__) - #define CPU_AVR_ATMEGA8 1 - #else - #define CPU_AVR_ATMEGA8 0 - #endif - - #if defined(__AVR_ATmega168__) - #define CPU_AVR_ATMEGA168 1 - #else - #define CPU_AVR_ATMEGA168 0 - #endif - - #if defined(__AVR_ATmega1281__) - #define CPU_AVR_ATMEGA1281 1 - #else - #define CPU_AVR_ATMEGA1281 0 - #endif - - #if CPU_AVR_ATMEGA64 + CPU_AVR_ATMEGA103 + CPU_AVR_ATMEGA128 \ - + CPU_AVR_ATMEGA8 + CPU_AVR_ATMEGA168 + CPU_AVR_ATMEGA1281 != 1 - #error AVR CPU configuration error - #endif -#else - #define CPU_AVR 0 - #define CPU_AVR_ATMEGA8 0 - #define CPU_AVR_ATMEGA168 0 - #define CPU_AVR_ATMEGA64 0 - #define CPU_AVR_ATMEGA103 0 - #define CPU_AVR_ATMEGA128 0 - #define CPU_AVR_ATMEGA1281 0 -#endif - - -/* Self-check for the detection: only one CPU must be detected */ -#if CPU_ARM + CPU_I196 + CPU_X86 + CPU_PPC + CPU_DSP56K + CPU_AVR == 0 - #error Unknown CPU -#elif !defined(CPU_ID) - #error CPU_ID not defined -#elif CPU_ARM + CPU_I196 + CPU_X86 + CPU_PPC + CPU_DSP56K + CPU_AVR != 1 - #error Internal CPU configuration error -#endif - - -#endif /* CPU_DETECT_H */ diff --git a/cpu/dsp56k/drv/buzzerled_dsp56k.h b/cpu/dsp56k/drv/buzzerled_dsp56k.h deleted file mode 100644 index 4eafa57b..00000000 --- a/cpu/dsp56k/drv/buzzerled_dsp56k.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * \file - * - * - * \brief Hardware support for buzzers and leds in DSP56K-based boards - * - * \version $Id$ - * - * \author Giovanni Bajo - */ - -/*#* - *#* $Log$ - *#* Revision 1.7 2006/07/19 12:56:25 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.6 2005/11/04 16:20:02 bernie - *#* Fix reference to README.devlib in header. - *#* - *#* Revision 1.5 2005/04/11 19:10:27 bernie - *#* Include top-level headers from cfg/ subdir. - *#* - *#* Revision 1.4 2004/11/16 21:54:43 bernie - *#* Changes for SC Monoboard support. - *#* - *#* Revision 1.3 2004/08/25 14:12:08 rasky - *#* Aggiornato il comment block dei log RCS - *#* - *#* Revision 1.2 2004/06/03 11:27:09 bernie - *#* Add dual-license information. - *#* - *#* Revision 1.1 2004/05/23 18:36:05 bernie - *#* Import buzzerled driver. - *#* - *#*/ - -#ifndef DRV_BUZZERLED_DSP56K_H -#define DRV_BUZZERLED_DSP56K_H - -#include -#include -#include "pwm.h" - -#if ARCH & ARCH_HECO - -/** - * \name Connection of the leds to the DSP: - *
- *   Led       Line    DSP Pin
- *   ---------------------------
- *   YELLOW    T2      HOME1/TB3
- *   GREEN     T3      INDX1/TB2
- *   RED       T4      PHB1/TB1
- * 
- */ - -INLINE bool bld_is_inverted_intensity(enum BLD_DEVICE device) -{ - return (device == BLD_GREEN_LED - || device == BLD_YELLOW_LED - || device == BLD_RED_LED); -} - -INLINE bool bld_is_pwm(enum BLD_DEVICE device) -{ - // Only the buzzer is connected to a PWM - return (device == BLD_BUZZER || device == BLD_READY_LED); -} - -INLINE bool bld_is_timer(enum BLD_DEVICE device) -{ - // LEDs are connected to timers - return (device == BLD_GREEN_LED || device == BLD_YELLOW_LED || device == BLD_RED_LED); -} - -INLINE uint16_t bld_get_pwm(enum BLD_DEVICE device) -{ - switch (device) - { - default: ASSERT(0); - case BLD_BUZZER: return 5; // PWMA5 - case BLD_READY_LED: return 9; // PWMB3 - } -} - - -INLINE struct REG_TIMER_STRUCT* bld_get_timer(enum BLD_DEVICE device) -{ - switch (device) - { - default: ASSERT(0); - case BLD_GREEN_LED: return ®_TIMER_B[2]; - case BLD_RED_LED: return ®_TIMER_B[1]; - case BLD_YELLOW_LED: return ®_TIMER_B[3]; - } -} - -INLINE void bld_hw_init(void) -{ -} - -INLINE void bld_hw_set(enum BLD_DEVICE device, bool enable) -{ - if (bld_is_inverted_intensity(device)) - enable = !enable; - - // Handle a BLD connected to a PWM - if (bld_is_pwm(device)) - { - struct PWM* pwm = pwm_get_handle(bld_get_pwm(device)); - - pwm_set_enable(pwm, false); - pwm_set_dutycycle_percent(pwm, (enable ? 50 : 0)); - pwm_set_enable(pwm, true); - } - else if (bld_is_timer(device)) - { - struct REG_TIMER_STRUCT* timer = bld_get_timer(device); - - // Check that the timer is currently stopped, and the OFLAG is not - // controlled by another timer. Otherwise, the led is already - // controlled by the timer, and we cannot correctly set it - // on/off without reprogramming the timer. - ASSERT((timer->CTRL & REG_TIMER_CTRL_MODE_MASK) == REG_TIMER_CTRL_MODE_STOP); - ASSERT(!(timer->SCR & REG_TIMER_SCR_EEOF)); - - // Check also that polarity is correct - ASSERT(!(timer->SCR & REG_TIMER_SCR_OPS)); - - // Without programming the timer, we have a way to manually force a certain - // value on the external pin. We also need to enable the output pin. - timer->SCR &= ~REG_TIMER_SCR_VAL_1; - timer->SCR |= REG_TIMER_SCR_OEN | - REG_TIMER_SCR_FORCE | - (!enable ? REG_TIMER_SCR_VAL_0 : REG_TIMER_SCR_VAL_1); - } - else - ASSERT(0); -} - -#elif ARCH & ARCH_SC - -// We do not need inline functions here, because constant propagation is not big deal here -void bld_hw_init(void); -void bld_hw_set(enum BLD_DEVICE device, bool enable); - -#endif - -#endif /* DRV_BUZZERLED_DSP56K_H */ diff --git a/cpu/dsp56k/drv/kdebug_dsp56k.c b/cpu/dsp56k/drv/kdebug_dsp56k.c deleted file mode 100644 index 67c9a9db..00000000 --- a/cpu/dsp56k/drv/kdebug_dsp56k.c +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file - * - * - * \brief General pourpose debug support for embedded systems (implementation). - * - * \version $Id$ - * \author Bernardo Innocenti - * \author Stefano Fedrigo - */ - -#error Revise me! - -/* Debugging go through the JTAG interface. The MSL library already - implements the console I/O correctly. */ -#include -#define KDBG_WAIT_READY() do { } while (0) -#define KDBG_WRITE_CHAR(c) __put_char(c, stdout) -#define KDBG_MASK_IRQ(old) do { (void)(old); } while (0) -#define KDBG_RESTORE_IRQ(old) do { (void)(old); } while (0) -typedef uint8_t kdbg_irqsave_t; /* unused */ -#if CONFIG_KDEBUG_PORT == 666 - #error BITBANG debug console missing for this platform - -#define kdbg_hw_init() do {} while (0) ///< Not needed diff --git a/cpu/dsp56k/drv/ser_dsp56k.c b/cpu/dsp56k/drv/ser_dsp56k.c deleted file mode 100644 index d69e0c57..00000000 --- a/cpu/dsp56k/drv/ser_dsp56k.c +++ /dev/null @@ -1,367 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Stefano Fedrigo - * \author Giovanni Bajo - * - * \brief DSP5680x CPU specific serial I/O driver - */ - - -#include -#include -#include -#include -#include -#include - -// GPIO E is shared with SPI (in DSP56807). Pins 0&1 are TXD0 and RXD0. To use -// the serial, we need to disable the GPIO functions on them. -#define REG_GPIO_SERIAL_0 REG_GPIO_E -#define REG_GPIO_SERIAL_MASK_0 0x03 - -#define REG_GPIO_SERIAL_1 REG_GPIO_D -#define REG_GPIO_SERIAL_MASK_1 0xC0 - - -// Check flag consistency -#if (SERRF_PARITYERROR != REG_SCI_SR_PF) || \ - (SERRF_RXSROVERRUN != REG_SCI_SR_OR) || \ - (SERRF_FRAMEERROR != REG_SCI_SR_FE) || \ - (SERRF_NOISEERROR != REG_SCI_SR_NF) - #error error flags do not match with register bits -#endif - -static unsigned char ser0_fifo_rx[CONFIG_SER0_FIFOSIZE_RX]; -static unsigned char ser0_fifo_tx[CONFIG_SER0_FIFOSIZE_TX]; -static unsigned char ser1_fifo_rx[CONFIG_SER1_FIFOSIZE_RX]; -static unsigned char ser1_fifo_tx[CONFIG_SER1_FIFOSIZE_TX]; - -#if CONFIG_SER_MULTI - #include - - #define MAX_MULTI_GROUPS 1 - - struct Semaphore multi_sems[MAX_MULTI_GROUPS]; -#endif - - -struct SCI -{ - struct SerialHardware hw; - struct Serial* serial; - volatile struct REG_SCI_STRUCT* regs; - IRQ_VECTOR irq_tx; - IRQ_VECTOR irq_rx; - int num_group; - int id; -}; - -static inline void enable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs) -{ - regs->CR |= REG_SCI_CR_TEIE | REG_SCI_CR_TIIE; -} - -static inline void enable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs) -{ - regs->CR |= REG_SCI_CR_RIE; -} - -static inline void disable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs) -{ - regs->CR &= ~(REG_SCI_CR_TEIE | REG_SCI_CR_TIIE); -} - -static inline void disable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs) -{ - regs->CR &= ~(REG_SCI_CR_RIE | REG_SCI_CR_REIE); -} - -static inline void disable_tx_irq(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - disable_tx_irq_bare(hw->regs); -} - -static inline void disable_rx_irq(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - disable_rx_irq_bare(hw->regs); -} - -static inline void enable_tx_irq(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - enable_tx_irq_bare(hw->regs); -} - -static inline void enable_rx_irq(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - enable_rx_irq_bare(hw->regs); -} - -static inline bool tx_irq_enabled(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - return (hw->regs->CR & REG_SCI_CR_TEIE); -} - -static void tx_isr(const struct SCI *hw) -{ -#pragma interrupt warn - volatile struct REG_SCI_STRUCT* regs = hw->regs; - - if (fifo_isempty(&hw->serial->txfifo)) - disable_tx_irq_bare(regs); - else - { - // Clear transmitter flags before sending data - (void)regs->SR; - regs->DR = fifo_pop(&hw->serial->txfifo); - } -} - -static void rx_isr(const struct SCI *hw) -{ -#pragma interrupt warn - volatile struct REG_SCI_STRUCT* regs = hw->regs; - - // Propagate errors - hw->serial->status |= regs->SR & (SERRF_PARITYERROR | - SERRF_RXSROVERRUN | - SERRF_FRAMEERROR | - SERRF_NOISEERROR); - - /* - * Serial IRQ can happen for two reason: data ready (RDRF) or overrun (OR) - * If the data is ready, we need to fetch it from the data register or - * the interrupt will retrigger immediatly. In case of overrun, instead, - * the value of the data register is meaningless. - */ - if (regs->SR & REG_SCI_SR_RDRF) - { - unsigned char data = regs->DR; - - if (fifo_isfull(&hw->serial->rxfifo)) - hw->serial->status |= SERRF_RXFIFOOVERRUN; - else - fifo_push(&hw->serial->rxfifo, data); - } - - // Writing anything to the status register clear the error bits. - regs->SR = 0; -} - -static void init(struct SerialHardware* _hw, struct Serial* ser) -{ - struct SCI* hw = (struct SCI*)_hw; - volatile struct REG_SCI_STRUCT* regs = hw->regs; - - // Clear status register (IRQ/status flags) - (void)regs->SR; - regs->SR = 0; - - // Clear data register - (void)regs->DR; - - // Install the handlers and set priorities for both IRQs - irq_install(hw->irq_tx, (isr_t)tx_isr, hw); - irq_install(hw->irq_rx, (isr_t)rx_isr, hw); - irq_setpriority(hw->irq_tx, IRQ_PRIORITY_SCI_TX); - irq_setpriority(hw->irq_rx, IRQ_PRIORITY_SCI_RX); - - // Activate the RX error interrupts, and RX/TX transmissions - regs->CR = REG_SCI_CR_TE | REG_SCI_CR_RE; - enable_rx_irq_bare(regs); - - // Disable GPIO pins for TX and RX lines - // \todo this should be divided into serial 0 and 1 - REG_GPIO_SERIAL_0->PER |= REG_GPIO_SERIAL_MASK_0; - REG_GPIO_SERIAL_1->PER |= REG_GPIO_SERIAL_MASK_1; - - hw->serial = ser; -} - -static void cleanup(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - // Uninstall the ISRs - disable_rx_irq(_hw); - disable_tx_irq(_hw); - irq_uninstall(hw->irq_tx); - irq_uninstall(hw->irq_rx); -} - -static void setbaudrate(struct SerialHardware* _hw, unsigned long rate) -{ - struct SCI* hw = (struct SCI*)_hw; - - // SCI has an internal 16x divider on the input clock, which comes - // from the IPbus (see the scheme in user manual, 12.7.3). We apply - // it to calculate the period to store in the register. - hw->regs->BR = (IPBUS_FREQ + rate * 8ul) / (rate * 16ul); -} - -static void setparity(struct SerialHardware* _hw, int parity) -{ - // ??? - ASSERT(0); -} - - -#if CONFIG_SER_MULTI - -static void multi_init(void) -{ - static bool flag = false; - int i; - - if (flag) - return; - - for (i = 0; i < MAX_MULTI_GROUPS; ++i) - sem_init(&multi_sems[i]); - flag = true; -} - -static void init_lock(struct SerialHardware* _hw, struct Serial *ser) -{ - struct SCI* hw = (struct SCI*)_hw; - - // Initialize the multi engine (if needed) - multi_init(); - - // Acquire the lock of the semaphore for this group - ASSERT(hw->num_group >= 0); - ASSERT(hw->num_group < MAX_MULTI_GROUPS); - sem_obtain(&multi_sems[hw->num_group]); - - // Do a hardware switch to the given serial - ser_hw_switch(hw->num_group, hw->id); - - init(_hw, ser); -} - -static void cleanup_unlock(struct SerialHardware* _hw) -{ - struct SCI* hw = (struct SCI*)_hw; - - cleanup(_hw); - - sem_release(&multi_sems[hw->num_group]); -} - -#endif /* CONFIG_SER_MULTI */ - - -static const struct SerialHardwareVT SCI_VT = -{ - .init = init, - .cleanup = cleanup, - .setBaudrate = setbaudrate, - .setParity = setparity, - .txStart = enable_tx_irq, - .txSending = tx_irq_enabled, -}; - -#if CONFIG_SER_MULTI -static const struct SerialHardwareVT SCI_MULTI_VT = -{ - .init = init_lock, - .cleanup = cleanup_unlock, - .setBaudrate = setbaudrate, - .setParity = setparity, - .txStart = enable_tx_irq, - .txSending = tx_irq_enabled, -}; -#endif /* CONFIG_SER_MULTI */ - -#define SCI_DESC_NORMAL(hwch) \ - { \ - .hw = \ - { \ - .table = &SCI_VT, \ - .rxbuffer = ser ## hwch ## _fifo_rx, \ - .txbuffer = ser ## hwch ## _fifo_tx, \ - .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \ - .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \ - }, \ - .regs = ®_SCI[hwch], \ - .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \ - .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \ - .num_group = -1, \ - .id = -1, \ - } \ - /**/ - -#if CONFIG_SER_MULTI -#define SCI_DESC_MULTI(hwch, group_, id_) \ - { \ - .hw = \ - { \ - .table = &SCI_MULTI_VT, \ - .rxbuffer = ser ## hwch ## _fifo_rx, \ - .txbuffer = ser ## hwch ## _fifo_tx, \ - .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \ - .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \ - }, \ - .regs = ®_SCI[hwch], \ - .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \ - .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \ - .num_group = group_, \ - .id = id_, \ - } \ - /**/ -#endif /* CONFIG_SER_MULTI */ - -// \todo Move this into hw.h, with a little preprocessor magic -static struct SCI SCIDescs[] = -{ - SCI_DESC_NORMAL(0), - SCI_DESC_MULTI(1, 0, 0), - SCI_DESC_MULTI(1, 0, 1), -}; - -struct SerialHardware* ser_hw_getdesc(int unit) -{ - ASSERT(unit < countof(SCIDescs)); - return &SCIDescs[unit].hw; -} diff --git a/cpu/dsp56k/drv/ser_dsp56k.h b/cpu/dsp56k/drv/ser_dsp56k.h deleted file mode 100644 index d035df67..00000000 --- a/cpu/dsp56k/drv/ser_dsp56k.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * \file - * - * - * \version $Id: timer_arm.h 18273 2007-10-11 14:53:02Z batt $ - * - * \author Daniele Basile - * - * \brief Low-level serial module for ARM (interface). - */ - -#include /* BV() */ -#include /* uint32_t */ - -typedef uint16_t serstatus_t; - -/* Software errors */ -#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */ -#define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */ -#define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */ - -/* - * Hardware errors. - * These flags map directly to the SCI Control Register. - */ -#define SERRF_PARITYERROR BV(8) /**< Parity error */ -#define SERRF_FRAMEERROR BV(9) /**< Stop bit missing */ -#define SERRF_NOISEERROR BV(10) /**< Noise error */ -#define SERRF_RXSROVERRUN BV(11) /**< Rx shift register overrun */ - -/** - * \name Serial hw numbers - * - * \{ - */ -enum -{ -// \todo since we now support "fake" multiplexed serials, this should be moved to hw.h -SER_UART0, -SER_PUNTALI, -SER_BARCODE, -SER_CNT /**< Number of serial ports */ -}; -/*\}*/ diff --git a/cpu/dsp56k/drv/timer_dsp56k.h b/cpu/dsp56k/drv/timer_dsp56k.h deleted file mode 100644 index f86cb50b..00000000 --- a/cpu/dsp56k/drv/timer_dsp56k.h +++ /dev/null @@ -1,148 +0,0 @@ -#error This code must be revised for the new timer API -/** - * \file - * - * - * \version $Id$ - * - * \author Giovanni Bajo - * - * \brief Driver module for DSP56K - */ - -/*#* - *#* $Log$ - *#* Revision 1.10 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.9 2006/02/21 21:28:02 bernie - *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. - *#* - *#* Revision 1.8 2005/11/04 16:20:02 bernie - *#* Fix reference to README.devlib in header. - *#* - *#* Revision 1.7 2005/04/11 19:10:28 bernie - *#* Include top-level headers from cfg/ subdir. - *#* - *#* Revision 1.6 2004/11/16 22:37:14 bernie - *#* Replace IPTR with iptr_t. - *#* - *#* Revision 1.5 2004/08/25 14:12:08 rasky - *#* Aggiornato il comment block dei log RCS - *#* - *#* Revision 1.4 2004/07/30 14:27:49 rasky - *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management - *#* - *#* Revision 1.3 2004/06/06 18:30:34 bernie - *#* Import DSP56800 changes from SC. - *#* - *#* Revision 1.2 2004/06/03 11:27:09 bernie - *#* Add dual-license information. - *#* - *#* Revision 1.1 2004/05/23 18:23:30 bernie - *#* Import drv/timer module. - *#* - *#*/ - -#ifndef DRV_TIMER_DSP56K_H -#define DRV_TIMER_DSP56K_H - -#include "timer.h" -#include -#include -#include -#include - -// Calculate register pointer and irq vector from hw.h setting -#define REG_SYSTEM_TIMER PP_CAT(REG_TIMER_, SYSTEM_TIMER) -#define SYSTEM_TIMER_IRQ_VECTOR PP_CAT(IRQ_TIMER_, SYSTEM_TIMER) - -/// Prescaler for the system timer -#define TIMER_PRESCALER 16 - -/// Frequency of the hardware high precision timer -#define TIMER_HW_HPTICKS_PER_SEC (IPBUS_FREQ / TIMER_PRESCALER) - -/// Type of time expressed in ticks of the hardware high precision timer -typedef uint16_t hptime_t; - -static void system_timer_isr(UNUSED(iptr_t, arg)); - -static void timer_hw_init(void) -{ - uint16_t compare; - - // Clear compare flag status and enable interrupt on compare - REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF; - REG_SYSTEM_TIMER->SCR |= REG_TIMER_SCR_TCFIE; - - // Calculate the compare value needed to generate an interrupt exactly - // TICKS_PER_SEC times each second (usually, every millisecond). Check that - // the calculation is accurate, otherwise there is a precision error - // (probably the prescaler is too big or too small). - compare = TIMER_HW_HPTICKS_PER_SEC / TICKS_PER_SEC; - ASSERT((uint32_t)compare * TICKS_PER_SEC == IPBUS_FREQ / TIMER_PRESCALER); - REG_SYSTEM_TIMER->CMP1 = compare; - - // The value for reload (at initializationa and after compare is met) is zero - REG_SYSTEM_TIMER->LOAD = 0; - - // Set the interrupt handler and priority - irq_install(SYSTEM_TIMER_IRQ_VECTOR, &system_timer_isr, NULL); - irq_setpriority(SYSTEM_TIMER_IRQ_VECTOR, IRQ_PRIORITY_SYSTEM_TIMER); - - // Small preprocessor trick to generate the REG_TIMER_CTRL_PRIMARY_IPBYNN macro - // needed to set the prescaler - #define REG_CONTROL_PRESCALER PP_CAT(REG_TIMER_CTRL_PRIMARY_IPBY, TIMER_PRESCALER) - - // Setup the counter and start counting - REG_SYSTEM_TIMER->CTRL = - REG_TIMER_CTRL_MODE_RISING | // count rising edges (normal) - REG_CONTROL_PRESCALER | // frequency (IPbus / TIMER_PRESCALER) - REG_TIMER_CTRL_LENGTH; // up to CMP1, then reload -} - -INLINE void timer_hw_irq(void) -{ - // Clear the overflow flag so that we are ready for another interrupt - REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF; -} - -INLINE hptime_t timer_hw_hpread(void) -{ - return REG_SYSTEM_TIMER->CNTR; -} - -#define DEFINE_TIMER_ISR \ - static void system_timer_isr(UNUSED(iptr_t, arg)) - -#endif /* DRV_TIMER_DSP56_H */ diff --git a/cpu/i196/drv/kdebug_i196.c b/cpu/i196/drv/kdebug_i196.c deleted file mode 100644 index 2f72e519..00000000 --- a/cpu/i196/drv/kdebug_i196.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file - * - * - * \brief General pourpose debug support for embedded systems (implementation). - * - * \version $Id$ - * \author Bernardo Innocenti - * \author Stefano Fedrigo - */ - -#error Revise me! - -#include -#include /* for BV() */ -#include -#include /* for CLOCK_FREQ */ -#include /* Required for bus macros overrides */ - - -#include "Util196.h" -#define KDBG_WAIT_READY() do {} while (!(SP_STAT & (SPSF_TX_EMPTY | SPSF_TX_INT))) -#define KDBG_WRITE_CHAR(c) do { SBUF = (c); } while(0) -#define KDBG_MASK_IRQ(old) \ - do { \ - (old) = INT_MASK1 & INT1F_TI; \ - INT_MASK1 &= ~INT1F_TI; \ - } while(0) -#define KDBG_RESTORE_IRQ(old) do { INT_MASK1 |= (old); } -typedef uint16_t kdbg_irqsave_t; /* FIXME: unconfirmed */ - -#if CONFIG_KDEBUG_PORT == 666 - #error BITBANG debug console missing for this platform -#endif - - -INLINE void kdbg_hw_init(void) -{ - /* Set serial port for 19200bps 8N1 */ - INT_MASK1 &= ~(INT1F_TI | INT1F_RI); - SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1; - ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC; - IOC1 = ioc1_img; - BAUD_RATE = 0x33; - BAUD_RATE = 0x80; -} diff --git a/cpu/i196/drv/ser_i196.c b/cpu/i196/drv/ser_i196.c deleted file mode 100644 index a87de6fa..00000000 --- a/cpu/i196/drv/ser_i196.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * - * \brief CPU specific serial I/O driver - */ - -/*#* - *#* $Log$ - *#* Revision 1.7 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.6 2005/11/04 16:20:02 bernie - *#* Fix reference to README.devlib in header. - *#* - *#* Revision 1.5 2004/12/13 11:51:08 bernie - *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE. - *#* - *#* Revision 1.4 2004/08/25 14:12:08 rasky - *#* Aggiornato il comment block dei log RCS - *#* - *#* Revision 1.3 2004/06/03 11:27:09 bernie - *#* Add dual-license information. - *#* - *#* Revision 1.2 2004/05/23 18:21:53 bernie - *#* Trim CVS logs and cleanup header info. - *#* - *#*/ - -#include "hw.h" -#include "serhw.h" - -#define SER_HW_ENABLE_TX \ - ATOMIC( \ - if (!ser_sending) \ - { \ - ser_sending = true; \ - (INT_PEND1 |= INT1F_TI) \ - } \ - ); - -static volatile bool ser_sending; - -// Serial TX intr -INTERRUPT(0x30) void TI_interrupt(void) -{ - if (CANT_SEND) - { - ser_sending = false; - return; - } - - /* Can we send two bytes at the same time? */ - if (SP_STAT & SPSF_TX_EMPTY) - { - SBUF = fifo_pop(&ser_txfifo); - - if (CANT_SEND) - { - ser_sending = false; - return; - } - } - - SBUF = fifo_pop(&ser_txfifo); -} - -INTERRUPT(0x32) void RI_interrupt(void) -{ - ser_status |= SP_STAT & - (SPSF_OVERRUN_ERROR | SPSF_PARITY_ERROR | SPSF_FRAMING_ERROR); - if (fifo_isfull(&ser_rxfifo)) - ser_status |= SERRF_RXFIFOOVERRUN; - else - fifo_push(&ser_rxfifo, SBUF); -} - -static void ser_setbaudrate(unsigned long rate) -{ - // Calcola il periodo per la generazione del baud rate richiesto - uint16_t baud = (uint16_t)(((CLOCK_FREQ / 16) / rate) - 1) | 0x8000; - BAUD_RATE = (uint8_t)baud; - BAUD_RATE = (uint8_t)(baud >> 8); -} - -static void ser_hw_init(void) -{ - // Inizializza la porta seriale - SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1; - ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC; - IOC1 = ioc1_img; - - // Svuota il buffer di ricezione - { - uint8_t dummy = SBUF; - } - - // Abilita gli interrupt - INT_MASK1 |= INT1F_TI | INT1F_RI; -} - diff --git a/cpu/i196/drv/timer_i196.h b/cpu/i196/drv/timer_i196.h deleted file mode 100644 index 5c4bc8bd..00000000 --- a/cpu/i196/drv/timer_i196.h +++ /dev/null @@ -1,89 +0,0 @@ -#error This code must be revised for the new timer API -/** - * \file - * - * - * \version $Id$ - * - * \author Bernardo Innocenti - * - * \brief Low-level timer module for AVR - */ - -/*#* - *#* $Log$ - *#* Revision 1.7 2006/07/19 12:56:26 bernie - *#* Convert to new Doxygen style. - *#* - *#* Revision 1.6 2006/02/21 21:28:02 bernie - *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. - *#* - *#* Revision 1.5 2005/11/04 16:20:02 bernie - *#* Fix reference to README.devlib in header. - *#* - *#* Revision 1.4 2004/12/13 11:51:08 bernie - *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE. - *#* - *#* Revision 1.3 2004/08/25 14:12:08 rasky - *#* Aggiornato il comment block dei log RCS - *#* - *#* Revision 1.2 2004/06/03 11:27:09 bernie - *#* Add dual-license information. - *#* - *#* Revision 1.1 2004/05/23 18:23:30 bernie - *#* Import drv/timer module. - *#* - *#*/ - -#ifndef TIMER_I196_H -#define TIMER_I196_H - -/** - * Retrigger TIMER2, adjusting the time to account for - * the interrupt prologue latency. - */ -#define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE) - -#define TIMER_INIT \ - TIMER2 = (65535 - TICKS_RATE); \ - INT_MASK1 |= INT1F_T2OVF; \ - ATOMIC( \ - WSR = 1; \ - IOC3 |= IOC3F_T2_ENA; \ - WSR = 0; \ - ) - -#define DEFINE_TIMER_ISR \ - INTERRUPT(0x38) void TM2_OVFL_interrupt(void); \ - INTERRUPT(0x38) void TM2_OVFL_interrupt(void) - -#endif /* DRV_TIMER_I196_H */ diff --git a/cpu/irq.h b/cpu/irq.h deleted file mode 100644 index 15609d76..00000000 --- a/cpu/irq.h +++ /dev/null @@ -1,251 +0,0 @@ -/** - * \file - * - * - * \brief CPU-specific IRQ definitions. - * - * \author Giovanni Bajo - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * \author Francesco Sacchi - */ -#ifndef CPU_IRQ_H -#define CPU_IRQ_H - -#include "detect.h" -#include "types.h" - -#include /* for uintXX_t */ - -#if CPU_I196 - #define IRQ_DISABLE disable_interrupt() - #define IRQ_ENABLE enable_interrupt() -#elif CPU_X86 - - /* Get IRQ_* definitions from the hosting environment. */ - #include - #if OS_EMBEDDED - #define IRQ_DISABLE FIXME - #define IRQ_ENABLE FIXME - #define IRQ_SAVE_DISABLE(x) FIXME - #define IRQ_RESTORE(x) FIXME - #endif /* OS_EMBEDDED */ - -#elif CPU_ARM - - - #ifdef __IAR_SYSTEMS_ICC__ - - #include - - #if __CPU_MODE__ == 1 /* Thumb */ - /* Use stubs */ - extern cpuflags_t get_CPSR(void); - extern void set_CPSR(cpuflags_t flags); - #else - #define get_CPSR __get_CPSR - #define set_CPSR __set_CPSR - #endif - - #define IRQ_DISABLE __disable_interrupt() - #define IRQ_ENABLE __enable_interrupt() - - #define IRQ_SAVE_DISABLE(x) \ - do { \ - (x) = get_CPSR(); \ - __disable_interrupt(); \ - } while (0) - - #define IRQ_RESTORE(x) \ - do { \ - set_CPSR(x); \ - } while (0) - - #define IRQ_ENABLED() \ - ((bool)(get_CPSR() & 0xb0)) - - #define BREAKPOINT /* asm("bkpt 0") DOES NOT WORK */ - - #else /* !__IAR_SYSTEMS_ICC__ */ - - #define IRQ_DISABLE \ - do { \ - asm volatile ( \ - "mrs r0, cpsr\n\t" \ - "orr r0, r0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - ::: "r0" \ - ); \ - } while (0) - - #define IRQ_ENABLE \ - do { \ - asm volatile ( \ - "mrs r0, cpsr\n\t" \ - "bic r0, r0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - ::: "r0" \ - ); \ - } while (0) - - #define IRQ_SAVE_DISABLE(x) \ - do { \ - asm volatile ( \ - "mrs %0, cpsr\n\t" \ - "orr r0, %0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - : "=r" (x) \ - : /* no inputs */ \ - : "r0" \ - ); \ - } while (0) - - #define IRQ_RESTORE(x) \ - do { \ - asm volatile ( \ - "msr cpsr_c, %0" \ - : /* no outputs */ \ - : "r" (x) \ - ); \ - } while (0) - - #define CPU_READ_FLAGS() \ - ({ \ - cpuflags_t sreg; \ - asm volatile ( \ - "mrs %0, cpsr\n\t" \ - : "=r" (sreg) \ - : /* no inputs */ \ - ); \ - sreg; \ - }) - - #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0) - - #endif /* !__IAR_SYSTEMS_ICC_ */ - -#elif CPU_PPC - #define IRQ_DISABLE FIXME - #define IRQ_ENABLE FIXME - #define IRQ_SAVE_DISABLE(x) FIXME - #define IRQ_RESTORE(x) FIXME - #define IRQ_ENABLED() FIXME - -#elif CPU_DSP56K - - #define BREAKPOINT asm(debug) - #define IRQ_DISABLE do { asm(bfset #0x0200,SR); asm(nop); } while (0) - #define IRQ_ENABLE do { asm(bfclr #0x0200,SR); asm(nop); } while (0) - - #define IRQ_SAVE_DISABLE(x) \ - do { (void)x; asm(move SR,x); asm(bfset #0x0200,SR); } while (0) - #define IRQ_RESTORE(x) \ - do { (void)x; asm(move x,SR); } while (0) - - static inline bool irq_running(void) - { - extern void *user_sp; - return !!user_sp; - } - #define IRQ_RUNNING() irq_running() - - static inline bool irq_enabled(void) - { - uint16_t x; - asm(move SR,x); - return !(x & 0x0200); - } - #define IRQ_ENABLED() irq_enabled() - -#elif CPU_AVR - - #define IRQ_DISABLE asm volatile ("cli" ::) - #define IRQ_ENABLE asm volatile ("sei" ::) - - #define IRQ_SAVE_DISABLE(x) \ - do { \ - __asm__ __volatile__( \ - "in %0,__SREG__\n\t" \ - "cli" \ - : "=r" (x) : /* no inputs */ : "cc" \ - ); \ - } while (0) - - #define IRQ_RESTORE(x) \ - do { \ - __asm__ __volatile__( \ - "out __SREG__,%0" : /* no outputs */ : "r" (x) : "cc" \ - ); \ - } while (0) - - #define IRQ_ENABLED() \ - ({ \ - uint8_t sreg; \ - __asm__ __volatile__( \ - "in %0,__SREG__\n\t" \ - : "=r" (sreg) /* no inputs & no clobbers */ \ - ); \ - (bool)(sreg & 0x80); \ - }) -#else - #error No CPU_... defined. -#endif - -#ifndef IRQ_ENTRY - #define IRQ_ENTRY() /* NOP */ -#endif - -#ifndef IRQ_EXIT - #define IRQ_EXIT() /* NOP */ -#endif - - -/** - * Execute \a CODE atomically with respect to interrupts. - * - * \see IRQ_SAVE_DISABLE IRQ_RESTORE - */ -#define ATOMIC(CODE) \ - do { \ - cpuflags_t __flags; \ - IRQ_SAVE_DISABLE(__flags); \ - CODE; \ - IRQ_RESTORE(__flags); \ - } while (0) - - -#ifndef BREAKPOINT -#define BREAKPOINT /* nop */ -#endif - - -#endif /* CPU_IRQ_H */ diff --git a/cpu/newcore b/cpu/newcore deleted file mode 100755 index 043764c9..00000000 --- a/cpu/newcore +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -DIRS="drv hw io scripts" -if [ $# != 1 ]; then - echo "Create a new core tree with subdirs:" - echo $DIRS - echo "usage $0 " - exit 1 -fi -CORE=$1 -mkdir $CORE -cd $CORE -for dir in $DIRS -do - mkdir $dir -done -cd .. diff --git a/cpu/types.h b/cpu/types.h deleted file mode 100644 index be9b5fd5..00000000 --- a/cpu/types.h +++ /dev/null @@ -1,193 +0,0 @@ -/** - * \file - * - * - * \brief CPU-specific type definitions. - * - * \author Giovanni Bajo - * \author Bernardo Innocenti - * \author Stefano Fedrigo - * \author Francesco Sacchi - */ -#ifndef CPU_TYPES_H -#define CPU_TYPES_H - -#include "detect.h" -#include "attr.h" -#include /* for uintXX_t */ - -#if CPU_I196 - - typedef uint16_t cpuflags_t; // FIXME - typedef unsigned int cpustack_t; - #warning Verify following constant - #define SIZEOF_CPUSTACK_T 2 - -#elif CPU_X86 - - /* Get IRQ_* definitions from the hosting environment. */ - #include - #if OS_EMBEDDED - typedef uint32_t cpuflags_t; // FIXME - #endif /* OS_EMBEDDED */ - - #if CPU_X86_64 - typedef uint64_t cpustack_t; - #define SIZEOF_CPUSTACK_T 8 - #else - typedef uint32_t cpustack_t; - #define SIZEOF_CPUSTACK_T 4 - #endif - -#elif CPU_ARM - - typedef uint32_t cpuflags_t; - typedef uint32_t cpustack_t; - #define SIZEOF_CPUSTACK_T 4 - -#elif CPU_PPC - - typedef uint32_t cpuflags_t; // FIXME - typedef uint32_t cpustack_t; // FIXME - #define SIZEOF_CPUSTACK_T 4 - -#elif CPU_DSP56K - - typedef uint16_t cpuflags_t; - typedef unsigned int cpustack_t; - #warning Verify following costant - #define SIZEOF_CPUSTACK_T 2 - -#elif CPU_AVR - - typedef uint8_t cpuflags_t; - typedef uint8_t cpustack_t; - #define SIZEOF_CPUSTACK_T 1 - -#else - #error No CPU_... defined. -#endif - -/** - * \name Default type sizes. - * - * These defaults are reasonable for most 16/32bit machines. - * Some of these macros may be overridden by CPU-specific code above. - * - * ANSI C requires that the following equations be true: - * \code - * sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) - * sizeof(float) <= sizeof(double) - * CPU_BITS_PER_CHAR >= 8 - * CPU_BITS_PER_SHORT >= 8 - * CPU_BITS_PER_INT >= 16 - * CPU_BITS_PER_LONG >= 32 - * \endcode - * \{ - */ -#ifndef SIZEOF_CHAR -#define SIZEOF_CHAR 1 -#endif - -#ifndef SIZEOF_SHORT -#define SIZEOF_SHORT 2 -#endif - -#ifndef SIZEOF_INT -#if CPU_REG_BITS < 32 - #define SIZEOF_INT 2 -#else - #define SIZEOF_INT 4 -#endif -#endif /* !SIZEOF_INT */ - -#ifndef SIZEOF_LONG -#if CPU_REG_BITS > 32 - #define SIZEOF_LONG 8 -#else - #define SIZEOF_LONG 4 -#endif -#endif - -#ifndef SIZEOF_PTR -#if CPU_REG_BITS < 32 - #define SIZEOF_PTR 2 -#elif CPU_REG_BITS == 32 - #define SIZEOF_PTR 4 -#else /* CPU_REG_BITS > 32 */ - #define SIZEOF_PTR 8 -#endif -#endif - -#ifndef CPU_BITS_PER_CHAR -#define CPU_BITS_PER_CHAR (SIZEOF_CHAR * 8) -#endif - -#ifndef CPU_BITS_PER_SHORT -#define CPU_BITS_PER_SHORT (SIZEOF_SHORT * CPU_BITS_PER_CHAR) -#endif - -#ifndef CPU_BITS_PER_INT -#define CPU_BITS_PER_INT (SIZEOF_INT * CPU_BITS_PER_CHAR) -#endif - -#ifndef CPU_BITS_PER_LONG -#define CPU_BITS_PER_LONG (SIZEOF_LONG * CPU_BITS_PER_CHAR) -#endif - -#ifndef CPU_BITS_PER_PTR -#define CPU_BITS_PER_PTR (SIZEOF_PTR * CPU_BITS_PER_CHAR) -#endif - - -/*\}*/ - -/* Sanity checks for the above definitions */ -STATIC_ASSERT(sizeof(char) == SIZEOF_CHAR); -STATIC_ASSERT(sizeof(short) == SIZEOF_SHORT); -STATIC_ASSERT(sizeof(long) == SIZEOF_LONG); -STATIC_ASSERT(sizeof(int) == SIZEOF_INT); -STATIC_ASSERT(sizeof(void *) == SIZEOF_PTR); -STATIC_ASSERT(sizeof(int8_t) * CPU_BITS_PER_CHAR == 8); -STATIC_ASSERT(sizeof(uint8_t) * CPU_BITS_PER_CHAR == 8); -STATIC_ASSERT(sizeof(int16_t) * CPU_BITS_PER_CHAR == 16); -STATIC_ASSERT(sizeof(uint16_t) * CPU_BITS_PER_CHAR == 16); -STATIC_ASSERT(sizeof(int32_t) * CPU_BITS_PER_CHAR == 32); -STATIC_ASSERT(sizeof(uint32_t) * CPU_BITS_PER_CHAR == 32); -#ifdef __HAS_INT64_T__ -STATIC_ASSERT(sizeof(int64_t) * CPU_BITS_PER_CHAR == 64); -STATIC_ASSERT(sizeof(uint64_t) * CPU_BITS_PER_CHAR == 64); -#endif -STATIC_ASSERT(sizeof(cpustack_t) == SIZEOF_CPUSTACK_T); - - -#endif /* CPU_TYPES_H */