2011-04-20 Rohan Kangralkar <rkangral@ece.neu.edu>

PR 1781/bsps
	* bf52x/include: Added additional MMR.
	* bf52x/interrupt: The BF52X processors have a different
	System interrupt controller than present in the 53X range of
	processors. The 52X have 8 interrupt assignment registers. The
	implementation uses tables to increase predictability.
	* serial/uart.?: Added DMA based and interrupt based transfer
	support. The uart code used a single ISR for TX and RX and tried
	to identify and multiplex inside the ISR. In the new code the
	type of interrupt is identified by the central ISR dispatcher
	bf52x/interrupt or interrupt/.	This simplifies the UART ISR.
This commit is contained in:
Joel Sherrill
2011-04-20 20:20:47 +00:00
parent 5eb50f38e9
commit cb4c90b227
10 changed files with 1480 additions and 177 deletions
+14
View File
@@ -1,3 +1,17 @@
2011-04-20 Rohan Kangralkar <rkangral@ece.neu.edu>
PR 1781/bsps
* bf52x/include: Added additional MMR.
* bf52x/interrupt: The BF52X processors have a different
System interrupt controller than present in the 53X range of
processors. The 52X have 8 interrupt assignment registers. The
implementation uses tables to increase predictability.
* serial/uart.?: Added DMA based and interrupt based transfer
support. The uart code used a single ISR for TX and RX and tried
to identify and multiplex inside the ISR. In the new code the
type of interrupt is identified by the central ISR dispatcher
bf52x/interrupt or interrupt/. This simplifies the UART ISR.
2011-02-11 Ralf Corsépius <ralf.corsepius@rtems.org>
* timer/timer.c:
+27
View File
@@ -10,9 +10,31 @@ EXTRA_DIST =
noinst_PROGRAMS =
include_bspdir = $(includedir)/bsp
include_libcpudir = $(includedir)/libcpu
include_bsp_HEADERS =
include_libcpu_HEADERS =
############
# Start of bf52x files
if bf52x
include_HEADERS = bf52x/include/bf52x.h
## INTERRUPT
include_bsp_HEADERS += bf52x/interrupt/interrupt.h
noinst_PROGRAMS += bf52x/interrupt.rel
bf52x_interrupt_rel_SOURCES = bf52x/interrupt/interrupt.c \
bf52x/interrupt/interrupt.h
bf52x_interrupt_rel_CPPFLAGS = $(AM_CPPFLAGS)
bf52x_interrupt_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
# endof bf52x
############
include_libcpu_HEADERS += include/bf533.h
include_libcpu_HEADERS += include/bf537.h
include_libcpu_HEADERS += include/cecRegs.h
@@ -47,12 +69,17 @@ mmu_rel_SOURCES = mmu/mmu.c
mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
if bf52x
else
include_libcpu_HEADERS += interrupt/interrupt.h
noinst_PROGRAMS += interrupt.rel
interrupt_rel_SOURCES = interrupt/interrupt.c
interrupt_rel_CPPFLAGS = $(AM_CPPFLAGS)
interrupt_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
noinst_PROGRAMS += clock.rel
clock_rel_SOURCES = clock/clock.c
clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
+133
View File
@@ -0,0 +1,133 @@
/**
*@file bf52x.h
*
*@brief
* - This file provides the register address for the 52X model. The file is
* based on the 533 implementation with some addition to support 52X range of
* processors.
*
* Target: TLL6527v1-0
* Compiler:
*
* COPYRIGHT (c) 2010 by ECE Northeastern University.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license
*
* @author Rohan Kangralkar, ECE, Northeastern University
* (kangralkar.r@husky.neu.edu)
*
* LastChange:
* $Id$
*
*/
#ifndef _BF52X_H_
#define _BF52X_H_
/* register (or register block) addresses */
#define SIC_BASE_ADDRESS 0xffc00100
#define WDOG_BASE_ADDRESS 0xffc00200
#define RTC_BASE_ADDRESS 0xffc00300
#define UART0_BASE_ADDRESS 0xffc00400
#define UART1_BASE_ADDRESS 0xffc02000
#define SPI_BASE_ADDRESS 0xffc00500
#define TIMER_BASE_ADDRESS 0xffc00600
#define TIMER_CHANNELS 3
#define TIMER_PITCH 0x10
#define TIMER0_BASE_ADDRESS 0xffc00600
#define TIMER1_BASE_ADDRESS 0xffc00610
#define TIMER2_BASE_ADDRESS 0xffc00620
#define TIMER_ENABLE 0xffc00640
#define TIMER_DISABLE 0xffc00644
#define TIMER_STATUS 0xffc00648
#define PORTFIO_BASE_ADDRESS 0xffc00700
#define SPORT0_BASE_ADDRESS 0xffc00800
#define SPORT1_BASE_ADDRESS 0xffc00900
#define EBIU_BASE_ADDRESS 0xffc00a00
#define DMA_TC_PER 0xffc00b0c
#define DMA_TC_CNT 0xffc00b10
#define DMA_BASE_ADDRESS 0xffc00c00
#define DMA_CHANNELS 8
#define DMA_PITCH 0x40
#define DMA0_BASE_ADDRESS 0xffc00c00
#define DMA1_BASE_ADDRESS 0xffc00c40
#define DMA2_BASE_ADDRESS 0xffc00c80
#define DMA3_BASE_ADDRESS 0xffc00cc0
#define DMA4_BASE_ADDRESS 0xffc00d00
#define DMA5_BASE_ADDRESS 0xffc00d40
#define DMA6_BASE_ADDRESS 0xffc00d80
#define DMA7_BASE_ADDRESS 0xffc00dc0
#define DMA8_BASE_ADDRESS 0xffc00e00
#define DMA9_BASE_ADDRESS 0xffc00e40
#define DMA10_BASE_ADDRESS 0xffc00e80
#define DMA11_BASE_ADDRESS 0xffc00ec0
#define MDMA_BASE_ADDRESS 0xffc00e00
#define MDMA_CHANNELS 2
#define MDMA_D_S 0x40
#define MDMA_PITCH 0x80
#define MDMA0D_BASE_ADDRESS 0xffc00e00
#define MDMA0S_BASE_ADDRESS 0xffc00e40
#define MDMA1D_BASE_ADDRESS 0xffc00e80
#define MDMA1S_BASE_ADDRESS 0xffc00ec0
#define PPI_BASE_ADDRESS 0xffc01000
/* register fields */
#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_MASK 0xf800
#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_SHIFT 11
#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_MASK 0x0700
#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_SHIFT 8
#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_MASK 0x00f0
#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_SHIFT 4
#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_MASK 0x000f
#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_SHIFT 0
#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_MASK 0xf800
#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_SHIFT 11
#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_MASK 0x0700
#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_SHIFT 8
#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_MASK 0x00f0
#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_SHIFT 4
#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_MASK 0x000f
#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_SHIFT 0
#define TIMER_ENABLE_TIMEN2 0x0004
#define TIMER_ENABLE_TIMEN1 0x0002
#define TIMER_ENABLE_TIMEN0 0x0001
#define TIMER_DISABLE_TIMDIS2 0x0004
#define TIMER_DISABLE_TIMDIS1 0x0002
#define TIMER_DISABLE_TIMDIS0 0x0001
#define TIMER_STATUS_TRUN2 0x00004000
#define TIMER_STATUS_TRUN1 0x00002000
#define TIMER_STATUS_TRUN0 0x00001000
#define TIMER_STATUS_TOVF_ERR2 0x00000040
#define TIMER_STATUS_TOVF_ERR1 0x00000020
#define TIMER_STATUS_TOVF_ERR0 0x00000010
#define TIMER_STATUS_TIMIL2 0x00000004
#define TIMER_STATUS_TIMIL1 0x00000002
#define TIMER_STATUS_TIMIL0 0x00000001
/* Core Event Controller vectors */
#define CEC_EMULATION_VECTOR 0
#define CEC_RESET_VECTOR 1
#define CEC_NMI_VECTOR 2
#define CEC_EXCEPTIONS_VECTOR 3
#define CEC_HARDWARE_ERROR_VECTOR 5
#define CEC_CORE_TIMER_VECTOR 6
#define CEC_INTERRUPT_BASE_VECTOR 7
#define CEC_INTERRUPT_COUNT 9
/* System Interrupt Controller vectors */
#define SIC_IAR_COUNT 8
#endif /* _BF52X_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,146 @@
/**
*@file interrupt.h
*
*@brief
* - This file implements interrupt dispatcher. The init code is taken from
* the 533 implementation for blackfin. Since 52X supports 56 line and 2 ISR
* registers some portion is written twice.
*
* Target: TLL6527v1-0
* Compiler:
*
* COPYRIGHT (c) 2010 by ECE Northeastern University.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license
*
* @author Rohan Kangralkar, ECE, Northeastern University
* (kangralkar.r@husky.neu.edu)
*
* LastChange:
* $Id$
*
*/
#ifndef _BFIN_INTERRUPT_H_
#define _BFIN_INTERRUPT_H_
#ifdef __cplusplus
extern "C" {
#endif
/** The type of interrupts handled by the SIC
*/
typedef enum {
IRQ_PLL_WAKEUP_INTERRUPT, /* 0 */
IRQ_DMA_ERROR_0, /* 1 */
IRQ_DMAR0_BLOCK_INTERRUPT, /* 2 */
IRQ_DMAR1_BLOCK_INTERRUPT, /* 3 */
IRQ_DMAR0_OVERFLOW_ERROR, /* 4 */
IRQ_DMAR1_OVERFLOW_ERROR, /* 5 */
IRQ_PPI_STATUS, /* 6 */
IRQ_MAC_STATUS, /* 7 */
IRQ_SPORT0_STATUS, /* 8 */
IRQ_SPORT1_STATUS, /* 9 */
IRQ_RESERVED_10, /* 10 */
IRQ_RESERVED_11, /* 11 */
IRQ_UART0_STATUS, /* 12 */
IRQ_UART1_STATUS, /* 13 */
IRQ_REAL_TIME_CLOCK, /* 14 */
IRQ_DMA0_PPI_NFC, /* 15 */
IRQ_DMA3_SPORT0_RX, /* 16 */
IRQ_DMA4_SPORT0_TX, /* 17 */
IRQ_DMA5_SPORT1_RX, /* 18 */
IRQ_DMA6_SPORT1_TX, /* 19 */
IRQ_TWI_INTERRUPT, /* 20 */
IRQ_DMA7_SPI, /* 21 */
IRQ_DMA8_UART0_RX, /* 22 */
IRQ_DMA9_UART0_TX, /* 23 */
IRQ_DMA10_UART1_RX, /* 24 */
IRQ_DMA11_UART1_TX, /* 25 */
IRQ_OTP, /* 26 */
IRQ_GP_COUNTER, /* 27 */
IRQ_DMA1_MAC_RX_HOSTDP, /* 28 */
IRQ_PORT_H_INTERRUPT_A, /* 29 */
IRQ_DMA2_MAC_TX_NFC, /* 30 */
IRQ_PORT_H_INTERRUPT_B, /* 31 */
SIC_ISR0_MAX, /* 32 ***/
IRQ_TIMER0 = SIC_ISR0_MAX, /* 32 */
IRQ_TIMER1, /* 33 */
IRQ_TIMER2, /* 34 */
IRQ_TIMER3, /* 35 */
IRQ_TIMER4, /* 36 */
IRQ_TIMER5, /* 37 */
IRQ_TIMER6, /* 38 */
IRQ_TIMER7, /* 39 */
IRQ_PORT_G_INTERRUPT_A, /* 40 */
IRQ_PORT_G_INTERRUPT_B, /* 41 */
IRQ_MDMA0_STREAM_0_INTERRUPT, /* 42 */
IRQ_MDMA1_STREAM_0_INTERRUPT, /* 43 */
IRQ_SOFTWARE_WATCHDOG_INTERRUPT, /* 44 */
IRQ_PORT_F_INTERRUPT_A, /* 45 */
IRQ_PORT_F_INTERRUPT_B, /* 46 */
IRQ_SPI_STATUS, /* 47 */
IRQ_NFC_STATUS, /* 48 */
IRQ_HOSTDP_STATUS, /* 49 */
IRQ_HOREAD_DONE_INTERRUPT, /* 50 */
IRQ_RESERVED_19, /* 51 */
IRQ_USB_INT0_INTERRUPT, /* 52 */
IRQ_USB_INT1_INTERRUPT, /* 53 */
IRQ_USB_INT2_INTERRUPT, /* 54 */
IRQ_USB_DMAINT, /* 55 */
IRQ_MAX, /* 56 */
} e_isr_t;
/* source is the source to the SIC (the bit number in SIC_ISR). isr is
the function that will be called when the interrupt is active. */
typedef struct bfin_isr_s {
#if INTERRUPT_USE_TABLE
e_isr_t source;
void (*pFunc)(void *arg);
void *pArg;
int priority; /** not used */
#else
int source;
void (*isr)(void *arg);
void *_arg;
/* the following are for internal use only */
uint32_t mask0;
uint32_t mask1;
uint32_t vector;
struct bfin_isr_s *next;
#endif
} bfin_isr_t;
/**
* This routine registers a new ISR. It will write a new entry to the IVT table
* @param isr contains a callback function and source
* @return rtems status code
*/
rtems_status_code bfin_interrupt_register(bfin_isr_t *isr);
/**
* This function unregisters a registered interrupt handler.
* @param isr
*/
rtems_status_code bfin_interrupt_unregister(bfin_isr_t *isr);
/**
* blackfin interrupt initialization routine. It initializes the bfin ISR
* dispatcher. It will also create SIC CEC map which will be used for
* identifying the ISR.
*/
void bfin_interrupt_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _BFIN_INTERRUPT_H_ */
+4
View File
@@ -24,6 +24,10 @@ RTEMS_PROG_CCAS
RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
# AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "bf52x")
AM_CONDITIONAL(bf52x, test "$RTEMS_CPU_MODEL" = "bf52x")
RTEMS_AMPOLISH3
# Explicitly list all Makefiles here
+7 -1
View File
@@ -16,8 +16,14 @@
/* register addresses */
#define SIC_IMASK (SIC_BASE_ADDRESS + 0x000c)
#define SIC_IMASK_PITCH (0x40)
#define SIC_ISR (SIC_BASE_ADDRESS + 0x0020)
#define SIC_ISR_PITCH (0x40)
#define SIC_IAR_BASE_ADDRESS (SIC_BASE_ADDRESS + 0x0010)
#define SIC_IAR_PITCH 0x04
#define SIC_IAR0 (SIC_BASE_ADDRESS + 0x0010)
#if SIC_IAR_COUNT > 1
#define SIC_IAR1 (SIC_BASE_ADDRESS + 0x0014)
@@ -28,7 +34,7 @@
#if SIC_IAR_COUNT > 3
#define SIC_IAR3 (SIC_BASE_ADDRESS + 0x001c)
#endif
#define SIC_ISR (SIC_BASE_ADDRESS + 0x0020)
#define SIC_IWR (SIC_BASE_ADDRESS + 0x0024)
+22 -1
View File
@@ -13,11 +13,30 @@ all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES = $(PREINSTALL_FILES)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/libcpu
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
if bf52x
$(PROJECT_INCLUDE)/bf52x.h: bf52x/include/bf52x.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bf52x.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bf52x.h
$(PROJECT_INCLUDE)/bsp/interrupt.h: bf52x/interrupt/interrupt.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/interrupt.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/interrupt.h
endif
$(PROJECT_INCLUDE)/libcpu/bf533.h: include/bf533.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/bf533.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/bf533.h
@@ -102,10 +121,12 @@ $(PROJECT_INCLUDE)/libcpu/mmu.h: mmu/mmu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h
if bf52x
else
$(PROJECT_INCLUDE)/libcpu/interrupt.h: interrupt/interrupt.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/interrupt.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/interrupt.h
endif
$(PROJECT_INCLUDE)/libcpu/uart.h: serial/uart.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/uart.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/uart.h
File diff suppressed because it is too large Load Diff
+97 -16
View File
@@ -8,52 +8,133 @@
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* Modified:
* $Author$ Added interrupt support and DMA support
*
* $Id$
*/
#ifndef _uart_h_
#define _uart_h_
#ifndef _UART_H_
#define _UART_H_
#ifdef __cplusplus
extern "C" {
#endif
/** bfin_uart_channel object
*/
typedef struct {
const char *name;
void *base_address;
bool use_interrupts;
int force_baud;
/* the following are for internal use */
void *termios;
uint8_t volatile flags;
const char *name; /** Holds name of the device */
uint32_t uart_baseAddress; /** UART base address */
uint32_t uart_rxDmaBaseAddress; /** RX DMA base address */
uint32_t uart_txDmaBaseAddress; /** TX DMA base address */
bool uart_useInterrupts; /** are interrupts used */
bool uart_useDma; /** is dma used */
int uart_baud; /** baud rate, 0 for default */
void *termios; /** termios associated */
uint8_t volatile flags; /** flags for internal use */
uint16_t length; /** length for internal use */
} bfin_uart_channel_t;
typedef struct {
uint32_t freq;
int num_channels;
bfin_uart_channel_t *channels;
} bfin_uart_config_t;
/**
* @param base_address defines the UART base address
* @param source defines the source that caused the interrupt. This argument
* will help us in identifying if Rx or TX caused the interrupt.
*/
typedef struct {
uint32_t base_address;
int source;
} bfin_uart_arg_t;
char bfin_uart_poll_read(int minor);
char bfin_uart_poll_read(rtems_device_minor_number minor);
void bfin_uart_poll_write(int minor, char c);
/**
* Uart initialization function.
* @param major major number of the device
* @param config configuration parameters
* @return rtems status code
*/
rtems_status_code bfin_uart_initialize(rtems_device_major_number major,
bfin_uart_config_t *config);
bfin_uart_config_t *config);
/**
* Opens the device in different modes. The supported modes are
* 1. Polling
* 2. Interrupt
* 3. DMA
* At exit the uart_Exit function will be called to flush the device.
*
* @param major Major number of the device
* @param minor Minor number of the device
* @param arg
* @return
*/
rtems_device_driver bfin_uart_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg);
rtems_device_minor_number minor, void *arg);
void bfin_uart_isr(int source);
/**
* This function implements TX dma ISR. It clears the IRQ and dequeues a char
* The channel argument will have the base address. Since there are two uart
* and both the uarts can use the same tx dma isr.
*
* TODO: 1. Error checking 2. sending correct length ie after looking at the
* number of elements the uart transmitted.
*
* @param _arg argument passed to the interrupt handler. It contains the
* channel argument.
*/
void bfinUart_txDmaIsr(void *_arg);
/**
* RX DMA ISR.
* The polling route is used for receiving the characters. This is a place
* holder for future implementation.
* @param _arg
*/
void bfinUart_rxDmaIsr(void *_arg);
/**
* This function implements TX ISR. The function gets called when the TX FIFO is
* empty. It clears the interrupt and dequeues the character. It only tx one
* character at a time.
*
* TODO: error handling.
* @param _arg gets the channel information.
*/
void bfinUart_txIsr(void *_arg);
/**
* This function implements RX ISR
*/
void bfinUart_rxIsr(void *_arg);
#ifdef __cplusplus
}
#endif
#endif /* _uart_h_ */
#endif /* _UART_H_ */