for rt-thread 1.1.0

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2372 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
nongli1031@gmail.com
2012-10-26 03:36:13 +00:00
parent 2cdbbf8b05
commit 6fe2afed8c
11 changed files with 683 additions and 649 deletions

View File

@@ -15,50 +15,48 @@
#include "microblaze.inc"
.text
.globl rt_interrupt_enter
.globl rt_interrupt_leave
.text
.globl rt_interrupt_enter
.globl rt_interrupt_leave
/*
* rt_base_t rt_hw_interrupt_disable()
* copy from ucos-ii
*/
.globl rt_hw_interrupt_disable
.ent rt_hw_interrupt_disable
.align 2
.globl rt_hw_interrupt_disable
.ent rt_hw_interrupt_disable
.align 2
rt_hw_interrupt_disable:
ADDIK r1, r1, -4
SW r4, r1, r0
ADDIK r1, r1, -4
SW r4, r1, r0
MFS r3, RMSR
ANDNI r4, r3, IE_BIT
MTS RMSR, r4
MFS r3, RMSR
ANDNI r4, r3, IE_BIT
MTS RMSR, r4
LW r4, r1, r0
ADDIK r1, r1, 4
LW r4, r1, r0
ADDIK r1, r1, 4
AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */
RTSD r15, 8
AND r0, r0, r0
.end rt_hw_interrupt_disable
RTSD r15, 8
AND r0, r0, r0
.end rt_hw_interrupt_disable
/*
* void rt_hw_interrupt_enable(rt_base_t level)
* copy from ucos-ii
*/
.globl rt_hw_interrupt_enable
.ent rt_hw_interrupt_enable
.align 2
.globl rt_hw_interrupt_enable
.ent rt_hw_interrupt_enable
.align 2
rt_hw_interrupt_enable:
RTSD r15, 8
MTS rMSR, r5 /* Move the saved status from r5 into rMSR */
.end rt_hw_interrupt_enable
RTSD r15, 8
MTS rMSR, r5 /* Move the saved status from r5 into rMSR */
.end rt_hw_interrupt_enable
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
@@ -66,163 +64,162 @@ rt_hw_interrupt_enable:
* r6 --> to
*/
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch
.ent rt_hw_context_switch
.align 2
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch
.ent rt_hw_context_switch
.align 2
rt_hw_context_switch:
PUSH_ALL
MFS r3, RMSR /* save the MSR */
SWI r3, r1, STACK_RMSR
SWI r1, r5, 0 /* store sp in preempted tasks TCB */
LWI r1, r6, 0 /* get new task stack pointer */
PUSH_ALL
MFS r3, RMSR /* save the MSR */
SWI r3, r1, STACK_RMSR
SWI r1, r5, 0 /* store sp in preempted tasks TCB */
LWI r1, r6, 0 /* get new task stack pointer */
LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT
BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT
BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR
MTS RMSR, r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTSD r15, 8
AND r0, r0, r0
LWI r3, r1, STACK_RMSR
MTS RMSR,r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTSD r15, 8
AND r0, r0, r0
rt_hw_context_switch_ie:
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3
LWI r3, r1, STACK_R03
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
.end rt_hw_context_switch
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR,r3
LWI r3, r1, STACK_R03
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
.end rt_hw_context_switch
/*
* void rt_hw_context_switch_to(rt_uint32 to)
* r5 --> to
*/
.globl rt_hw_context_switch_to
.ent rt_hw_context_switch_to
.align 2
.globl rt_hw_context_switch_to
.ent rt_hw_context_switch_to
.align 2
rt_hw_context_switch_to:
LWI r1, r5, 0 /* get new task stack pointer */
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
LWI r1, r5, 0 /* get new task stack pointer */
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR,r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
.end rt_hw_context_switch_to
.end rt_hw_context_switch_to
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
*/
.globl rt_thread_switch_interrupt_flag
.globl rt_hw_context_switch_interrupt
.ent rt_hw_context_switch_interrupt
.align 2
.globl rt_thread_switch_interrupt_flag
.globl rt_hw_context_switch_interrupt
.ent rt_hw_context_switch_interrupt
.align 2
rt_hw_context_switch_interrupt:
LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */
LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */
ANDI r4, r4, 1
BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */
ANDI r4, r4, 1
BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */
ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */
SWI r4, r3, 0
ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */
SWI r4, r3, 0
LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
SWI r5, r3, 0 /* rt_interrupt_from_thread = from */
LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
SWI r5, r3, 0 /* rt_interrupt_from_thread = from */
_reswitch:
LA r3, r0, rt_interrupt_to_thread/* set rt_interrupt_to_thread */
SWI r6, r3, 0 /* rt_interrupt_to_thread = to */
RTSD r15, 8
AND r0, r0, r0
.end rt_hw_context_switch_interrupt
LA r3, r0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
SWI r6, r3, 0 /* rt_interrupt_to_thread = to */
RTSD r15, 8
AND r0, r0, r0
.end rt_hw_context_switch_interrupt
.globl _interrupt_handler
.align 2
.ent _interrupt_handler
.type _interrupt_handler, @function
.globl _interrupt_handler
.section .text
.align 2
.ent _interrupt_handler
.type _interrupt_handler, @function
_interrupt_handler:
PUSH_ALL
MFS r3, RMSR
ORI r3, r3, IE_BIT
SWI r3, r1, STACK_RMSR /* push MSR */
PUSH_ALL
MFS r3, RMSR
ORI r3, r3, IE_BIT
SWI r3, r1, STACK_RMSR /* push MSR */
BRLID r15, rt_interrupt_enter
AND r0, r0, r0
BRLID r15, rt_interrupt_enter
AND r0, r0, r0
BRLID r15, rt_hw_trap_irq
AND r0, r0, r0
BRLID r15, rt_hw_trap_irq
AND r0, r0, r0
BRLID r15, rt_interrupt_leave
AND r0, r0, r0
BRLID r15, rt_interrupt_leave
AND r0, r0, r0
/*
* if rt_thread_switch_interrupt_flag set, jump to
* rt_hw_context_switch_interrupt_do and don't return
*/
LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0
/*
* if rt_thread_switch_interrupt_flag set, jump to
* rt_hw_context_switch_interrupt_do and don't return
*/
LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0
ANDI r4, r4, 1
BNEI r4, rt_hw_context_switch_interrupt_do
ANDI r4, r4, 1
BNEI r4, rt_hw_context_switch_interrupt_do
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT
MTS RMSR, r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT
MTS RMSR,r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0
AND r0, r0, r0
RTID r14, 0
AND r0, r0, r0
/*
* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
*/
rt_hw_context_switch_interrupt_do:
SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */
SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */
LA r3, r0, rt_interrupt_from_thread
LW r4, r0, r3
SWI r1, r4, 0 /* store sp in preempted tasks's TCB */
LA r3, r0, rt_interrupt_from_thread
LW r4, r0, r3
SWI r1, r4, 0 /* store sp in preempted tasks's TCB */
LA r3, r0, rt_interrupt_to_thread
LW r4, r0, r3
LWI r1, r4, 0 /* get new task's stack pointer */
LA r3, r0, rt_interrupt_to_thread
LW r4, r0, r3
LWI r1, r4, 0 /* get new task's stack pointer */
LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT
BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT
BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR
MTS RMSR, r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTSD r15, 8
AND r0, r0, r0
LWI r3, r1, STACK_RMSR
MTS RMSR,r3
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTSD r15, 8
AND r0, r0, r0
return_with_ie:
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3
LWI r3, r1, STACK_R03
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR,r3
LWI r3, r1, STACK_R03
POP_ALL
ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0
.end _interrupt_handler
.end _interrupt_handler

View File

@@ -22,23 +22,23 @@
typedef volatile rt_uint32_t REG32;
struct rt_mb_uart_lite_hw
{
REG32 Rx_FIFO; // Receiver Holding Register
REG32 Tx_FIFO; // Transmitter Holding Register
REG32 STAT_REG; // Channel Status Register
REG32 CTRL_REG; // Control Register
REG32 Rx_FIFO; // Receiver Holding Register
REG32 Tx_FIFO; // Transmitter Holding Register
REG32 STAT_REG; // Channel Status Register
REG32 CTRL_REG; // Control Register
};
struct rt_mb_uart_lite
{
struct rt_device parent;
struct rt_device parent;
struct rt_mb_uart_lite_hw* hw_base;
rt_uint16_t peripheral_id;
rt_uint32_t baudrate;
struct rt_mb_uart_lite_hw* hw_base;
rt_uint16_t peripheral_id;
rt_uint32_t baudrate;
/* reception field */
rt_uint16_t save_index, read_index;
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
/* reception field */
rt_uint16_t save_index, read_index;
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
};
#ifdef RT_USING_UART1
struct rt_mb_uart_lite serial1;
@@ -46,263 +46,271 @@ struct rt_mb_uart_lite serial1;
static void rt_hw_serial_isr(void)
{
unsigned int status;
rt_base_t level;
struct rt_device* device;
struct rt_mb_uart_lite* serial = RT_NULL;
unsigned int status;
rt_base_t level;
struct rt_device* device;
struct rt_mb_uart_lite* serial = RT_NULL;
#ifdef RT_USING_UART1
/* serial 1 */
serial = &serial1;
/* serial 1 */
serial = &serial1;
#endif
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(serial != RT_NULL);
/* get generic device object */
device = (rt_device_t) serial;
/* get generic device object */
device = (rt_device_t)serial;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* get uart status register */
status = serial->hw_base->STAT_REG;
while (status & XUL_SR_RX_FIFO_VALID_DATA)
{
/* get received character */
serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO;
/* get uart status register */
status = serial->hw_base->STAT_REG;
while (status & XUL_SR_RX_FIFO_VALID_DATA)
{
/* get received character */
serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO;
/* move to next position */
serial->save_index++;
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
serial->save_index = 0;
/* move to next position */
serial->save_index ++;
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
serial->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (serial->save_index == serial->read_index)
{
serial->read_index++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
status = serial->hw_base->STAT_REG;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* if the next position is read index, discard this 'read char' */
if (serial->save_index == serial->read_index)
{
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
status = serial->hw_base->STAT_REG;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* indicate to upper layer application */
if (device->rx_indicate != RT_NULL)
device->rx_indicate(device, 1);
/* indicate to upper layer application */
if (device->rx_indicate != RT_NULL)
device->rx_indicate(device, 1);
}
static rt_err_t rt_serial_init(rt_device_t dev)
static rt_err_t rt_serial_init (rt_device_t dev)
{
struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev;
struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(serial->peripheral_id != XPAR_INTC_0_UARTLITE_1_VEC_ID);
RT_ASSERT(serial->peripheral_id != XPAR_UARTLITE_1_DEVICE_ID);
/* reset rx index */
serial->save_index = 0;
serial->read_index = 0;
/* reset rx buffer */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
/* reset rx index */
serial->save_index = 0;
serial->read_index = 0;
return RT_EOK;
/* reset rx buffer */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
return RT_EOK;
}
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL);
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* enable UART rx interrupt */
serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; /* enable interrupt */
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* enable UART rx interrupt */
serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; /* enable interrupt */
/* install UART handler */
rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t) rt_hw_serial_isr, RT_NULL);
rt_hw_interrupt_umask(serial->peripheral_id);
}
/* install UART handler */
rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t)rt_hw_serial_isr, RT_NULL);
rt_hw_interrupt_umask(serial->peripheral_id);
}
return RT_EOK;
return RT_EOK;
}
static rt_err_t rt_serial_close(rt_device_t dev)
{
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL);
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* disable interrupt */
serial->hw_base->CTRL_REG = 0; /* RxReady interrupt */
}
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* disable interrupt */
serial->hw_base->CTRL_REG = 0; /* RxReady interrupt */
}
return RT_EOK;
return RT_EOK;
}
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL);
rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL);
/* point to buffer */
ptr = (rt_uint8_t*) buffer;
/* point to buffer */
ptr = (rt_uint8_t*) buffer;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
while (size)
{
/* interrupt receive */
rt_base_t level;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
while (size)
{
/* interrupt receive */
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial->read_index != serial->save_index)
{
*ptr = serial->rx_buffer[serial->read_index];
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial->read_index != serial->save_index)
{
*ptr = serial->rx_buffer[serial->read_index];
serial->read_index++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
} else
{
/* no data in rx buffer */
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
else
{
/* no data in rx buffer */
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* enable interrupt */
rt_hw_interrupt_enable(level);
ptr++;
size--;
}
ptr ++; size --;
}
return (rt_uint32_t) ptr - (rt_uint32_t) buffer;
} else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
{
/* not support right now */
RT_ASSERT(0);
} else
{
/* poll mode */
while (size)
{
/* Wait for Full Rx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA))
;
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
{
/* not support right now */
RT_ASSERT(0);
}
else
{
/* poll mode */
while (size)
{
/* Wait for Full Rx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA));
/* Read Character */
*ptr = serial->hw_base->Rx_FIFO;
ptr++;
size--;
}
/* Read Character */
*ptr = serial->hw_base->Rx_FIFO;
ptr ++;
size --;
}
return (rt_size_t) ptr - (rt_size_t) buffer;
}
return (rt_size_t)ptr - (rt_size_t)buffer;
}
return 0;
return 0;
}
static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL);
rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL);
ptr = (rt_uint8_t*) buffer;
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
/* it's a stream mode device */
while (size)
{
/* stream mode */
if (*ptr == '\n')
{
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY))
;
serial->hw_base->Tx_FIFO = '\r';
}
ptr = (rt_uint8_t*) buffer;
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
/* it's a stream mode device */
while (size)
{
/* stream mode */
if (*ptr == '\n')
{
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
serial->hw_base->Tx_FIFO = '\r';
}
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY)) ;
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
/* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr;
ptr++;
size--;
}
}
else
{
while (size)
{
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY))
;
/* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr;
if (*ptr & 1)
rt_hw_board_led_on(2);
else
rt_hw_board_led_off(2);
ptr ++; size --;
}
}
else
{
while (size)
{
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
/* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr;
ptr++;
size--;
}
}
}
/* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr;
if (*ptr & 1)
rt_hw_board_led_on(2);
else
rt_hw_board_led_off(2);
ptr ++; size --;
}
}
}
return (rt_size_t) ptr - (rt_size_t) buffer;
return (rt_size_t)ptr - (rt_size_t)buffer;
}
static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
{
return RT_EOK;
return RT_EOK;
}
rt_err_t rt_hw_serial_init()
{
rt_device_t device;
rt_device_t device;
#ifndef RT_USING_CONSOLE
int Status;
int Status;
/*
* Initialize the UartLite driver so that it is ready to use.
*/
Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return;
}
/*
* Initialize the UartLite driver so that it is ready to use.
*/
Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return;
}
#endif
#ifdef RT_USING_UART1
device = (rt_device_t) &serial1;
device = (rt_device_t) &serial1;
/* init serial device private data */
serial1.hw_base = (struct rt_mb_uart_lite_hw*) XPAR_USB_UART_BASEADDR;
serial1.peripheral_id = XPAR_INTC_0_UARTLITE_1_VEC_ID;
serial1.baudrate = 9600;
/* init serial device private data */
serial1.hw_base = (struct rt_mb_uart_lite_hw*)XPAR_USB_UART_BASEADDR;
serial1.peripheral_id = XPAR_UARTLITE_1_DEVICE_ID;
serial1.baudrate = 115200;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* register uart1 on device subsystem */
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
/* register uart1 on device subsystem */
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif
return RT_EOK;
return RT_EOK;
}

View File

@@ -13,8 +13,10 @@
*
*/
#include <rtthread.h>
extern void *_SDA_BASE_;
extern void *_SDA2_BASE_;
extern void *_SDA_BASE_;
extern void *_SDA2_BASE_;
/**
* This function will initialize thread stack
@@ -26,43 +28,44 @@ extern void *_SDA2_BASE_;
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{
unsigned long *stk;
unsigned long *stk;
stk = (unsigned long *) stack_addr;
stk--;
stk--;
*stk-- = 0; /* r31 */
*stk-- = 0; /* r30 */
*stk-- = 0; /* r29 */
*stk-- = 0; /* r28 */
*stk-- = 0; /* r27 */
*stk-- = 0; /* r26 */
*stk-- = 0; /* r25 */
*stk-- = 0; /* r24 */
*stk-- = 0; /* r23 */
*stk-- = 0; /* r22 */
*stk-- = 0; /* r21 */
*stk-- = 0; /* r20 */
*stk-- = 0; /* r19 */
*stk-- = 0; /* r18 */
*stk-- = 0; /* r17 */
*stk-- = (unsigned long) texit - 8; /* r15 = task return address*/
*stk-- = (unsigned long) tentry; /* r14 = entry address*/
*stk-- = (unsigned long) &_SDA_BASE_; /* r13 */
*stk-- = 0; /* r12 */
*stk-- = 0; /* r11 */
*stk-- = 0; /* r10 */
*stk-- = 0; /* r09 */
*stk-- = 0; /* r08 */
*stk-- = 0; /* r07 */
*stk-- = 0; /* r06 */
*stk-- = (unsigned long) parameter; /* r05 */
*stk-- = 0; /* r04 */
*stk-- = 0; /* r03 */
*stk-- = (unsigned long) &_SDA2_BASE_; /* r02 */
*stk = 2; /* enable interrupt */
return (rt_uint8_t *) stk;
stk = (unsigned long *)stack_addr;
stk--;
stk--;
*stk-- = 0; /* r31 */
*stk-- = 0; /* r30 */
*stk-- = 0; /* r29 */
*stk-- = 0; /* r28 */
*stk-- = 0; /* r27 */
*stk-- = 0; /* r26 */
*stk-- = 0; /* r25 */
*stk-- = 0; /* r24 */
*stk-- = 0; /* r23 */
*stk-- = 0; /* r22 */
*stk-- = 0; /* r21 */
*stk-- = 0; /* r20 */
*stk-- = 0; /* r19 */
*stk-- = 0; /* r18 */
*stk-- = 0; /* r17 */
*stk-- = (unsigned long)texit - 8; /* r15 = task return address*/
*stk-- = (unsigned long)tentry; /* r14 = entry address*/
*stk-- = (unsigned long)&_SDA_BASE_; /* r13 */
*stk-- = 0; /* r12 */
*stk-- = 0; /* r11 */
*stk-- = 0; /* r10 */
*stk-- = 0; /* r09 */
*stk-- = 0; /* r08 */
*stk-- = 0; /* r07 */
*stk-- = 0; /* r06 */
*stk-- = (unsigned long) parameter; /* r05 */
*stk-- = 0; /* r04 */
*stk-- = 0; /* r03 */
*stk-- = (unsigned long)&_SDA2_BASE_; /* r02 */
*stk = 2; /* enable interrupt */
return (rt_uint8_t *)stk;
}

View File

@@ -20,17 +20,20 @@
#include "xintc_i.h"
#include "xintc_l.h"
#define MAX_HANDLERS XPAR_INTC_MAX_NUM_INTR_INPUTS
extern XIntc int_ctl; /* The instance of the Interrupt Controller */
extern rt_uint32_t rt_interrupt_nest;
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
void rt_hw_interrupt_handler(int vector)
{
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
}
/**
@@ -38,22 +41,24 @@ void rt_hw_interrupt_handler(int vector)
*/
void rt_hw_interrupt_init()
{
rt_base_t index;
rt_base_t index;
XIntc_Config *CfgPtr;
XIntc_Config *CfgPtr;
CfgPtr = &XIntc_ConfigTable[0];
for (index = 0; index < MAX_HANDLERS; index++)
{
CfgPtr->HandlerTable[index].Handler = (XInterruptHandler) rt_hw_interrupt_handler;
}
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
for (index = 0; index < MAX_HANDLERS; index ++)
{
CfgPtr->HandlerTable[index].Handler = (XInterruptHandler)rt_hw_interrupt_handler;
}
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
}
/**
@@ -62,8 +67,8 @@ void rt_hw_interrupt_init()
*/
void rt_hw_interrupt_mask(int vector)
{
/* disable interrupt */
XIntc_Disable(&int_ctl, vector);
/* disable interrupt */
XIntc_Disable(&int_ctl,vector);
}
/**
@@ -72,7 +77,7 @@ void rt_hw_interrupt_mask(int vector)
*/
void rt_hw_interrupt_umask(int vector)
{
XIntc_Enable(&int_ctl, vector);
XIntc_Enable(&int_ctl,vector);
}
/**
@@ -83,123 +88,124 @@ void rt_hw_interrupt_umask(int vector)
*/
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
{
XIntc_Config *CfgPtr;
XIntc_Config *CfgPtr;
CfgPtr = &XIntc_ConfigTable[0];
if (vector >= 0 && vector < MAX_HANDLERS)
{
if (*old_handler != RT_NULL)
*old_handler = (rt_isr_handler_t) CfgPtr->HandlerTable[vector].Handler;
if (new_handler != RT_NULL)
CfgPtr->HandlerTable[vector].Handler = (XInterruptHandler) new_handler;
}
if(vector >= 0 && vector < MAX_HANDLERS)
{
if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)CfgPtr->HandlerTable[vector].Handler;
if (new_handler != RT_NULL) CfgPtr->HandlerTable[vector].Handler = (XInterruptHandler)new_handler;
}
}
/*****************************************************************************/
/** copy from XIntc_DeviceInterruptHandler in xintc_l.c nl1031
*
* This function is the primary interrupt handler for the driver. It must be
* connected to the interrupt source such that is called when an interrupt of
* the interrupt controller is active. It will resolve which interrupts are
* active and enabled and call the appropriate interrupt handler. It uses
* the AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first.
* The driver can be configured to service only the highest priority interrupt
* or all pending interrupts using the {XIntc_SetOptions()} function or
* the {XIntc_SetIntrSrvOption()} function.
*
* This function assumes that an interrupt vector table has been previously
* initialized. It does not verify that entries in the table are valid before
* calling an interrupt handler.
*
*
* @return None.
*
* @note
*
* The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile.
* Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals
* for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the
* highest numbered interrupt input signal that is used.
*
******************************************************************************/
*
* This function is the primary interrupt handler for the driver. It must be
* connected to the interrupt source such that is called when an interrupt of
* the interrupt controller is active. It will resolve which interrupts are
* active and enabled and call the appropriate interrupt handler. It uses
* the AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first.
* The driver can be configured to service only the highest priority interrupt
* or all pending interrupts using the {XIntc_SetOptions()} function or
* the {XIntc_SetIntrSrvOption()} function.
*
* This function assumes that an interrupt vector table has been previously
* initialized. It does not verify that entries in the table are valid before
* calling an interrupt handler.
*
*
* @return None.
*
* @note
*
* The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile.
* Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals
* for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the
* highest numbered interrupt input signal that is used.
*
******************************************************************************/
void rt_hw_trap_irq(void)
void rt_hw_trap_irq(void )
{
u32 intr_status;
u32 intr_mask = 1;
int intr_number;
volatile u32 reg; /* used as bit bucket */
XIntc_Config *cfg_ptr;
u32 intr_status;
u32 intr_mask = 1;
int intr_number;
volatile u32 reg; /* used as bit bucket */
XIntc_Config *cfg_ptr;
/* Get the configuration data using the device ID */
cfg_ptr = &XIntc_ConfigTable[0];
/* Get the interrupts that are waiting to be serviced */
intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR);
/* Get the configuration data using the device ID */
cfg_ptr = &XIntc_ConfigTable[0];
/* Service each interrupt that is active and enabled by checking each
* bit in the register from LSB to MSB which corresponds to an interrupt
* intput signal
*/
for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++)
{
if (intr_status & 1)
{
XIntc_VectorTableEntry *table_ptr;
/* Get the interrupts that are waiting to be serviced */
intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR);
/* If the interrupt has been setup to acknowledge it
* before servicing the interrupt, then ack it
*/
if (cfg_ptr->AckBeforeService & intr_mask)
{
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/* Service each interrupt that is active and enabled by checking each
* bit in the register from LSB to MSB which corresponds to an interrupt
* intput signal
*/
for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++)
{
if (intr_status & 1)
{
XIntc_VectorTableEntry *table_ptr;
/* The interrupt is active and enabled, call the
* interrupt handler that was setup with the specified
* parameter
*/
table_ptr = &(cfg_ptr->HandlerTable[intr_number]);
table_ptr->Handler(table_ptr->CallBackRef);
/* If the interrupt has been setup to acknowledge it
* before servicing the interrupt, then ack it
*/
if (cfg_ptr->AckBeforeService & intr_mask)
{
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/* If the interrupt has been setup to acknowledge it
* after it has been serviced then ack it
*/
if ((cfg_ptr->AckBeforeService & intr_mask) == 0)
{
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/* The interrupt is active and enabled, call the
* interrupt handler that was setup with the specified
* parameter
*/
table_ptr = &(cfg_ptr->HandlerTable[intr_number]);
table_ptr->Handler(table_ptr->CallBackRef);
/*
* Read the ISR again to handle architectures with posted write
* bus access issues.
*/
reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress);
/* If the interrupt has been setup to acknowledge it
* after it has been serviced then ack it
*/
if ((cfg_ptr->AckBeforeService & intr_mask) == 0)
{
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/*
* If only the highest priority interrupt is to be
* serviced, exit loop and return after servicing
* the interrupt
*/
if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION)
{
return;
}
}
/*
* Read the ISR again to handle architectures with posted write
* bus access issues.
*/
reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress);
/* Move to the next interrupt to check */
intr_mask <<= 1;
intr_status >>= 1;
/*
* If only the highest priority interrupt is to be
* serviced, exit loop and return after servicing
* the interrupt
*/
if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION)
{
return;
}
}
/* If there are no other bits set indicating that all interrupts
* have been serviced, then exit the loop
*/
if (intr_status == 0)
{
break;
}
}
/* Move to the next interrupt to check */
intr_mask <<= 1;
intr_status >>= 1;
/* If there are no other bits set indicating that all interrupts
* have been serviced, then exit the loop
*/
if (intr_status == 0)
{
break;
}
}
}