AT91SAM9260 branch
1. Support Keil MDK development environment 2. Modify EMAC driver according to the changes of lwIP API in reversion 1668 and 1669 git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1681 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
1f1c6fb47e
commit
da74af2347
|
@ -32,6 +32,16 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(RT_USING_DFS_DEVFS)
|
||||||
|
#include <devfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_LWIP
|
||||||
|
#include <netif/ethernetif.h>
|
||||||
|
#include <arch/sys_arch_init.h>
|
||||||
|
#include "macb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RT_USING_LED
|
#ifdef RT_USING_LED
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,6 +100,7 @@ void rt_init_thread_entry(void* parameter)
|
||||||
rt_kprintf("UFFS File System initialzation failed!\n");
|
rt_kprintf("UFFS File System initialzation failed!\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -98,8 +109,6 @@ void rt_init_thread_entry(void* parameter)
|
||||||
/* register ethernetif device */
|
/* register ethernetif device */
|
||||||
eth_system_device_init();
|
eth_system_device_init();
|
||||||
rt_hw_macb_init();
|
rt_hw_macb_init();
|
||||||
/* re-init device driver */
|
|
||||||
rt_device_init_all();
|
|
||||||
/* init lwip system */
|
/* init lwip system */
|
||||||
lwip_sys_init();
|
lwip_sys_init();
|
||||||
rt_kprintf("TCP/IP initialized!\n");
|
rt_kprintf("TCP/IP initialized!\n");
|
||||||
|
|
|
@ -68,7 +68,7 @@ struct rt_macb_eth
|
||||||
/* inherit from ethernet device */
|
/* inherit from ethernet device */
|
||||||
struct eth_device parent;
|
struct eth_device parent;
|
||||||
|
|
||||||
void *regs;
|
unsigned int regs;
|
||||||
|
|
||||||
unsigned int rx_tail;
|
unsigned int rx_tail;
|
||||||
unsigned int tx_head;
|
unsigned int tx_head;
|
||||||
|
@ -213,9 +213,9 @@ static rt_uint16_t macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg)
|
||||||
|
|
||||||
static void macb_phy_reset(rt_device_t dev)
|
static void macb_phy_reset(rt_device_t dev)
|
||||||
{
|
{
|
||||||
struct rt_macb_eth *macb = dev->user_data;;
|
|
||||||
int i;
|
int i;
|
||||||
rt_uint16_t status, adv;
|
rt_uint16_t status, adv;
|
||||||
|
struct rt_macb_eth *macb = dev->user_data;;
|
||||||
|
|
||||||
adv = ADVERTISE_CSMA | ADVERTISE_ALL;
|
adv = ADVERTISE_CSMA | ADVERTISE_ALL;
|
||||||
macb_mdio_write(macb, MII_ADVERTISE, adv);
|
macb_mdio_write(macb, MII_ADVERTISE, adv);
|
||||||
|
@ -322,13 +322,15 @@ void macb_update_link(struct rt_macb_eth *macb)
|
||||||
? 100 : 10);
|
? 100 : 10);
|
||||||
macb->duplex = (media & ADVERTISE_FULL) ? 1 : 0;
|
macb->duplex = (media & ADVERTISE_FULL) ? 1 : 0;
|
||||||
rt_kprintf("%s: link up (%dMbps/%s-duplex)\n",
|
rt_kprintf("%s: link up (%dMbps/%s-duplex)\n",
|
||||||
dev->parent.name, macb->speed,
|
dev->parent.name, macb->speed,
|
||||||
DUPLEX_FULL == macb->duplex ? "Full":"Half");
|
DUPLEX_FULL == macb->duplex ? "Full":"Half");
|
||||||
netif_set_link_up(macb->parent.netif);
|
macb->parent.link_status = 1;
|
||||||
} else {
|
} else {
|
||||||
rt_kprintf("%s: link down\n", dev->parent.name);
|
rt_kprintf("%s: link down\n", dev->parent.name);
|
||||||
netif_set_link_down(macb->parent.netif);
|
macb->parent.link_status = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eth_device_linkchange(&macb->parent, RT_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -458,13 +460,11 @@ static rt_err_t rt_macb_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
/* transmit packet. */
|
/* transmit packet. */
|
||||||
rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p)
|
rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p)
|
||||||
{
|
{
|
||||||
struct rt_macb_eth *macb = dev->user_data;
|
|
||||||
struct pbuf* q;
|
struct pbuf* q;
|
||||||
rt_uint32_t len;
|
|
||||||
rt_uint8_t* bufptr, *buf = RT_NULL;
|
rt_uint8_t* bufptr, *buf = RT_NULL;
|
||||||
unsigned long paddr, ctrl;
|
unsigned long ctrl;
|
||||||
|
struct rt_macb_eth *macb = dev->user_data;
|
||||||
unsigned int tx_head = macb->tx_head;
|
unsigned int tx_head = macb->tx_head;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* lock macb device */
|
/* lock macb device */
|
||||||
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
||||||
|
@ -500,7 +500,6 @@ rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p)
|
||||||
/* wait ack */
|
/* wait ack */
|
||||||
rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
|
||||||
rt_free(buf);
|
rt_free(buf);
|
||||||
buf == RT_NULL;
|
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +554,7 @@ struct pbuf *rt_macb_rx(rt_device_t dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & RXBUF_FRAME_END) {
|
if (status & RXBUF_FRAME_END) {
|
||||||
buffer = macb->rx_buffer + 128 * macb->rx_tail;
|
buffer = (void *)((unsigned int)macb->rx_buffer + 128 * macb->rx_tail);
|
||||||
len = status & RXBUF_FRMLEN_MASK;
|
len = status & RXBUF_FRMLEN_MASK;
|
||||||
p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
|
p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
|
||||||
if (!p)
|
if (!p)
|
||||||
|
@ -579,14 +578,14 @@ struct pbuf *rt_macb_rx(rt_device_t dev)
|
||||||
taillen = len - headlen;
|
taillen = len - headlen;
|
||||||
memcpy((void *)buf,
|
memcpy((void *)buf,
|
||||||
buffer, headlen);
|
buffer, headlen);
|
||||||
memcpy((void *)buf + headlen,
|
memcpy((void *)((unsigned int)buf + headlen),
|
||||||
macb->rx_buffer, taillen);
|
macb->rx_buffer, taillen);
|
||||||
buffer = (void *)buf;
|
buffer = (void *)buf;
|
||||||
for (q = p; q != RT_NULL; q= q->next)
|
for (q = p; q != RT_NULL; q= q->next)
|
||||||
{
|
{
|
||||||
/* read data from device */
|
/* read data from device */
|
||||||
memcpy((void *)q->payload, buffer, q->len);
|
memcpy((void *)q->payload, buffer, q->len);
|
||||||
buffer += q->len;
|
buffer = (void *)((unsigned int)buffer + q->len);
|
||||||
}
|
}
|
||||||
rt_free(buf);
|
rt_free(buf);
|
||||||
buf = RT_NULL;
|
buf = RT_NULL;
|
||||||
|
@ -595,7 +594,7 @@ struct pbuf *rt_macb_rx(rt_device_t dev)
|
||||||
{
|
{
|
||||||
/* read data from device */
|
/* read data from device */
|
||||||
memcpy((void *)q->payload, buffer, q->len);
|
memcpy((void *)q->payload, buffer, q->len);
|
||||||
buffer += q->len;
|
buffer = (void *)((unsigned int)buffer + q->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -643,7 +642,7 @@ void macb_initialize()
|
||||||
macb->rx_ring_dma = (unsigned long)macb->rx_ring;
|
macb->rx_ring_dma = (unsigned long)macb->rx_ring;
|
||||||
macb->tx_ring_dma = (unsigned long)macb->tx_ring;
|
macb->tx_ring_dma = (unsigned long)macb->tx_ring;
|
||||||
|
|
||||||
macb->regs = (void *)AT91SAM9260_BASE_EMAC;
|
macb->regs = AT91SAM9260_BASE_EMAC;
|
||||||
macb->phy_addr = 0x00;
|
macb->phy_addr = 0x00;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -330,6 +330,7 @@ struct dma_desc {
|
||||||
#define MACB_TX_USED_OFFSET 31
|
#define MACB_TX_USED_OFFSET 31
|
||||||
#define MACB_TX_USED_SIZE 1
|
#define MACB_TX_USED_SIZE 1
|
||||||
|
|
||||||
|
void rt_hw_macb_init();
|
||||||
|
|
||||||
#endif /* _MACB_H */
|
#endif /* _MACB_H */
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@
|
||||||
* 100T4 this is fine. If your phy places 100T4 elsewhere in the
|
* 100T4 this is fine. If your phy places 100T4 elsewhere in the
|
||||||
* priority order, you will need to roll your own function.
|
* priority order, you will need to roll your own function.
|
||||||
*/
|
*/
|
||||||
static inline unsigned int mii_nway_result (unsigned int negotiated)
|
rt_inline unsigned int mii_nway_result (unsigned int negotiated)
|
||||||
{
|
{
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,17 @@
|
||||||
#include <finsh.h>
|
#include <finsh.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_DEVICE
|
||||||
|
#include <serial.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void rt_hw_interrupt_init(void);
|
extern void rt_hw_interrupt_init(void);
|
||||||
extern void rt_hw_board_init(void);
|
extern void rt_hw_board_init(void);
|
||||||
extern void rt_serial_init(void);
|
extern void rt_serial_init(void);
|
||||||
extern void rt_system_timer_init(void);
|
extern void rt_system_timer_init(void);
|
||||||
extern void rt_system_scheduler_init(void);
|
extern void rt_system_scheduler_init(void);
|
||||||
extern void rt_thread_idle_init(void);
|
extern void rt_thread_idle_init(void);
|
||||||
|
extern void mmu_invalidate_icache();
|
||||||
extern void rt_hw_cpu_icache_enable(void);
|
extern void rt_hw_cpu_icache_enable(void);
|
||||||
extern void rt_show_version(void);
|
extern void rt_show_version(void);
|
||||||
extern void rt_system_heap_init(void*, void*);
|
extern void rt_system_heap_init(void*, void*);
|
||||||
|
@ -174,4 +179,12 @@ void rtthread_startup(void)
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
/* startup RT-Thread RTOS */
|
||||||
|
rtthread_startup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -203,6 +203,10 @@ struct rt_hw_register
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
extern struct clk *clk_get(const char *id);
|
||||||
|
extern rt_uint32_t clk_get_rate(struct clk *clk);
|
||||||
|
extern void rt_hw_clock_init(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
;/*
|
||||||
|
; * File : context_rvds.S
|
||||||
|
; * This file is part of RT-Thread RTOS
|
||||||
|
; * COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
; *
|
||||||
|
; * The license and distribution terms for this file may be
|
||||||
|
; * found in the file LICENSE in this distribution or at
|
||||||
|
; * http://www.rt-thread.org/license/LICENSE
|
||||||
|
; *
|
||||||
|
; * Change Logs:
|
||||||
|
; * Date Author Notes
|
||||||
|
; * 2011-08-14 weety copy from mini2440
|
||||||
|
; */
|
||||||
|
|
||||||
|
NOINT EQU 0xc0 ; disable interrupt in psr
|
||||||
|
|
||||||
|
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||||
|
ARM
|
||||||
|
REQUIRE8
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * rt_base_t rt_hw_interrupt_disable();
|
||||||
|
; */
|
||||||
|
rt_hw_interrupt_disable PROC
|
||||||
|
EXPORT rt_hw_interrupt_disable
|
||||||
|
MRS r0, cpsr
|
||||||
|
ORR r1, r0, #NOINT
|
||||||
|
MSR cpsr_c, r1
|
||||||
|
BX lr
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * void rt_hw_interrupt_enable(rt_base_t level);
|
||||||
|
; */
|
||||||
|
rt_hw_interrupt_enable PROC
|
||||||
|
EXPORT rt_hw_interrupt_enable
|
||||||
|
MSR cpsr_c, r0
|
||||||
|
BX lr
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||||
|
; * r0 --> from
|
||||||
|
; * r1 --> to
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch PROC
|
||||||
|
EXPORT rt_hw_context_switch
|
||||||
|
STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC)
|
||||||
|
STMFD sp!, {r0-r12, lr} ; push lr & register file
|
||||||
|
|
||||||
|
MRS r4, cpsr
|
||||||
|
STMFD sp!, {r4} ; push cpsr
|
||||||
|
MRS r4, spsr
|
||||||
|
STMFD sp!, {r4} ; push spsr
|
||||||
|
|
||||||
|
STR sp, [r0] ; store sp in preempted tasks TCB
|
||||||
|
LDR sp, [r1] ; get new task stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task cpsr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * void rt_hw_context_switch_to(rt_uint32 to);
|
||||||
|
; * r0 --> to
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch_to PROC
|
||||||
|
EXPORT rt_hw_context_switch_to
|
||||||
|
LDR sp, [r0] ; get new task stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task cpsr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
|
||||||
|
; */
|
||||||
|
IMPORT rt_thread_switch_interrput_flag
|
||||||
|
IMPORT rt_interrupt_from_thread
|
||||||
|
IMPORT rt_interrupt_to_thread
|
||||||
|
|
||||||
|
rt_hw_context_switch_interrupt PROC
|
||||||
|
EXPORT rt_hw_context_switch_interrupt
|
||||||
|
LDR r2, =rt_thread_switch_interrput_flag
|
||||||
|
LDR r3, [r2]
|
||||||
|
CMP r3, #1
|
||||||
|
BEQ _reswitch
|
||||||
|
MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1
|
||||||
|
STR r3, [r2]
|
||||||
|
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||||
|
STR r0, [r2]
|
||||||
|
_reswitch
|
||||||
|
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||||
|
STR r1, [r2]
|
||||||
|
BX lr
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
END
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __GPIO_H__
|
#ifndef __GPIO_H__
|
||||||
#define __GPIO_H__
|
#define __GPIO_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
#include <at91_aic.h>
|
#include <at91_aic.h>
|
||||||
|
|
||||||
#define PIN_BASE AIC_IRQS
|
#define PIN_BASE AIC_IRQS
|
||||||
|
@ -111,7 +112,7 @@
|
||||||
#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
|
#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
|
||||||
|
|
||||||
|
|
||||||
static inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio)
|
rt_inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio)
|
||||||
{
|
{
|
||||||
return gpio;
|
return gpio;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,9 @@ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = {
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_mask(int irq);
|
||||||
|
void rt_hw_interrupt_umask(int irq);
|
||||||
|
|
||||||
rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
|
rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
|
||||||
{
|
{
|
||||||
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
@ -102,7 +105,7 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector)
|
||||||
irq_n = AIC_IRQS + 32*2;
|
irq_n = AIC_IRQS + 32*2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return;
|
return RT_NULL;
|
||||||
isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR);
|
isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR);
|
||||||
while (isr)
|
while (isr)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +116,8 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector)
|
||||||
isr >>= 1;
|
isr >>= 1;
|
||||||
irq_n++;
|
irq_n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -28,16 +28,16 @@
|
||||||
#define writel(v,a) (*(volatile unsigned int *)(a) = (v))
|
#define writel(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||||
|
|
||||||
|
|
||||||
static inline unsigned int at91_sys_read(unsigned int reg_offset)
|
rt_inline unsigned int at91_sys_read(unsigned int reg_offset)
|
||||||
{
|
{
|
||||||
void *addr = (void *)AT91_BASE_SYS;
|
unsigned int addr = AT91_BASE_SYS;
|
||||||
|
|
||||||
return readl(addr + reg_offset);
|
return readl(addr + reg_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
|
rt_inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
|
||||||
{
|
{
|
||||||
void *addr = (void *)AT91_BASE_SYS;
|
unsigned int addr = AT91_BASE_SYS;
|
||||||
|
|
||||||
writel(value, addr + reg_offset);
|
writel(value, addr + reg_offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
;/*
|
||||||
|
; * File : start_rvds.S
|
||||||
|
; * This file is part of RT-Thread RTOS
|
||||||
|
; * COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
; *
|
||||||
|
; * The license and distribution terms for this file may be
|
||||||
|
; * found in the file LICENSE in this distribution or at
|
||||||
|
; * http://www.rt-thread.org/license/LICENSE
|
||||||
|
; *
|
||||||
|
; * Change Logs:
|
||||||
|
; * Date Author Notes
|
||||||
|
; * 2011-08-14 weety first version
|
||||||
|
; */
|
||||||
|
|
||||||
|
|
||||||
|
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
|
||||||
|
|
||||||
|
Mode_USR EQU 0x10
|
||||||
|
Mode_FIQ EQU 0x11
|
||||||
|
Mode_IRQ EQU 0x12
|
||||||
|
Mode_SVC EQU 0x13
|
||||||
|
Mode_ABT EQU 0x17
|
||||||
|
Mode_UND EQU 0x1B
|
||||||
|
Mode_SYS EQU 0x1F
|
||||||
|
|
||||||
|
SVCMODE EQU 0x13
|
||||||
|
MODEMASK EQU 0x1f
|
||||||
|
|
||||||
|
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
|
||||||
|
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------- Stack and Heap Definitions ----------------------------
|
||||||
|
|
||||||
|
;// <h> Stack Configuration (Stack Sizes in Bytes)
|
||||||
|
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
UND_Stack_Size EQU 512
|
||||||
|
SVC_Stack_Size EQU 4096
|
||||||
|
ABT_Stack_Size EQU 512
|
||||||
|
FIQ_Stack_Size EQU 1024
|
||||||
|
IRQ_Stack_Size EQU 1024
|
||||||
|
USR_Stack_Size EQU 512
|
||||||
|
|
||||||
|
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||||
|
FIQ_Stack_Size + IRQ_Stack_Size)
|
||||||
|
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
|
||||||
|
Stack_Mem SPACE USR_Stack_Size
|
||||||
|
__initial_sp SPACE ISR_Stack_Size
|
||||||
|
Stack_Top
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Heap Configuration
|
||||||
|
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
Heap_Size EQU 0x00000000
|
||||||
|
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
Heap_Mem SPACE Heap_Size
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------- Memory Definitions ------------------------------------
|
||||||
|
|
||||||
|
AT91_MATRIX_BASE EQU 0xffffee00
|
||||||
|
AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100)
|
||||||
|
AT91_MATRIX_RCB0 EQU 0x00000001
|
||||||
|
AT91_MATRIX_RCB1 EQU 0x00000002
|
||||||
|
AT91_AIC_BASE EQU 0xfffff000
|
||||||
|
AT91_AIC_IDCR EQU 0x124
|
||||||
|
AT91_AIC_ICCR EQU 0x128
|
||||||
|
|
||||||
|
;----------------------- CODE --------------------------------------------------
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
|
||||||
|
; Area Definition and Entry Point
|
||||||
|
; Startup Code must be linked first at Address at which it expects to run.
|
||||||
|
|
||||||
|
AREA RESET, CODE, READONLY
|
||||||
|
ARM
|
||||||
|
|
||||||
|
; Exception Vectors
|
||||||
|
; Mapped to Address 0.
|
||||||
|
; Absolute addressing mode must be used.
|
||||||
|
; Dummy Handlers are implemented as infinite loops which can be modified.
|
||||||
|
|
||||||
|
EXPORT Entry_Point
|
||||||
|
Entry_Point
|
||||||
|
Vectors LDR PC, Reset_Addr
|
||||||
|
LDR PC, Undef_Addr
|
||||||
|
LDR PC, SWI_Addr
|
||||||
|
LDR PC, PAbt_Addr
|
||||||
|
LDR PC, DAbt_Addr
|
||||||
|
NOP
|
||||||
|
LDR PC, IRQ_Addr
|
||||||
|
LDR PC, FIQ_Addr
|
||||||
|
|
||||||
|
Reset_Addr DCD Reset_Handler
|
||||||
|
Undef_Addr DCD Undef_Handler
|
||||||
|
SWI_Addr DCD SWI_Handler
|
||||||
|
PAbt_Addr DCD PAbt_Handler
|
||||||
|
DAbt_Addr DCD DAbt_Handler
|
||||||
|
DCD 0 ; Reserved Address
|
||||||
|
IRQ_Addr DCD IRQ_Handler
|
||||||
|
FIQ_Addr DCD FIQ_Handler
|
||||||
|
|
||||||
|
Undef_Handler B Undef_Handler
|
||||||
|
SWI_Handler B SWI_Handler
|
||||||
|
PAbt_Handler B PAbt_Handler
|
||||||
|
;DAbt_Handler B DAbt_Handler
|
||||||
|
FIQ_Handler B FIQ_Handler
|
||||||
|
|
||||||
|
;*
|
||||||
|
;*************************************************************************
|
||||||
|
;*
|
||||||
|
;* Interrupt handling
|
||||||
|
;*
|
||||||
|
;*************************************************************************
|
||||||
|
;*
|
||||||
|
; DAbt Handler
|
||||||
|
DAbt_Handler
|
||||||
|
IMPORT rt_hw_trap_dabt
|
||||||
|
|
||||||
|
sub sp, sp, #72
|
||||||
|
stmia sp, {r0 - r12} ;/* Calling r0-r12 */
|
||||||
|
add r8, sp, #60
|
||||||
|
stmdb r8, {sp, lr} ;/* Calling SP, LR */
|
||||||
|
str lr, [r8, #0] ;/* Save calling PC */
|
||||||
|
mrs r6, spsr
|
||||||
|
str r6, [r8, #4] ;/* Save CPSR */
|
||||||
|
str r0, [r8, #8] ;/* Save OLD_R0 */
|
||||||
|
mov r0, sp
|
||||||
|
|
||||||
|
bl rt_hw_trap_dabt
|
||||||
|
|
||||||
|
|
||||||
|
;##########################################
|
||||||
|
; Reset Handler
|
||||||
|
|
||||||
|
EXPORT Reset_Handler
|
||||||
|
Reset_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; set the cpu to SVC32 mode-----------------------------------------------------
|
||||||
|
|
||||||
|
MRS R0,CPSR
|
||||||
|
BIC R0,R0,#MODEMASK
|
||||||
|
ORR R0,R0,#SVCMODE
|
||||||
|
MSR CPSR_cxsf,R0
|
||||||
|
LDR R1, =AT91_AIC_BASE
|
||||||
|
LDR R0, =0xffffffff
|
||||||
|
STR R0, [R1, #AT91_AIC_IDCR]
|
||||||
|
STR R0, [R1, #AT91_AIC_ICCR]
|
||||||
|
|
||||||
|
; remap internal ram to 0x00000000 address
|
||||||
|
LDR R0, =AT91_MATRIX_MRCR
|
||||||
|
LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
|
||||||
|
; Copy Exception Vectors to Internal RAM ---------------------------------------
|
||||||
|
|
||||||
|
ADR R8, Vectors ; Source
|
||||||
|
LDR R9, =0x00 ; Destination
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Vectors
|
||||||
|
STMIA R9!, {R0-R7} ; Store Vectors
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Handler Addresses
|
||||||
|
STMIA R9!, {R0-R7} ; Store Handler Addresses
|
||||||
|
|
||||||
|
|
||||||
|
; Setup Stack for each mode ----------------------------------------------------
|
||||||
|
|
||||||
|
LDR R0, =Stack_Top
|
||||||
|
|
||||||
|
; Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #UND_Stack_Size
|
||||||
|
|
||||||
|
; Enter Abort Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #ABT_Stack_Size
|
||||||
|
|
||||||
|
; Enter FIQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #FIQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter IRQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #IRQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter Supervisor Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #SVC_Stack_Size
|
||||||
|
|
||||||
|
; Enter User Mode and set its Stack Pointer
|
||||||
|
; MSR CPSR_c, #Mode_USR
|
||||||
|
MOV SP, R0
|
||||||
|
SUB SL, SP, #USR_Stack_Size
|
||||||
|
|
||||||
|
; Enter the C code -------------------------------------------------------------
|
||||||
|
|
||||||
|
IMPORT __main
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
IMPORT rt_interrupt_enter
|
||||||
|
IMPORT rt_interrupt_leave
|
||||||
|
IMPORT rt_thread_switch_interrput_flag
|
||||||
|
IMPORT rt_interrupt_from_thread
|
||||||
|
IMPORT rt_interrupt_to_thread
|
||||||
|
IMPORT rt_hw_trap_irq
|
||||||
|
|
||||||
|
IRQ_Handler PROC
|
||||||
|
EXPORT IRQ_Handler
|
||||||
|
STMFD sp!, {r0-r12,lr}
|
||||||
|
BL rt_interrupt_enter
|
||||||
|
BL rt_hw_trap_irq
|
||||||
|
BL rt_interrupt_leave
|
||||||
|
|
||||||
|
; if rt_thread_switch_interrput_flag set, jump to
|
||||||
|
; rt_hw_context_switch_interrupt_do and don't return
|
||||||
|
LDR r0, =rt_thread_switch_interrput_flag
|
||||||
|
LDR r1, [r0]
|
||||||
|
CMP r1, #1
|
||||||
|
BEQ rt_hw_context_switch_interrupt_do
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}
|
||||||
|
SUBS pc, lr, #4
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; /*
|
||||||
|
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch_interrupt_do PROC
|
||||||
|
EXPORT rt_hw_context_switch_interrupt_do
|
||||||
|
MOV r1, #0 ; clear flag
|
||||||
|
STR r1, [r0]
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}; reload saved registers
|
||||||
|
STMFD sp!, {r0-r3} ; save r0-r3
|
||||||
|
MOV r1, sp
|
||||||
|
ADD sp, sp, #16 ; restore sp
|
||||||
|
SUB r2, lr, #4 ; save old task's pc to r2
|
||||||
|
|
||||||
|
MRS r3, spsr ; get cpsr of interrupt thread
|
||||||
|
|
||||||
|
; switch to SVC mode and no interrupt
|
||||||
|
MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
|
||||||
|
|
||||||
|
STMFD sp!, {r2} ; push old task's pc
|
||||||
|
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
|
||||||
|
MOV r4, r1 ; Special optimised code below
|
||||||
|
MOV r5, r3
|
||||||
|
LDMFD r4!, {r0-r3}
|
||||||
|
STMFD sp!, {r0-r3} ; push old task's r3-r0
|
||||||
|
STMFD sp!, {r5} ; push old task's cpsr
|
||||||
|
MRS r4, spsr
|
||||||
|
STMFD sp!, {r4} ; push old task's spsr
|
||||||
|
|
||||||
|
LDR r4, =rt_interrupt_from_thread
|
||||||
|
LDR r5, [r4]
|
||||||
|
STR sp, [r5] ; store sp in preempted tasks's TCB
|
||||||
|
|
||||||
|
LDR r6, =rt_interrupt_to_thread
|
||||||
|
LDR r6, [r6]
|
||||||
|
LDR sp, [r6] ; get new task's stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task's spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task's psr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
; User Initial Stack & Heap
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
__user_initial_stackheap
|
||||||
|
|
||||||
|
LDR R0, = Heap_Mem
|
||||||
|
LDR R1, =(Stack_Mem + USR_Stack_Size)
|
||||||
|
LDR R2, = (Heap_Mem + Heap_Size)
|
||||||
|
LDR R3, = Stack_Mem
|
||||||
|
BX LR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
END
|
||||||
|
|
|
@ -26,34 +26,52 @@ struct clk {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk clk32k = {
|
static struct clk clk32k = {
|
||||||
.name = "clk32k",
|
"clk32k",
|
||||||
.rate_hz = AT91_SLOW_CLOCK,
|
AT91_SLOW_CLOCK,
|
||||||
|
RT_NULL,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk main_clk = {
|
static struct clk main_clk = {
|
||||||
.name = "main",
|
"main",
|
||||||
|
0,
|
||||||
|
RT_NULL,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk plla = {
|
static struct clk plla = {
|
||||||
.name = "plla",
|
"plla",
|
||||||
|
0,
|
||||||
|
RT_NULL,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk mck = {
|
static struct clk mck = {
|
||||||
.name = "mck",
|
"mck",
|
||||||
|
0,
|
||||||
|
RT_NULL,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk uhpck = {
|
static struct clk uhpck = {
|
||||||
.name = "uhpck",
|
"uhpck",
|
||||||
|
0,
|
||||||
|
RT_NULL,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk pllb = {
|
static struct clk pllb = {
|
||||||
.name = "pllb",
|
"pllb",
|
||||||
.parent = &main_clk,
|
0,
|
||||||
|
&main_clk,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk udpck = {
|
static struct clk udpck = {
|
||||||
.name = "udpck",
|
"udpck",
|
||||||
.parent = &pllb,
|
0,
|
||||||
|
&pllb,
|
||||||
|
{RT_NULL, RT_NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk *const standard_pmc_clocks[] = {
|
static struct clk *const standard_pmc_clocks[] = {
|
||||||
|
@ -75,7 +93,7 @@ struct clk *clk_get(const char *id)
|
||||||
for (list = (&clocks)->next; list != &clocks; list = list->next)
|
for (list = (&clocks)->next; list != &clocks; list = list->next)
|
||||||
{
|
{
|
||||||
clk = (struct clk *)rt_list_entry(list, struct clk, node);
|
clk = (struct clk *)rt_list_entry(list, struct clk, node);
|
||||||
if (strcmp(id, clk->name) == 0)
|
if (rt_strcmp(id, clk->name) == 0)
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue