diff --git a/bsp/mini4020/application.c b/bsp/mini4020/application.c new file mode 100644 index 000000000..15a2ef6e4 --- /dev/null +++ b/bsp/mini4020/application.c @@ -0,0 +1,127 @@ +/* + * File : application.c + * 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 + * 2007-11-20 Yi.Qiu add rtgui application + * 2008-6-28 Bernard no rtgui init + */ + +/** + * @addtogroup mini2440 + */ +/*@{*/ + +#include +#include + +#ifdef RT_USING_DFS +#include +#include +#include +#include +#endif +#ifdef RT_USING_RTGUI +#include +extern void radio_rtgui_init(void); +#endif +#define RT_INIT_THREAD_STACK_SIZE (2*1024) + +void rt_init_thread_entry(void* parameter) +{ + int fd; + rt_uint32_t sz; + char buffer[20]; +#ifdef RT_USING_DFS + dfs_init(); +#ifdef RT_USING_DFS_ELMFATFS + elm_init(); + /* mount sd card fat partition 1 as root directory */ + if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + rt_kprintf("File System initialized!\n"); + + /*Open a file*/ + fd = open("/fattest.txt", O_RDWR|O_CREAT, 0); + if (fd < 0) + { + rt_kprintf("open file for write failed\n"); + return; + } + + sz = write(fd,"Hello RT-Thread!",sizeof("Hello RT-Thread!")); + + if(sz!=0) + { + rt_kprintf("written %d\n",sz); + } + else + rt_kprintf("haven't written\n"); + + lseek(fd,0,SEEK_SET); + + sz = read(fd,buffer,sizeof(buffer)); + + if(sz!=0) + { + rt_kprintf("READ %d:",sz); + while(sz--) + rt_kprintf("%c",buffer[sz]);//opposite + rt_kprintf("\n"); + } + else + rt_kprintf("haven't read\n"); + + close(fd); + } + else + rt_kprintf("File System initialzation failed!\n"); +#endif +#endif +} + +void rt_led_thread_entry(void* parameter) +{ + /* + while (1) + { + count++; + *(RP)GPIO_PORTE_DATA |= 0x1<<4; + rt_thread_delay(RT_TICK_PER_SECOND*2); + + *(RP)GPIO_PORTE_DATA &= ~(0x1<<4); + rt_thread_delay(RT_TICK_PER_SECOND*2); + + } +*/ +} + + +int rt_application_init() +{ + rt_thread_t init_thread; + rt_thread_t led_thread; + + + init_thread = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + RT_INIT_THREAD_STACK_SIZE, 8, 20); + led_thread = rt_thread_create("led", + rt_led_thread_entry, RT_NULL, + 512, 200, 20); + + if (init_thread != RT_NULL) + rt_thread_startup(init_thread); + + if (led_thread != RT_NULL) + rt_thread_startup(led_thread); + return 0; +} + +/*@}*/ diff --git a/bsp/mini4020/board.c b/bsp/mini4020/board.c new file mode 100644 index 000000000..50fa2d311 --- /dev/null +++ b/bsp/mini4020/board.c @@ -0,0 +1,163 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-05-16 Bernard first implementation + * 2010-10-5 Wangmeng sep4020 implementation + */ +#include +#include + +#include +#include + +void rt_hw_serial_putc(const char c); + +#define UART0 ((struct uartport *)UART0_BASE) +struct rt_device uart0_device; +struct serial_int_rx uart0_int_rx; +struct serial_device uart0 = +{ + UART0, + &uart0_int_rx, + RT_NULL +}; + + +/** + * This function will handle rtos timer + */ +void rt_timer_handler(int vector) +{ + rt_uint32_t clear_int; + rt_tick_increase(); + + /*Clear timer interrupt*/ + clear_int = *(RP)TIMER_T1ISCR; + *(RP)TIMER_T1ISCR=clear_int; +} + +/** + * This function will handle serial + */ +void rt_serial_handler(int vector) +{ + //rt_kprintf("in rt_serial_handler\n"); + rt_int32_t stat = *(RP)UART0_IIR ; + UNUSED char c; + + /*Received data*/ + if(((stat & 0x0E) >> 1) == 0x02) + { + + rt_hw_serial_isr(&uart0_device); + + } + else + { + /*clear the timeout interrupt*/ + while (uart0.uart_device->lsr & USTAT_RCV_READY) + c = uart0.uart_device->dlbl_fifo.rxfifo; + } +} +/** + * This function will init led on the board + */ +static void rt_hw_board_led_init(void) +{ + /* PE3 PE4 PE5 for led */ + *(RP)GPIO_PORTE_SEL |=0x38; /* GPIO */ + + *(RP)GPIO_PORTE_DIR &= ~0x38; /* output*/ + + *(RP)GPIO_PORTE_DATA &= ~0x38; /* low */ +} +/** + * This function will init timer4 for system ticks + */ + void rt_hw_timer_init() + { + /*Set timer1*/ + *(RP)TIMER_T1LCR = 880000; + *(RP)TIMER_T1CR = 0x06; + + rt_hw_interrupt_install(INTSRC_TIMER1, rt_timer_handler, RT_NULL); + rt_hw_interrupt_umask(INTSRC_TIMER1); + + /*Enable timer1*/ + *(RP)TIMER_T1CR |= 0x01; + } + +/** + * This function will handle init uart + */ +void rt_hw_uart_init(void) +{ + const rt_int32_t sysclk = 72000000; + + /*Set data bit:8*/ + *(RP)(UART0_LCR) = 0x83; + /*Set baud rate high*/ + *(RP)(UART0_DLBH) = (sysclk/16/115200) >> 8; + /*Set baud rate low*/ + *(RP)(UART0_DLBL) = (sysclk/16/115200) & 0xff; + + *(RP)(UART0_LCR) = 0x83&(~(0x1 << 7)); + + /*Set trigger level*/ + *(RP)(UART0_FCR) = 0x0; + *(RP)(UART0_IER) = 0x0; + + /*Enable rx interrupt*/ + *(RP)(UART0_IER) |= 0x01; + /*Disable tx interrupt*/ + *(RP)(UART0_IER) &= ~(0x1<<1); + + rt_hw_interrupt_install(INTSRC_UART0, rt_serial_handler, RT_NULL); + rt_hw_interrupt_umask(INTSRC_UART0); + /* register uart0 */ + rt_hw_serial_register(&uart0_device, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + &uart0); +} + +void rt_hw_board_init() +{ + /* initialize uart */ + rt_hw_uart_init(); +// rt_hw_board_led_init(); + rt_hw_timer_init(); +} + +/* write one character to serial, must not trigger interrupt */ +void rt_hw_serial_putc(const char c) +{ + /* + to be polite with serial console add a line feed + to the carriage return character + */ + if (c=='\n')rt_hw_serial_putc('\r'); + + while (!((*(RP)UART0_LSR) & 0x40)); + *(RP)(UART0_BASE) = c; +} + +/** + * This function is used by rt_kprintf to display a string on console. + * + * @param str the displayed string + */ +void rt_hw_console_output(const char* str) +{ + while (*str) + { + rt_hw_serial_putc(*str++); + } +} diff --git a/bsp/mini4020/board.h b/bsp/mini4020/board.h new file mode 100644 index 000000000..2d0ac8a22 --- /dev/null +++ b/bsp/mini4020/board.h @@ -0,0 +1,24 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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 + * 2006-10-08 Bernard add board.h to this bsp + * 2010-10-5 Wangmeng sep4020 implemention + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +void rt_hw_board_init(void); +void rt_hw_sdcard_init(void); + +#endif diff --git a/bsp/mini4020/dm9161.c b/bsp/mini4020/dm9161.c new file mode 100644 index 000000000..e189f4b4c --- /dev/null +++ b/bsp/mini4020/dm9161.c @@ -0,0 +1,700 @@ +#include +#include + +#include "dm9161.h" +#include +#include "mii.h" + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +/* Duplex, half or full. */ +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 + +/* + * Davicom dm9161EP driver + * + * IRQ_LAN connects to EINT7(GPF7) + * nLAN_CS connects to nGCS4 + */ + +/* #define dm9161_DEBUG 1 */ +#if DM9161_DEBUG +#define DM9161_TRACE rt_kprintf +#else +#define DM9161_TRACE(...) +#endif + +/* + * dm9161 interrupt line is connected to PF7 + */ +//-------------------------------------------------------- + +#define DM9161_PHY 0x40 /* PHY address 0x01 */ + +#define MAX_ADDR_LEN 6 +enum DM9161_PHY_mode +{ + DM9161_10MHD = 0, DM9161_100MHD = 1, + DM9161_10MFD = 4, DM9161_100MFD = 5, + DM9161_AUTO = 8, DM9161_1M_HPNA = 0x10 +}; + +enum DM9161_TYPE +{ + TYPE_DM9161, +}; + +struct rt_dm9161_eth +{ + /* inherit from ethernet device */ + struct eth_device parent; + + enum DM9161_TYPE type; + enum DM9161_PHY_mode mode; + + rt_uint8_t imr_all; + rt_uint8_t phy_addr; + + rt_uint32_t tx_index; + + rt_uint8_t packet_cnt; /* packet I or II */ + rt_uint16_t queue_packet_len; /* queued packet (packet II) */ + + /* interface address info. */ + rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ +}; +static struct rt_dm9161_eth dm9161_device; +static struct rt_semaphore sem_ack, sem_lock; + +void rt_dm9161_isr(int irqno); + +static void udelay(unsigned long ns) +{ + unsigned long i; + while(ns--) + { + i = 100; + while(i--); + } +} + +static __inline unsigned long sep_emac_read(unsigned int reg) +{ + void __iomem *emac_base = (void __iomem *)reg; + return read_reg(emac_base); +} + +/* +* Write to a EMAC register. +*/ +static __inline void sep_emac_write(unsigned int reg, unsigned long value) +{ + void __iomem *emac_base = (void __iomem *)reg; + + write_reg(emac_base,value); +} + + +/* ........................... PHY INTERFACE ........................... */ +/* CAN DO MAC CONFIGRATION +* Enable the MDIO bit in MAC control register +* When not called from an interrupt-handler, access to the PHY must be +* protected by a spinlock. +*/ +static void enable_mdi(void) //need think more +{ + unsigned long ctl; + + ctl = sep_emac_read(MAC_CTRL); + sep_emac_write(MAC_CTRL, ctl&(~0x3)); /* enable management port */ + return; +} + +/* CANNOT DO MAC CONFIGRATION +* Disable the MDIO bit in the MAC control register +*/ +static void disable_mdi(void) +{ + unsigned long ctl; + + ctl = sep_emac_read(MAC_CTRL); + sep_emac_write(MAC_CTRL, ctl|(0x3)); /* disable management port */ + return; +} + +/* +* Wait until the PHY operation is complete. +*/ +static __inline void sep_phy_wait(void) +{ + unsigned long timeout = 2; + + while ((sep_emac_read(MAC_MII_STATUS) & 0x2)) + { + timeout--; + if (!timeout) + { + EOUT("sep_ether: MDIO timeout\n"); + break; + } + } + return; +} + +/* +* Write value to the a PHY register +* Note: MDI interface is assumed to already have been enabled. +*/ +static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value) +{ + unsigned short mii_txdata; + + mii_txdata = value; + sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr); + sep_emac_write(MAC_MII_TXDATA ,mii_txdata); + sep_emac_write(MAC_MII_CMD ,0x4); + udelay(40); + + sep_phy_wait(); + return; +} + +/* +* Read value stored in a PHY register. +* Note: MDI interface is assumed to already have been enabled. +*/ +static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value) +{ + unsigned short mii_rxdata; +// unsigned long mii_status; + + sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr); + sep_emac_write(MAC_MII_CMD ,0x2); + udelay(40); + sep_phy_wait(); + + mii_rxdata = sep_emac_read(MAC_MII_RXDATA); + *value = mii_rxdata; + return; +} + + + + +/* interrupt service routine */ +void rt_dm9161_isr(int irqno) +{ + unsigned long intstatus; + rt_uint32_t address; + + mask_irq(INTSRC_MAC); + intstatus = sep_emac_read(MAC_INTSRC); + + sep_emac_write(MAC_INTSRC,intstatus); + + /*Receive complete*/ + if(intstatus & 0x04) + { + eth_device_ready(&(dm9161_device.parent)); + } + /*Receive error*/ + else if(intstatus & 0x08) + { + rt_kprintf("Receive error\n"); + } + /*Transmit complete*/ + else if(intstatus & 0x03) + { + if(dm9161_device.tx_index == 0) + address = (MAC_TX_BD +(MAX_TX_DESCR-2)*8); + else if(dm9161_device.tx_index == 1) + address = (MAC_TX_BD +(MAX_TX_DESCR-1)*8); + else + address = (MAC_TX_BD + dm9161_device.tx_index*8-16); + //printk("free tx skb 0x%x in inter!!\n",lp->txBuffIndex); + sep_emac_write(address,0x0); + } + else if (intstatus & 0x10) + { + rt_kprintf("ROVER ERROR\n"); + + } + + while(intstatus) + { + sep_emac_write(MAC_INTSRC,intstatus); + intstatus = sep_emac_read(MAC_INTSRC); + } + + unmask_irq(INTSRC_MAC); + +} + +static rt_err_t update_mac_address() +{ + rt_uint32_t lo,hi; + hi = sep_emac_read(MAC_ADDR1); + lo = sep_emac_read(MAC_ADDR0); + DBOUT("Before MAC: hi=%x lo=%x\n",hi,lo); + + sep_emac_write(MAC_ADDR0,(dm9161_device.dev_addr[2] << 24) | (dm9161_device.dev_addr[3] << 16) | (dm9161_device.dev_addr[4] << 8) | (dm9161_device.dev_addr[5])); + sep_emac_write(MAC_ADDR1,dm9161_device.dev_addr[1]|(dm9161_device.dev_addr[0]<<8)); + + hi = sep_emac_read(MAC_ADDR1); + lo = sep_emac_read(MAC_ADDR0); + DBOUT("After MAC: hi=%x lo=%x\n",hi,lo); + + return RT_EOK; +} + +static int mii_link_ok (unsigned long phy_id) +{ + /* first, a dummy read, needed to latch some MII phys */ + + unsigned int value; + + read_phy(phy_id, MII_BMSR,&value); + if (value & BMSR_LSTATUS) + return 1; + return 0; +} + +static void update_link_speed(unsigned short phy_addr) +{ + unsigned int bmsr, bmcr, lpa, mac_cfg; + unsigned int speed, duplex; + + if(!mii_link_ok(phy_addr)) + { + EOUT("Link Down\n"); + //goto result; + } + + read_phy(phy_addr,MII_BMSR,&bmsr); + read_phy(phy_addr,MII_BMCR,&bmcr); + + if (bmcr & BMCR_ANENABLE) /* AutoNegotiation is enabled */ + { + if (!(bmsr & BMSR_ANEGCOMPLETE)) /* Do nothing - another interrupt generated when negotiation complete */ + goto result; + + read_phy(phy_addr, MII_LPA, &lpa); + + if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) + speed = SPEED_100; + else + speed = SPEED_10; + + if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) + duplex = DUPLEX_FULL; + else + duplex = DUPLEX_HALF; + } + else + { + speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; + duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; + } + + /* Update the MAC */ + mac_cfg = sep_emac_read(MAC_CTRL); + if (speed == SPEED_100) + { + mac_cfg |= 0x800; /* set speed 100 M */ + //bmcr &=(~0x2000); + //write_phy(lp->phy_address, MII_BMCR, bmcr); //将dm9161的速度设为10M + if (duplex == DUPLEX_FULL) /* 100 Full Duplex */ + mac_cfg |= 0x400; + else /* 100 Half Duplex */ + mac_cfg &= (~0x400); + } + else + { + mac_cfg &= (~0x800); /* set speed 10 M */ + + if (duplex == DUPLEX_FULL) /* 10 Full Duplex */ + mac_cfg |= 0x400; + else /* 10 Half Duplex */ + mac_cfg &= (~0x400); + } + + sep_emac_write(MAC_CTRL, mac_cfg); + rt_kprintf("Link now %i M-%s\n", speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); + +result: + mac_cfg = sep_emac_read(MAC_CTRL); + DBOUT("After mac_cfg=%d\n",mac_cfg); + return; +} + +static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag); +/* RT-Thread Device Interface */ +/* initialize the interface */ +static rt_err_t rt_dm9161_init(rt_device_t dev) +{ + unsigned int phyid1, phyid2; + int detected = -1; + unsigned long phy_id; + unsigned short phy_address = 0; + + while ((detected != 0) && (phy_address < 32)) + { + /* Read the PHY ID registers */ + enable_mdi(); + read_phy(phy_address, MII_PHYSID1, &phyid1); + read_phy(phy_address, MII_PHYSID2, &phyid2); + + disable_mdi(); + + phy_id = (phyid1 << 16) | (phyid2 & 0xfff0); + switch (phy_id) + { + case MII_DM9161_ID: /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */ + case MII_DM9161A_ID: /* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */ + case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */ + case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */ + case MII_DP83847_ID: /* National Semiconductor DP83847: */ + case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ + case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ + { + enable_mdi(); + #warning SHOULD SET MAC ADDR + //get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ + update_mac_address(); /* Program ethernet address into MAC */ + + //用哈希寄存器比较当前群播地址,全双工,添加CRC校验,短数据帧进行填充 + sep_emac_write(MAC_CTRL, 0xa413); + #warning SHOULD DETERMIN LINK SPEED + update_link_speed(phy_address); + dm9161_device.phy_addr = phy_address; + disable_mdi(); + break; + } + + } + + phy_address++; + } + + rt_dm9161_open(dev,0); + + return RT_EOK; +} + + + +/* ................................ MAC ................................ */ + +/* + * Initialize and start the Receiver and Transmit subsystems + */ +static void sepether_start() +{ + int i; + unsigned int tempaddr; + + sep_emac_write(MAC_TXBD_NUM,MAX_TX_DESCR); + + //初始化发送和接收描述符 + for (i = 0; i < MAX_TX_DESCR; i++) + { + tempaddr=(MAC_TX_BD+i*8); + sep_emac_write(tempaddr,0); + tempaddr=(MAC_TX_BD+i*8+4); + sep_emac_write(tempaddr,0); + } + for (i = 0; i < MAX_RX_DESCR; i++) + { + tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8); + sep_emac_write(tempaddr,0); + tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4); + sep_emac_write(tempaddr,0); + } + + for (i = 0; i < MAX_RX_DESCR; i++) + { + tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8); + sep_emac_write(tempaddr,0xc000); + tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4); + sep_emac_write(tempaddr,ESRAM_BASE+ MAX_TX_DESCR*0x600+i*0x600); + } + + /* Set the Wrap bit on the last descriptor */ + tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8-8); + sep_emac_write(tempaddr,0xe000); + + + for (i = 0; i < MAX_TX_DESCR; i++) + { + tempaddr=(MAC_TX_BD+i*8); + sep_emac_write(tempaddr,0x0); + tempaddr=(MAC_TX_BD+i*8+4); + sep_emac_write(tempaddr,ESRAM_BASE+i*0x600); + } + + return; +} + +static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag) +{ + unsigned int dsintr; + enable_mdi(); + mask_irq(28); + + sep_emac_write(MAC_INTMASK,0x0); //首先屏蔽中断 + + + sepether_start(); + + /* Enable PHY interrupt */ + *(volatile unsigned long*)GPIO_PORTA_DIR |= 0x0080 ; //1 stands for in + *(volatile unsigned long*)GPIO_PORTA_SEL |= 0x0080 ; //for common use + *(volatile unsigned long*)GPIO_PORTA_INCTL |= 0x0080; //中断输入方式 + *(volatile unsigned long*)GPIO_PORTA_INTRCTL |= (0x3UL<<14); //中断类型为低电平解发 + *(volatile unsigned long*)GPIO_PORTA_INTRCLR |= 0x0080; //清除中断 + *(volatile unsigned long*)GPIO_PORTA_INTRCLR = 0x0000; //清除中断 + + rt_hw_interrupt_install(INTSRC_MAC, rt_dm9161_isr, RT_NULL); + enable_irq(INTSRC_EXINT7); + + + read_phy(dm9161_device.phy_addr, MII_DSINTR_REG, &dsintr); + dsintr = dsintr & ~0xf00; /* clear bits 8..11 */ + write_phy(dm9161_device.phy_addr, MII_DSINTR_REG, dsintr); + + update_link_speed(dm9161_device.phy_addr); + + + /************************************************************************************/ + /* Enable MAC interrupts */ + sep_emac_write(MAC_INTMASK,0xff); //open中断 + sep_emac_write(MAC_INTSRC,0xff); //clear all mac irq + unmask_irq(28); + disable_mdi(); + + rt_kprintf("SEP4020 ethernet interface open!\n\r"); + return RT_EOK; +} + +static rt_err_t rt_dm9161_close(rt_device_t dev) +{ + rt_kprintf("SEP4020 ethernet interface close!\n\r"); + + /* Disable Receiver and Transmitter */ + disable_mdi(); + #warning disable ether; + +// INT_ENABLE(28); + /* Disable PHY interrupt */ +// disable_phyirq(dev); + + /* Disable MAC interrupts */ + sep_emac_write(MAC_INTMASK,0); //屏蔽中断 + + +// INT_DISABLE(28); + + return RT_EOK; +} + +static rt_size_t rt_dm9161_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t rt_dm9161_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t rt_dm9161_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + + return RT_EOK; +} + +/* ethernet device interface */ +/* transmit packet. */ +rt_err_t rt_dm9161_tx( rt_device_t dev, struct pbuf* p) +{ + rt_uint8_t i; + rt_uint32_t length = 0; + struct pbuf *q; + unsigned long address; + unsigned long tmp_tx_bd; + + /* lock DM9000 device */ +// rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + + /* disable dm9000a interrupt */ + #warning SHOULD DISABLE INTEERUPT? + + /*Search for available BD*/ + for(i = 0;ipayload,q->len); + length += q->len; + q = q->next; + } + + #warning SHOULD NOTICE IT'S LENGTH + + length = length << 16; + + if(i == MAX_TX_DESCR - 1) + length |= 0xb800; + else + length |= 0x9800; + + address = (MAC_TX_BD + i*8); + dm9161_device.tx_index = i; + sep_emac_write(address,length); + + //wait for tranfer complete + while(!(sep_emac_read(address)&0x8000)); + + /* unlock DM9000 device */ +// rt_sem_release(&sem_lock); + + /* wait ack */ +// rt_sem_take(&sem_ack, RT_WAITING_FOREVER); + + return RT_EOK; +} + +/* reception packet. */ +struct pbuf *rt_dm9161_rx(rt_device_t dev) +{ + unsigned int temp_rx_bd,address; + rt_uint32_t i = 0; + rt_uint32_t length; + unsigned char *p_recv; + struct pbuf* p = RT_NULL; + + /* lock DM9000 device */ + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + + while(1) + { + + address = MAC_TX_BD + (MAX_TX_DESCR + i) * 8; + temp_rx_bd = sep_emac_read(address); + + if(!(temp_rx_bd & 0x8000)) + { + length = temp_rx_bd; + length = length >> 16; + + p_recv = (unsigned char*)(ESRAM_BASE + (MAX_TX_DESCR + i) * 0x600); + p = pbuf_alloc(PBUF_LINK,length,PBUF_RAM); + if(p != RT_NULL) + { + struct pbuf* q; + rt_int32_t len; + + for(q = p;q != RT_NULL;q = q->next) + { + rt_memcpy((rt_uint8_t*)(q->payload),p_recv,q->len); + } + } + else + { + rt_kprintf("Droping %d packet \n",length); + } + + if(i == (MAX_RX_DESCR-1)) + { + sep_emac_write(address,0xe000); + i = 0; + } + else + { + sep_emac_write(address,0xc000); + i++; + } + } + else + break; + } + + rt_sem_release(&sem_lock); + + + return p; +} + + +void rt_hw_dm9161_init() +{ + rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO); + rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO); + + dm9161_device.type = TYPE_DM9161; + dm9161_device.mode = DM9161_AUTO; + dm9161_device.packet_cnt = 0; + dm9161_device.queue_packet_len = 0; + + /* + * SRAM Tx/Rx pointer automatically return to start address, + * Packet Transmitted, Packet Received + */ + #warning NOTICE: + //dm9161_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM; + + dm9161_device.dev_addr[0] = 0x01; + dm9161_device.dev_addr[1] = 0x60; + dm9161_device.dev_addr[2] = 0x6E; + dm9161_device.dev_addr[3] = 0x11; + dm9161_device.dev_addr[4] = 0x02; + dm9161_device.dev_addr[5] = 0x0F; + + dm9161_device.parent.parent.init = rt_dm9161_init; + dm9161_device.parent.parent.open = rt_dm9161_open; + dm9161_device.parent.parent.close = rt_dm9161_close; + dm9161_device.parent.parent.read = rt_dm9161_read; + dm9161_device.parent.parent.write = rt_dm9161_write; + dm9161_device.parent.parent.control = rt_dm9161_control; + dm9161_device.parent.parent.user_data = RT_NULL; + + dm9161_device.parent.eth_rx = rt_dm9161_rx; + dm9161_device.parent.eth_tx = rt_dm9161_tx; + + eth_device_init(&(dm9161_device.parent), "e0"); + + /* instal interrupt */ + #warning TODO + //rt_hw_interrupt_install(INTEINT4_7, rt_dm9161_isr, RT_NULL); + //rt_hw_interrupt_umask(INTEINT4_7); +} + +void dm9161a(void) +{ +} + +#ifdef RT_USING_FINSH +#include +FINSH_FUNCTION_EXPORT(dm9161a, dm9161a register dump); +#endif diff --git a/bsp/mini4020/dm9161.h b/bsp/mini4020/dm9161.h new file mode 100644 index 000000000..e8c2faa1a --- /dev/null +++ b/bsp/mini4020/dm9161.h @@ -0,0 +1,65 @@ +#ifndef __DM9000_H__ +#define __DM9000_H__ + +/*MACRO DEFINATIONS*/ + + + #define SEP4020_ID_EMAC ((unsigned int) 28) // Ethernet Mac + /* Davicom 9161 PHY */ + #define MII_DM9161_ID 0x0181b880 + #define MII_DM9161A_ID 0x0181b8a0 + + /* Davicom specific registers */ + #define MII_DSCR_REG 16 + #define MII_DSCSR_REG 17 + #define MII_DSINTR_REG 21 + + /* Intel LXT971A PHY */ + #define MII_LXT971A_ID 0x001378E0 + + /* Intel specific registers */ + #define MII_ISINTE_REG 18 + #define MII_ISINTS_REG 19 + #define MII_LEDCTRL_REG 20 + + /* Realtek RTL8201 PHY */ + #define MII_RTL8201_ID 0x00008200 + + /* Broadcom BCM5221 PHY */ + #define MII_BCM5221_ID 0x004061e0 + + /* Broadcom specific registers */ + #define MII_BCMINTR_REG 26 + + /* National Semiconductor DP83847 */ + #define MII_DP83847_ID 0x20005c30 + + /* Altima AC101L PHY */ + #define MII_AC101L_ID 0x00225520 + + /* Micrel KS8721 PHY */ + #define MII_KS8721_ID 0x00221610 + + /* ........................................................................ */ + + #define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */ + #define MAX_RX_DESCR 20 /* max number of receive buffers */ + + #define MAX_TBUFF_SZ 0x600 /* 1518 rounded up */ + #define MAX_TX_DESCR 20 /* max number of receive buffers */ + + #define EMAC_DESC_DONE 0x00000001 /* bit for if DMA is done */ + #define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */ + + #define EMAC_BROADCAST 0x80000000 /* broadcast address */ + #define EMAC_MULTICAST 0x40000000 /* multicast address */ + #define EMAC_UNICAST 0x20000000 /* unicast address */ + +#define DM9161_inb(r) (*(volatile rt_uint8_t *)r) +#define DM9161_outb(r, d) (*(volatile rt_uint8_t *)r = d) +#define DM9161_inw(r) (*(volatile rt_uint16_t *)r) +#define DM9161_outw(r, d) (*(volatile rt_uint16_t *)r = d) + +void rt_hw_dm9616_init(void); + +#endif diff --git a/bsp/mini4020/export.c b/bsp/mini4020/export.c new file mode 100644 index 000000000..a79e29917 --- /dev/null +++ b/bsp/mini4020/export.c @@ -0,0 +1,9 @@ +#include +#include + +void testkkkk(void) +{ + rt_kprintf("Hello wangmengmeng!\n"); + return; +} +FINSH_FUNCTION_EXPORT(testkkkk,a test); diff --git a/bsp/mini4020/mii.h b/bsp/mini4020/mii.h new file mode 100644 index 000000000..349b8db30 --- /dev/null +++ b/bsp/mini4020/mii.h @@ -0,0 +1,130 @@ + +#ifndef __MII_H__ +#define __MII_H__ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ +#define ADVERTISE_RESV 0x1000 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ +#define LPA_RESV 0x1000 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ +#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + +/* 1000BASE-T Control register */ +#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ + +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ +#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ +#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ + +#endif diff --git a/bsp/mini4020/mini4020.sct b/bsp/mini4020/mini4020.sct new file mode 100644 index 000000000..f491876a0 --- /dev/null +++ b/bsp/mini4020/mini4020.sct @@ -0,0 +1,25 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +; ************************************************************* +; *** Scatter-Loadig Description File generated by uVision ***n +; ************************************************************* + + +LR_ROM1 0x30000000 0x0FFD00 ; load region size_region + { + ER_ROM1 0x30000000 0x0FFD00 ; load address = execution address + { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_RAM1 0x30100000 0x100000 ; RW data + { + .ANY (+RW +ZI) + } + + +} + diff --git a/bsp/mini4020/rtconfig.h b/bsp/mini4020/rtconfig.h new file mode 100644 index 000000000..ce5a572f2 --- /dev/null +++ b/bsp/mini4020/rtconfig.h @@ -0,0 +1,200 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +/* RT_NAME_MAX*/ +#define RT_NAME_MAX 8 + +/* RT_ALIGN_SIZE*/ +#define RT_ALIGN_SIZE 4 + +/* PRIORITY_MAX */ +#define RT_THREAD_PRIORITY_MAX 256 + +/* Tick per Second */ +#define RT_TICK_PER_SECOND 100 + +/* SECTION: RT_DEBUG */ +/* Thread Debug */ +#define RT_DEBUG +/* #define RT_THREAD_DEBUG */ + +#define RT_USING_OVERFLOW_CHECK + +/* Using Hook */ +#define RT_USING_HOOK + +/* Using Software Timer */ +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 8 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_TICK_PER_SECOND 10 + +/* SECTION: IPC */ +/* Using Semaphore */ +#define RT_USING_SEMAPHORE + +/* Using Mutex */ +#define RT_USING_MUTEX + +/* Using Event */ +#define RT_USING_EVENT + +/* Using MailBox */ +#define RT_USING_MAILBOX + +/* Using Message Queue */ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +#define RT_USING_MEMPOOL + +/* Using Dynamic Heap Management */ +#define RT_USING_HEAP + +/* Using Small MM */ +/* #define RT_USING_SMALL_MEM */ + +/* Using SLAB Allocator */ +#define RT_USING_SLAB + +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE + +/* SECTION: Console options */ +/* the buffer size of console */ +#define RT_CONSOLEBUF_SIZE 128 + +/* SECTION: finsh, a C-Express shell */ +/* Using FinSH as Shell*/ +#define RT_USING_FINSH +#define FINSH_USING_SYMTAB +#define FINSH USING DESCRIPTION + +/* SECTION: a runtime libc library */ +/* a runtime libc library */ +/* #define RT_USING_NEWLIB */ + +/* SECTION: a mini libc */ + +/* SECTION: C++ support */ +/* Using C++ support */ +/* #define RT_USING_CPLUSPLUS */ + +/* SECTION: Device filesystem support */ +/* using DFS support */ +#define RT_USING_DFS +#define RT_USING_DFS_ELMFATFS +/* #define RT_USING_DFS_YAFFS2 */ + +/* #define DFS_USING_WORKDIR */ + +/* the max number of mounted filesystem */ +#define DFS_FILESYSTEMS_MAX 2 +/* the max number of opened files */ +#define DFS_FD_MAX 16 +/* the max number of cached sector */ +#define DFS_CACHE_MAX_NUM 4 + +/* SECTION: lwip, a lighwight TCP/IP protocol stack */ +/* Using lighweight TCP/IP protocol stack */ +//#define RT_USING_LWIP +#define RT_LWIP_DNS + +/* Trace LwIP protocol */ +/* #define RT_LWIP_DEBUG */ + +/* Enable ICMP protocol */ +#define RT_LWIP_ICMP + +/* Enable IGMP protocol */ +#define RT_LWIP_IGMP + +/* Enable UDP protocol */ +#define RT_LWIP_UDP + +/* Enable TCP protocol */ +#define RT_LWIP_TCP + +/* the number of simulatenously active TCP connections*/ +#define RT_LWIP_TCP_PCB_NUM 5 + +/* TCP sender buffer space */ +#define RT_LWIP_TCP_SND_BUF 1024*10 + +/* TCP receive window. */ +#define RT_LWIP_TCP_WND 1024 + +/* Enable SNMP protocol */ +/* #define RT_LWIP_SNMP */ + +/* Using DHCP */ +/* #define RT_LWIP_DHCP */ + +#define RT_LWIP_DNS + +/* ip address of target */ +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 1 +#define RT_LWIP_IPADDR3 30 + +/* gateway address of target */ +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 1 +#define RT_LWIP_GWADDR3 1 + +/* mask address of target */ +#define RT_LWIP_MSKADDR0 255 +#define RT_LWIP_MSKADDR1 255 +#define RT_LWIP_MSKADDR2 255 +#define RT_LWIP_MSKADDR3 0 + +/* the number of blocks for pbuf */ +#define RT_LWIP_PBUF_NUM 16 + +/* thread priority of tcpip thread */ +#define RT_LWIP_TCPTHREAD_PRIORITY 128 + +/* mail box size of tcpip thread to wait for */ +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 + +/* thread stack size of tcpip thread */ +#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 + +/* thread priority of ethnetif thread */ +#define RT_LWIP_ETHTHREAD_PRIORITY 144 + +/* mail box size of ethnetif thread to wait for */ +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 32 + +/* thread stack size of ethnetif thread */ +#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 + +/* SECTION: RTGUI support */ +/* using RTGUI support */ +#define RT_USING_RTGUI + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 16 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support 16 weight font */ +#define RTGUI_USING_FONT12 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use font file as Chinese font */ +/* #define RTGUI_USING_HZ_FILE */ +/* use Chinese bitmap font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +/* #define RTGUI_USING_SMALL_SIZE */ +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ + +#endif diff --git a/bsp/mini4020/sdcard.c b/bsp/mini4020/sdcard.c new file mode 100644 index 000000000..21aa5c675 --- /dev/null +++ b/bsp/mini4020/sdcard.c @@ -0,0 +1,790 @@ +/* + * File : sdcard.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 2007, RT-Thread Develop 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 + * 2007-12-02 Yi.Qiu the first version + * 2010-01-01 Bernard Modify for mini2440 + * 2010-10-13 Wangmeng Added sep4020 support + */ + +#include "sdcard.h" +#include + +volatile rt_int32_t RCA; + +#ifdef RT_USING_DFS + +/* RT-Thread Device Driver Interface */ +#include +#include + +/*GLOBAL SD DEVICE PONITER*/ +static struct sd_device *ptr_sddev; +static rt_uint8_t gsec_buf[SECTOR_SIZE]; + +#define USE_TIMEOUT + +/*This file is to power on/off the SEP4020 SDC*/ +/** + * This function will power on/off the SEP4020 SDC + * + * @param sd_ctl: 0/power on; 1/power off + * @return none + * + */ +static void sd_pwr(int sd_ctl) +{ + if (sd_ctl) + { + *(RP)GPIO_PORTA_SEL |= 0x0200; + *(RP)GPIO_PORTA_DIR &= (~0x0200); + *(RP)GPIO_PORTA_DATA |= 0x0200; + } + else + { + + *(RP)GPIO_PORTA_SEL |= 0x0200; + *(RP)GPIO_PORTA_DIR &= (~0x0200); + *(RP)GPIO_PORTA_DATA &= (~0x0200); + } +} + +/*a nop operation to delay*/ +static void delay (U32 j) +{ + U32 i; + + for (i=0;ibytes_per_sector = 512; + geometry->block_size = 0x200000; + //if (CardType == SDIO_HIGH_CAPACITY_SD_CARD) + // geometry->sector_count = (SDCardInfo.SD_csd.DeviceSize + 1) * 1024; + //else + geometry->sector_count = 0x200000;//SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize; + } + + return RT_EOK; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_uint32_t retry = 3; + rt_uint8_t status; + rt_uint32_t index; + + ///*take the semaphore + struct dfs_partition *part = (struct dfs_partition *)dev->user_data; + rt_sem_take(part->lock, RT_WAITING_FOREVER); + while(retry--) + { + if (((rt_uint32_t)buffer % 4 != 0) || + ((rt_uint32_t)buffer > 0x20080000)) + { + for(index = 0;index < size;index++) + { + status = sd_readblock((part->offset + pos) * SECTOR_SIZE,ptr_sddev->sec_buf); + if(status != RT_EOK) + break; + + rt_memcpy((rt_uint8_t *)buffer + (index * SECTOR_SIZE),ptr_sddev->sec_buf,SECTOR_SIZE); + } + } + else + { + for(index = 0;indexlock); + + if (status == RT_EOK) + return size; + + rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); + return 0; + +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + int i; + rt_uint8_t status; + + struct dfs_partition *part = (struct dfs_partition *)dev->user_data; + + if ( dev == RT_NULL ) + { + rt_set_errno(-DFS_STATUS_EINVAL); + return 0; + } + + rt_sem_take(part->lock, RT_WAITING_FOREVER); + + if (((rt_uint32_t)buffer % 4 != 0) || + ((rt_uint32_t)buffer > 0x20080000)) + { + rt_uint32_t index; + + for(index=0;indexsec_buf, ((rt_uint8_t*)buffer + index * SECTOR_SIZE), SECTOR_SIZE); + status = sd_writeblock((part->offset + index + pos)*SECTOR_SIZE,ptr_sddev->sec_buf); + } + } + else + { + + for(i=0;ioffset + i + pos)*SECTOR_SIZE, + (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE)); + if (status != RT_EOK) break; + } + } + + rt_sem_release(part->lock); + + if (status == RT_EOK) + return size; + + rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); + return 0; +} + + +rt_err_t rt_hw_sdcard_exit() +{ + if(ptr_sddev->device != RT_NULL) + rt_free(ptr_sddev->device); + if(ptr_sddev->part != RT_NULL) + rt_free(ptr_sddev->part); + if(ptr_sddev != RT_NULL) + rt_free(ptr_sddev); + + return RT_EOK; +} + +/** + * This function will init sd card + * + * @param void + */ +rt_err_t rt_hw_sdcard_init() +{ + /*For test*/ + rt_err_t err; + rt_int32_t i; + + char dname[4]; + char sname[8]; + + /*Initialize structure*/ + + ptr_sddev = (struct sd_device*)rt_malloc(sizeof(struct sd_device)); + if(ptr_sddev == RT_NULL) + { + EOUT("Failed to allocate sdcard device structure\n"); + return RT_ENOMEM; + } + + /*sdcard intialize*/ + err = sd_init(); + if(err != RT_EOK) + goto FAIL2; + + /*set sector buffer*/ + ptr_sddev->sec_buf = gsec_buf; + ptr_sddev->buf_size = SECTOR_SIZE; + ptr_sddev->sdc = (struct sd_c*)SD_BASE; + + //DBOUT("allocate partition sector buffer OK!"); + + err = sd_readblock(0,ptr_sddev->sec_buf); + if(err != RT_EOK) + { + EOUT("read first block error\n"); + goto FAIL2; + } + + /*sdcard driver initialize*/ + ptr_sddev->part = (struct dfs_partition*)rt_malloc(4 * sizeof(struct dfs_partition)); + if(ptr_sddev->part == RT_NULL) + { + EOUT("allocate partition failed\n"); + err = RT_ENOMEM; + goto FAIL2; + } + + /*alloc device buffer*/ + ptr_sddev->device = (struct rt_device*)rt_malloc(4 * sizeof(struct rt_device)); + if(ptr_sddev->device == RT_NULL) + { + EOUT("allocate device failed\n"); + err = RT_ENOMEM; + goto FAIL1; + } + + ptr_sddev->part_num = 0; + + err = sd_readblock(0,ptr_sddev->sec_buf); + + if(err != RT_EOK) + { + EOUT("Read block 0 to initialize ERROR\n"); + goto FAIL1; + } + + for(i=0; i<4; i++) + { + /* get the first partition */ + err = dfs_filesystem_get_partition(&(ptr_sddev->part[i]), ptr_sddev->sec_buf, i); + if (err == RT_EOK) + { + rt_snprintf(dname, 4, "sd%d", i); + rt_snprintf(sname, 8, "sem_sd%d", i); + ptr_sddev->part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register sdcard device */ + ptr_sddev->device[i].init = rt_sdcard_init; + ptr_sddev->device[i].open = rt_sdcard_open; + ptr_sddev->device[i].close = rt_sdcard_close; + ptr_sddev->device[i].read = rt_sdcard_read; + ptr_sddev->device[i].write = rt_sdcard_write; + ptr_sddev->device[i].control = rt_sdcard_control; + ptr_sddev->device[i].user_data= &ptr_sddev->part[i]; + + err = rt_device_register(&ptr_sddev->device[i], dname, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + + if(err == RT_EOK) + ptr_sddev->part_num++; + } + else + { + if(i == 0) + { + /* there is no partition table */ + ptr_sddev->part[0].offset = 0; + ptr_sddev->part[0].size = 0; + ptr_sddev->part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO); + + /* register sdcard device */ + ptr_sddev->device[0].init = rt_sdcard_init; + ptr_sddev->device[0].open = rt_sdcard_open; + ptr_sddev->device[0].close = rt_sdcard_close; + ptr_sddev->device[0].read = rt_sdcard_read; + ptr_sddev->device[0].write = rt_sdcard_write; + ptr_sddev->device[0].control = rt_sdcard_control; + ptr_sddev->device[0].user_data= &ptr_sddev->part[0]; + + err = rt_device_register(&ptr_sddev->device[0], "sd0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + + if(err == RT_EOK) + ptr_sddev->part_num++; + + break; + } + } + } + + if(ptr_sddev->part_num == 0) + goto FAIL0; + + return err; + + FAIL0: + rt_free(ptr_sddev->device); + ptr_sddev->device = RT_NULL; + + FAIL1: + rt_free(ptr_sddev->part); + ptr_sddev->part = RT_NULL; + + FAIL2: + rt_free(ptr_sddev); + ptr_sddev = RT_NULL; + + return err; + + +} + +#endif diff --git a/bsp/mini4020/sdcard.h b/bsp/mini4020/sdcard.h new file mode 100644 index 000000000..f4b1ba10a --- /dev/null +++ b/bsp/mini4020/sdcard.h @@ -0,0 +1,51 @@ + +#ifndef __SDCARD_H +#define __SDCARD_H + +#include + +#ifdef RT_USING_DFS + +#include + +#define INICLK 300000 +#define SDCLK 24000000 //PCLK=49.392MHz +#define MMCCLK 15000000 //PCLK=49.392MHz + +/*struct of the SDC*/ +struct sd_c +{ + __IO rt_uint32_t clk_ctl; + __IO rt_uint32_t soft_rst; + __IO rt_uint32_t arg; + __IO rt_uint32_t cmd; + __IO rt_uint32_t blk_sz; + __IO rt_uint32_t blk_cnt; + __IO rt_uint32_t trans_mode; + __O rt_uint32_t response0; + __O rt_uint32_t response1; + __O rt_uint32_t response2; + __O rt_uint32_t response3; + __IO rt_uint32_t rd_to_ctl; + __IO rt_uint32_t int_stat; + __IO rt_uint32_t int_stat_mask; + __O rt_uint32_t rx_fifo; + __I rt_uint32_t tx_fifo; +}; + +/*sdcard driver structure*/ +struct sd_device +{ + struct rt_device *device; /*rt_device*/ + struct sd_c *sdc; /*SDCARD register*/ + struct dfs_partition *part; /*dfs partitions*/ + rt_uint8_t *sec_buf; /*sdcard buffer*/ + rt_uint32_t part_num; /*partiont numbers*/ + rt_uint32_t buf_size; /*buffer size*/ +}; + + + +#endif +#endif + diff --git a/bsp/mini4020/sep4020.h b/bsp/mini4020/sep4020.h new file mode 100644 index 000000000..b4590c2ef --- /dev/null +++ b/bsp/mini4020/sep4020.h @@ -0,0 +1,867 @@ +#ifndef __SEP4020_H +#define __SEP4020_H + +#include + +/*Core definations*/ +#define SVCMODE +#define Mode_USR 0x10 +#define Mode_FIQ 0x11 +#define Mode_IRQ 0x12 +#define Mode_SVC 0x13 +#define Mode_ABT 0x17 +#define Mode_UND 0x1B +#define Mode_SYS 0x1F + + + +/* + * 各模块寄存器基值 + */ + +#define ESRAM_BASE 0x04000000 +#define INTC_BASE 0x10000000 +#define PMU_BASE 0x10001000 +#define RTC_BASE 0x10002000 +#define WD_BASE 0x10002000 +#define TIMER_BASE 0x10003000 +#define PWM_BASE 0x10004000 +#define UART0_BASE 0X10005000 +#define UART1_BASE 0X10006000 +#define UART2_BASE 0X10007000 +#define UART3_BASE 0X10008000 +#define SSI_BASE 0X10009000 +#define I2S_BASE 0x1000A000 +#define MMC_BASE 0x1000B000 +#define SD_BASE 0x1000B000 +#define SMC0_BASE 0x1000C000 +#define SMC1_BASE 0x1000D000 +#define USBD_BASE 0x1000E000 +#define GPIO_BASE 0x1000F000 +#define EMI_BASE 0x11000000 +#define DMAC_BASE 0x11001000 +#define LCDC_BASE 0x11002000 +#define MAC_BASE 0x11003000 +#define AMBA_BASE 0x11005000 + + +/* + * INTC模块 + * 基址: 0x10000000 + */ + +#define INTC_IER (INTC_BASE+0X000) /* IRQ中断允许寄存器 */ +#define INTC_IMR (INTC_BASE+0X008) /* IRQ中断屏蔽寄存器 */ +#define INTC_IFR (INTC_BASE+0X010) /* IRQ软件强制中断寄存器 */ +#define INTC_IRSR (INTC_BASE+0X018) /* IRQ未处理中断状态寄存器 */ +#define INTC_ISR (INTC_BASE+0X020) /* IRQ中断状态寄存器 */ +#define INTC_IMSR (INTC_BASE+0X028) /* IRQ屏蔽中断状态寄存器 */ +#define INTC_IFSR (INTC_BASE+0X030) /* IRQ中断最终状态寄存器 */ +#define INTC_FIER (INTC_BASE+0X0C0) /* FIQ中断允许寄存器 */ +#define INTC_FIMR (INTC_BASE+0X0C4) /* FIQ中断屏蔽寄存器 */ +#define INTC_FIFR (INTC_BASE+0X0C8) /* FIQ软件强制中断寄存器 */ +#define INTC_FIRSR (INTC_BASE+0X0CC) /* FIQ未处理中断状态寄存器 */ +#define INTC_FISR (INTC_BASE+0X0D0) /* FIQ中断状态寄存器 */ +#define INTC_FIFSR (INTC_BASE+0X0D4) /* FIQ中断最终状态寄存器 */ +#define INTC_IPLR (INTC_BASE+0X0D8) /* IRQ中断优先级寄存器 */ +#define INTC_ICR1 (INTC_BASE+0X0DC) /* IRQ内部中断优先级控制寄存器1 */ +#define INTC_ICR2 (INTC_BASE+0X0E0) /* IRQ内部中断优先级控制寄存器2 */ +#define INTC_EXICR1 (INTC_BASE+0X0E4) /* IRQ外部中断优先级控制寄存器1 */ +#define INTC_EXICR2 (INTC_BASE+0X0E8) /* IRQ外部中断优先级控制寄存器2 */ + + +/* + * PMU模块 + * 基址: 0x10001000 + */ + +#define PMU_PLTR (PMU_BASE+0X000) /* PLL的稳定过渡时间 */ +#define PMU_PMCR (PMU_BASE+0X004) /* 系统主时钟PLL的控制寄存器 */ +#define PMU_PUCR (PMU_BASE+0X008) /* USB时钟PLL的控制寄存器 */ +#define PMU_PCSR (PMU_BASE+0X00C) /* 内部模块时钟源供给的控制寄存器 */ +#define PMU_PDSLOW (PMU_BASE+0X010) /* SLOW状态下时钟的分频因子 */ +#define PMU_PMDR (PMU_BASE+0X014) /* 芯片工作模式寄存器 */ +#define PMU_RCTR (PMU_BASE+0X018) /* Reset控制寄存器 */ +#define PMU_CLRWAKUP (PMU_BASE+0X01C) /* WakeUp清除寄存器 */ + + +/* + * RTC模块 + * 基址: 0x10002000 + */ + +#define RTC_STA_YMD (RTC_BASE+0X000) /* 年, 月, 日计数寄存器 */ +#define RTC_STA_HMS (RTC_BASE+0X004) /* 小时, 分钟, 秒寄存器 */ +#define RTC_ALARM_ALL (RTC_BASE+0X008) /* 定时月, 日, 时, 分寄存器 */ +#define RTC_CTR (RTC_BASE+0X00C) /* 控制寄存器 */ +#define RTC_INT_EN (RTC_BASE+0X010) /* 中断使能寄存器 */ +#define RTC_INT_STS (RTC_BASE+0X014) /* 中断状态寄存器 */ +#define RTC_SAMP (RTC_BASE+0X018) /* 采样周期寄存器 */ +#define RTC_WD_CNT (RTC_BASE+0X01C) /* Watch-Dog计数值寄存器 */ +#define RTC_WD_SEV (RTC_BASE+0X020) /* Watch-Dog服务寄存器 */ +#define RTC_CONFIG_CHECK (RTC_BASE+0X024) /* 配置时间确认寄存器 (在配置时间之前先写0xaaaaaaaa) */ +#define RTC_KEY0 (RTC_BASE+0X02C) /* 密钥寄存器 */ + +/* + * TIMER模块 + * 基址: 0x10003000 + */ + +#define TIMER_T1LCR (TIMER_BASE+0X000) /* 通道1加载计数寄存器 */ +#define TIMER_T1CCR (TIMER_BASE+0X004) /* 通道1当前计数值寄存器 */ +#define TIMER_T1CR (TIMER_BASE+0X008) /* 通道1控制寄存器 */ +#define TIMER_T1ISCR (TIMER_BASE+0X00C) /* 通道1中断状态清除寄存器 */ +#define TIMER_T1IMSR (TIMER_BASE+0X010) /* 通道1中断屏蔽状态寄存器 */ +#define TIMER_T2LCR (TIMER_BASE+0X020) /* 通道2加载计数寄存器 */ +#define TIMER_T2CCR (TIMER_BASE+0X024) /* 通道2当前计数值寄存器 */ +#define TIMER_T2CR (TIMER_BASE+0X028) /* 通道2控制寄存器 */ +#define TIMER_T2ISCR (TIMER_BASE+0X02C) /* 通道2中断状态清除寄存器 */ +#define TIMER_T2IMSR (TIMER_BASE+0X030) /* 通道2中断屏蔽状态寄存器 */ +#define TIMER_T3LCR (TIMER_BASE+0X040) /* 通道3加载计数寄存器 */ +#define TIMER_T3CCR (TIMER_BASE+0X044) /* 通道3当前计数值寄存器 */ +#define TIMER_T3CR (TIMER_BASE+0X048) /* 通道3控制寄存器 */ +#define TIMER_T3ISCR (TIMER_BASE+0X04C) /* 通道3中断状态清除寄存器 */ +#define TIMER_T3IMSR (TIMER_BASE+0X050) /* 通道3中断屏蔽状态寄存器 */ +#define TIMER_T3CAPR (TIMER_BASE+0X054) /* 通道3捕获寄存器 */ +#define TIMER_T4LCR (TIMER_BASE+0X060) /* 通道4加载计数寄存器 */ +#define TIMER_T4CCR (TIMER_BASE+0X064) /* 通道4当前计数值寄存器 */ +#define TIMER_T4CR (TIMER_BASE+0X068) /* 通道4控制寄存器 */ +#define TIMER_T4ISCR (TIMER_BASE+0X06C) /* 通道4中断状态清除寄存器 */ +#define TIMER_T4IMSR (TIMER_BASE+0X070) /* 通道4中断屏蔽状态寄存器 */ +#define TIMER_T4CAPR (TIMER_BASE+0X074) /* 通道4捕获寄存器 */ +#define TIMER_T5LCR (TIMER_BASE+0X080) /* 通道5加载计数寄存器 */ +#define TIMER_T5CCR (TIMER_BASE+0X084) /* 通道5当前计数值寄存器 */ +#define TIMER_T5CR (TIMER_BASE+0X088) /* 通道5控制寄存器 */ +#define TIMER_T5ISCR (TIMER_BASE+0X08C) /* 通道5中断状态清除寄存器 */ +#define TIMER_T5IMSR (TIMER_BASE+0X090) /* 通道5中断屏蔽状态寄存器 */ +#define TIMER_T5CAPR (TIMER_BASE+0X094) /* 通道5捕获寄存器 */ +#define TIMER_T6LCR (TIMER_BASE+0X0A0) /* 通道6加载计数寄存器 */ +#define TIMER_T6CCR (TIMER_BASE+0X0A4) /* 通道6当前计数值寄存器 */ +#define TIMER_T6CR (TIMER_BASE+0X0A8) /* 通道6控制寄存器 */ +#define TIMER_T6ISCR (TIMER_BASE+0X0AC) /* 通道6中断状态清除寄存器 */ +#define TIMER_T6IMSR (TIMER_BASE+0X0B0) /* 通道6中断屏蔽状态寄存器 */ +#define TIMER_T6CAPR (TIMER_BASE+0X0B4) /* 通道6捕获寄存器 */ +#define TIMER_T7LCR (TIMER_BASE+0X0C0) /* 通道7加载计数寄存器 */ +#define TIMER_T7CCR (TIMER_BASE+0X0C4) /* 通道7当前计数值寄存器 */ +#define TIMER_T7CR (TIMER_BASE+0X0C8) /* 通道7控制寄存器 */ +#define TIMER_T7ISCR (TIMER_BASE+0X0CC) /* 通道7中断状态清除寄存器 */ +#define TIMER_T7IMSR (TIMER_BASE+0X0D0) /* 通道7中断屏蔽状态寄存器 */ +#define TIMER_T8LCR (TIMER_BASE+0X0E0) /* 通道8加载计数寄存器 */ +#define TIMER_T8CCR (TIMER_BASE+0X0E4) /* 通道8当前计数值寄存器 */ +#define TIMER_T8CR (TIMER_BASE+0X0E8) /* 通道8控制寄存器 */ +#define TIMER_T8ISCR (TIMER_BASE+0X0EC) /* 通道8中断状态清除寄存器 */ +#define TIMER_T8IMSR (TIMER_BASE+0X0F0) /* 通道8中断屏蔽状态寄存器 */ +#define TIMER_T9LCR (TIMER_BASE+0X100) /* 通道9加载计数寄存器 */ +#define TIMER_T9CCR (TIMER_BASE+0X104) /* 通道9当前计数值寄存器 */ +#define TIMER_T9CR (TIMER_BASE+0X108) /* 通道9控制寄存器 */ +#define TIMER_T9ISCR (TIMER_BASE+0X10C) /* 通道9中断状态清除寄存器 */ +#define TIMER_T9IMSR (TIMER_BASE+0X110) /* 通道9中断屏蔽状态寄存器 */ +#define TIMER_T10LCR (TIMER_BASE+0X120) /* 通道10加载计数寄存器 */ +#define TIMER_T10CCR (TIMER_BASE+0X124) /* 通道10当前计数值寄存器 */ +#define TIMER_T10CR (TIMER_BASE+0X128) /* 通道10控制寄存器 */ +#define TIMER_T10ISCR (TIMER_BASE+0X12C) /* 通道10中断状态清除寄存器 */ +#define TIMER_T10IMSR (TIMER_BASE+0X130) /* 通道10中断屏蔽状态寄存器 */ +#define TIMER_TIMSR (TIMER_BASE+0X140) /* TIMER中断屏蔽状态寄存器 */ +#define TIMER_TISCR (TIMER_BASE+0X144) /* TIMER中断状态清除寄存器 */ +#define TIMER_TISR (TIMER_BASE+0X148) /* TIMER中断状态寄存器 */ + + + +/* + * PWM模块 + * 基址: 0x10004000 + */ + +#define PWM0_CTRL (PWM_BASE+0X000) /* PWM0控制寄存器 */ +#define PWM0_DIV (PWM_BASE+0X004) /* PWM0分频寄存器 */ +#define PWM0_PERIOD (PWM_BASE+0X008) /* PWM0周期寄存器 */ +#define PWM0_DATA (PWM_BASE+0X00C) /* PWM0数据寄存器 */ +#define PWM0_CNT (PWM_BASE+0X010) /* PWM0计数寄存器 */ +#define PWM0_STATUS (PWM_BASE+0X014) /* PWM0状态寄存器 */ +#define PWM1_CTRL (PWM_BASE+0X020) /* PWM1控制寄存器 */ +#define PWM1_DIV (PWM_BASE+0X024) /* PWM1分频寄存器 */ +#define PWM1_PERIOD (PWM_BASE+0X028) /* PWM1周期寄存器 */ +#define PWM1_DATA (PWM_BASE+0X02C) /* PWM1数据寄存器 */ +#define PWM1_CNT (PWM_BASE+0X030) /* PWM1计数寄存器 */ +#define PWM1_STATUS (PWM_BASE+0X034) /* PWM1状态寄存器 */ +#define PWM2_CTRL (PWM_BASE+0X040) /* PWM2控制寄存器 */ +#define PWM2_DIV (PWM_BASE+0X044) /* PWM2分频寄存器 */ +#define PWM2_PERIOD (PWM_BASE+0X048) /* PWM2周期寄存器 */ +#define PWM2_DATA (PWM_BASE+0X04C) /* PWM2数据寄存器 */ +#define PWM2_CNT (PWM_BASE+0X050) /* PWM2计数寄存器 */ +#define PWM2_STATUS (PWM_BASE+0X054) /* PWM2状态寄存器 */ +#define PWM3_CTRL (PWM_BASE+0X060) /* PWM3控制寄存器 */ +#define PWM3_DIV (PWM_BASE+0X064) /* PWM3分频寄存器 */ +#define PWM3_PERIOD (PWM_BASE+0X068) /* PWM3周期寄存器 */ +#define PWM3_DATA (PWM_BASE+0X06C) /* PWM3数据寄存器 */ +#define PWM3_CNT (PWM_BASE+0X070) /* PWM3计数寄存器 */ +#define PWM3_STATUS (PWM_BASE+0X074) /* PWM3状态寄存器 */ +#define PWM_INTMASK (PWM_BASE+0X080) /* PWM中断屏蔽寄存器 */ +#define PWM_INT (PWM_BASE+0X084) /* PWM中断寄存器 */ +#define PWM_ENABLE (PWM_BASE+0X088) /* PWM使能寄存器 */ + + +/* + * UART0模块 + * 基址: 0x10005000 + */ + +#define UART0_DLBL (UART0_BASE+0X000) /* 波特率设置低八位寄存器 */ +#define UART0_RXFIFO (UART0_BASE+0X000) /* 接收FIFO */ +#define UART0_TXFIFO (UART0_BASE+0X000) /* 发送FIFO */ +#define UART0_DLBH (UART0_BASE+0X004) /* 波特率设置高八位寄存器 */ +#define UART0_IER (UART0_BASE+0X004) /* 中断使能寄存器 */ +#define UART0_IIR (UART0_BASE+0X008) /* 中断识别寄存器 */ +#define UART0_FCR (UART0_BASE+0X008) /* FIFO控制寄存器 */ +#define UART0_LCR (UART0_BASE+0X00C) /* 行控制寄存器 */ +#define UART0_MCR (UART0_BASE+0X010) /* Modem控制寄存器 */ +#define UART0_LSR (UART0_BASE+0X014) /* 行状态寄存器 */ +#define UART0_MSR (UART0_BASE+0X018) /* Modem状态寄存器 */ + + +/* + * UART1模块 + * 基址: 0x10006000 + */ + +#define UART1_DLBL (UART1_BASE+0X000) /* 波特率设置低八位寄存器 */ +#define UART1_RXFIFO (UART1_BASE+0X000) /* 接收FIFO */ +#define UART1_TXFIFO (UART1_BASE+0X000) /* 发送FIFO */ +#define UART1_DLBH (UART1_BASE+0X004) /* 波特率设置高八位寄存器 */ +#define UART1_IER (UART1_BASE+0X004) /* 中断使能寄存器 */ +#define UART1_IIR (UART1_BASE+0X008) /* 中断识别寄存器 */ +#define UART1_FCR (UART1_BASE+0X008) /* FIFO控制寄存器 */ +#define UART1_LCR (UART1_BASE+0X00C) /* 行控制寄存器 */ +#define UART1_MCR (UART1_BASE+0X010) /* Modem控制寄存器 */ +#define UART1_LSR (UART1_BASE+0X014) /* 行状态寄存器 */ +#define UART1_MSR (UART1_BASE+0X018) /* Modem状态寄存器 */ + + +/* + * UART2模块 + * 基址: 0x10007000 + */ + +#define UART2_DLBL (UART2_BASE+0X000) /* 波特率设置低八位寄存器 */ +#define UART2_RXFIFO (UART2_BASE+0X000) /* 接收FIFO */ +#define UART2_TXFIFO (UART2_BASE+0X000) /* 发送FIFO */ +#define UART2_DLBH (UART2_BASE+0X004) /* 波特率设置高八位寄存器 */ +#define UART2_IER (UART2_BASE+0X004) /* 中断使能寄存器 */ +#define UART2_IIR (UART2_BASE+0X008) /* 中断识别寄存器 */ +#define UART2_FCR (UART2_BASE+0X008) /* FIFO控制寄存器 */ +#define UART2_LCR (UART2_BASE+0X00C) /* 行控制寄存器 */ +#define UART2_MCR (UART2_BASE+0X010) /* Modem控制寄存器 */ +#define UART2_LSR (UART2_BASE+0X014) /* 行状态寄存器 */ +#define UART2_MSR (UART2_BASE+0X018) /* Modem状态寄存器 */ + + +/* + * UART3模块 + * 基址: 0x10008000 + */ + +#define UART3_DLBL (UART3_BASE+0X000) /* 波特率设置低八位寄存器 */ +#define UART3_RXFIFO (UART3_BASE+0X000) /* 接收FIFO */ +#define UART3_TXFIFO (UART3_BASE+0X000) /* 发送FIFO */ +#define UART3_DLBH (UART3_BASE+0X004) /* 波特率设置高八位寄存器 */ +#define UART3_IER (UART3_BASE+0X004) /* 中断使能寄存器 */ +#define UART3_IIR (UART3_BASE+0X008) /* 中断识别寄存器 */ +#define UART3_FCR (UART3_BASE+0X008) /* FIFO控制寄存器 */ +#define UART3_LCR (UART3_BASE+0X00C) /* 行控制寄存器 */ +#define UART3_MCR (UART3_BASE+0X010) /* Modem控制寄存器 */ +#define UART3_LSR (UART3_BASE+0X014) /* 行状态寄存器 */ +#define UART3_MSR (UART3_BASE+0X018) /* Modem状态寄存器 */ + + +/* + * SSI模块 + * 基址: 0x10009000 + */ + +#define SSI_CONTROL0 (SSI_BASE+0X000) /* 控制寄存器0 */ +#define SSI_CONTROL1 (SSI_BASE+0X004) /* 控制寄存器1 */ +#define SSI_SSIENR (SSI_BASE+0X008) /* SSI使能寄存器 */ +#define SSI_MWCR (SSI_BASE+0X00C) /* Microwire控制寄存器 */ +#define SSI_SER (SSI_BASE+0X010) /* 从设备使能寄存器 */ +#define SSI_BAUDR (SSI_BASE+0X014) /* 波特率设置寄存器 */ +#define SSI_TXFTLR (SSI_BASE+0X018) /* 发送FIFO阈值寄存器 */ +#define SSI_RXFTLR (SSI_BASE+0X01C) /* 接收FIFO阈值寄存器 */ +#define SSI_TXFLR (SSI_BASE+0X020) /* 发送FIFO状态寄存器 */ +#define SSI_RXFLR (SSI_BASE+0X024) /* 接收FIFO状态寄存器 */ +#define SSI_SR (SSI_BASE+0X028) /* 状态寄存器 */ +#define SSI_IMR (SSI_BASE+0X02C) /* 中断屏蔽寄存器 */ +#define SSI_ISR (SSI_BASE+0X030) /* 中断最终状态寄存器 */ +#define SSI_RISR (SSI_BASE+0X034) /* 中断原始状态寄存器 */ +#define SSI_TXOICR (SSI_BASE+0X038) /* 发送FIFO上溢中断清除寄存器 */ +#define SSI_RXOICR (SSI_BASE+0X03C) /* 接收FIFO上溢中断清除寄存器 */ +#define SSI_RXUICR (SSI_BASE+0X040) /* 接收FIFO下溢中断清除寄存器 */ +#define SSI_ICR (SSI_BASE+0X02C) /* 中断清除寄存器 */ +#define SSI_DMACR (SSI_BASE+0X04C) /* DMA控制寄存器 */ +#define SSI_DMATDLR (SSI_BASE+0X050) /* DMA发送状态寄存器 */ +#define SSI_DMARDLR (SSI_BASE+0X054) /* DMA接收状态寄存器 */ +#define SSI_DR (SSI_BASE+0X060) /* 数据寄存器 */ + + +/* + * I2S模块 + * 基址: 0x1000A000 + */ + +#define I2S_CTRL (I2S_BASE+0X000) /* I2S控制寄存器 */ +#define I2S_DATA (I2S_BASE+0X004) /* I2S数据寄存器 */ +#define I2S_INT (I2S_BASE+0X008) /* I2S中断寄存器 */ +#define I2S_STATUS (I2S_BASE+0X00C) /* I2S状态寄存器 */ + + +/* + * SD模块 + * 基址: 0x1000B000 + */ + +#define SDC_CLOCK_CONTROL (SD_BASE+0x00) /* SDIO时钟控制寄存器 */ +#define SDC_SOFTWARE_RESET (SD_BASE+0X04) /* SDIO软件复位寄存器 */ +#define SDC_ARGUMENT (SD_BASE+0X08) /* SDIO命令参数寄存器 */ +#define SDC_COMMAND (SD_BASE+0X0C) /* SDIO命令控制寄存器 */ +#define SDC_BLOCK_SIZE (SD_BASE+0X10) /* SDIO数据块长度寄存器 */ +#define SDC_BLOCK_COUNT (SD_BASE+0X14) /* SDIO数据块数目寄存器 */ +#define SDC_TRANSFER_MODE (SD_BASE+0X18) /* SDIO传输模式选择寄存器 */ +#define SDC_RESPONSE0 (SD_BASE+0X1c) /* SDIO响应寄存器0 */ +#define SDC_RESPONSE1 (SD_BASE+0X20) /* SDIO响应寄存器1 */ +#define SDC_RESPONSE2 (SD_BASE+0X24) /* SDIO响应寄存器2 */ +#define SDC_RESPONSE3 (SD_BASE+0X28) /* SDIO响应寄存器3 */ +#define SDC_READ_TIMEOUT_CONTROL (SD_BASE+0X2c) /* SDIO读超时控制寄存器 */ +#define SDC_INTERRUPT_STATUS (SD_BASE+0X30) /* SDIO中断状态寄存器 */ +#define SDC_INTERRUPT_STATUS_MASK (SD_BASE+0X34) /* SDIO中断状态屏蔽寄存器 */ +#define SDC_READ_BUFER_ACCESS (SD_BASE+0X38) /* SDIO接收FIFO */ +#define SDC_WRITE_BUFER_ACCESS (SD_BASE+0X3c) /* SDIO发送FIFO */ + + + +/* + * SMC0模块 + * 基址: 0x1000C000 + */ + +#define SMC0_CTRL (SMC0_BASE+0X000) /* SMC0控制寄存器 */ +#define SMC0_INT (SMC0_BASE+0X004) /* SMC0中断寄存器 */ +#define SMC0_FD (SMC0_BASE+0X008) /* SMC0基本单元时间寄存器 */ +#define SMC0_CT (SMC0_BASE+0X00C) /* SMC0字符传输时间寄存器 */ +#define SMC0_BT (SMC0_BASE+0X010) /* SMC0块传输时间寄存器 */ + + + +/* + * SMC1模块 + * 基址: 0x1000D000 + */ + +#define SMC1_CTRL (SMC1_BASE+0X000) /* SMC1控制寄存器 */ +#define SMC1_INT (SMC1_BASE+0X004) /* SMC1中断寄存器 */ +#define SMC1_FD (SMC1_BASE+0X008) /* SMC1基本单元时间寄存器 */ +#define SMC1_CT (SMC1_BASE+0X00C) /* SMC1字符传输时间寄存器 */ +#define SMC1_BT (SMC1_BASE+0X010) /* SMC1块传输时间寄存器 */ + + + +/* + * USBD模块 + * 基址: 0x1000E000 + */ + +#define USBD_PROTOCOLINTR (USBD_BASE+0X000) /* USB协议中断寄存器 */ +#define USBD_INTRMASK (USBD_BASE+0X004) /* USB中断屏蔽寄存器 */ +#define USBD_INTRCTRL (USBD_BASE+0X008) /* USB中断类型控制寄存器 */ +#define USBD_EPINFO (USBD_BASE+0X00C) /* USB活动端点状态寄存器 */ +#define USBD_BCONFIGURATIONVALUE (USBD_BASE+0X010) /* SET_CCONFIGURATION记录 */ +#define USBD_BMATTRIBUTES (USBD_BASE+0X014) /* 当前配置属性寄存器 */ +#define USBD_DEVSPEED (USBD_BASE+0X018) /* 当前设备工作速度寄存器 */ +#define USBD_FRAMENUMBER (USBD_BASE+0X01C) /* 记录当前SOF包内的帧号 */ +#define USBD_EPTRANSACTIONS0 (USBD_BASE+0X020) /* 记录下次要求的传输次数 */ +#define USBD_EPTRANSACTIONS1 (USBD_BASE+0X024) /* 记录下次要求的传输次数 */ +#define USBD_APPIFUPDATE (USBD_BASE+0X028) /* 接口号快速更新寄存器 */ +#define USBD_CFGINTERFACE0 (USBD_BASE+0X02C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE1 (USBD_BASE+0X030) /* 记录接口的值 */ +#define USBD_CFGINTERFACE2 (USBD_BASE+0X034) /* 记录接口的值 */ +#define USBD_CFGINTERFACE3 (USBD_BASE+0X038) /* 记录接口的值 */ +#define USBD_CFGINTERFACE4 (USBD_BASE+0X03C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE5 (USBD_BASE+0X040) /* 记录接口的值 */ +#define USBD_CFGINTERFACE6 (USBD_BASE+0X044) /* 记录接口的值 */ +#define USBD_CFGINTERFACE7 (USBD_BASE+0X048) /* 记录接口的值 */ +#define USBD_CFGINTERFACE8 (USBD_BASE+0X04C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE9 (USBD_BASE+0X050) /* 记录接口的值 */ +#define USBD_CFGINTERFACE10 (USBD_BASE+0X054) /* 记录接口的值 */ +#define USBD_CFGINTERFACE11 (USBD_BASE+0X058) /* 记录接口的值 */ +#define USBD_CFGINTERFACE12 (USBD_BASE+0X05C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE13 (USBD_BASE+0X060) /* 记录接口的值 */ +#define USBD_CFGINTERFACE14 (USBD_BASE+0X064) /* 记录接口的值 */ +#define USBD_CFGINTERFACE15 (USBD_BASE+0X068) /* 记录接口的值 */ +#define USBD_CFGINTERFACE16 (USBD_BASE+0X06C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE17 (USBD_BASE+0X070) /* 记录接口的值 */ +#define USBD_CFGINTERFACE18 (USBD_BASE+0X074) /* 记录接口的值 */ +#define USBD_CFGINTERFACE19 (USBD_BASE+0X078) /* 记录接口的值 */ +#define USBD_CFGINTERFACE20 (USBD_BASE+0X07C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE21 (USBD_BASE+0X080) /* 记录接口的值 */ +#define USBD_CFGINTERFACE22 (USBD_BASE+0X084) /* 记录接口的值 */ +#define USBD_CFGINTERFACE23 (USBD_BASE+0X088) /* 记录接口的值 */ +#define USBD_CFGINTERFACE24 (USBD_BASE+0X08C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE25 (USBD_BASE+0X090) /* 记录接口的值 */ +#define USBD_CFGINTERFACE26 (USBD_BASE+0X094) /* 记录接口的值 */ +#define USBD_CFGINTERFACE27 (USBD_BASE+0X098) /* 记录接口的值 */ +#define USBD_CFGINTERFACE28 (USBD_BASE+0X09C) /* 记录接口的值 */ +#define USBD_CFGINTERFACE29 (USBD_BASE+0X0A0) /* 记录接口的值 */ +#define USBD_CFGINTERFACE30 (USBD_BASE+0X0A4) /* 记录接口的值 */ +#define USBD_CFGINTERFACE31 (USBD_BASE+0X0A8) /* 记录接口的值 */ +#define USBD_PKTPASSEDCTRL (USBD_BASE+0X0AC) /* 记录成功接收的包数 */ +#define USBD_PKTDROPPEDCTRL (USBD_BASE+0X0B0) /* 记录丢失的包数 */ +#define USBD_CRCERRCTRL (USBD_BASE+0X0B4) /* 记录CRC错误的包数 */ +#define USBD_BITSTUFFERRCTRL (USBD_BASE+0X0B8) /* 记录位填充错误的包数 */ +#define USBD_PIDERRCTRL (USBD_BASE+0X0BC) /* 记录PID错误的包数 */ +#define USBD_FRAMINGERRCTL (USBD_BASE+0X0C0) /* 记录有SYNC和EOP的包数 */ +#define USBD_TXPKTCTRL (USBD_BASE+0X0C4) /* 记录发送包的数量 */ +#define USBD_STATCTRLOV (USBD_BASE+0X0C8) /* 记录统计寄存器溢出情况 */ +#define USBD_TXLENGTH (USBD_BASE+0X0CC) /* 记录每次IN传输事务包长度 */ +#define USBD_RXLENGTH (USBD_BASE+0X0D0) /* 记录OUT传输事务包长度 */ +#define USBD_RESUME (USBD_BASE+0X0D4) /* USB唤醒寄存器 */ +#define USBD_READFLAG (USBD_BASE+0X0D8) /* 读异步状态寄存器标志 */ +#define USBD_RECEIVETYPE (USBD_BASE+0X0DC) /* 传输状态寄存器 */ +#define USBD_APPLOCK (USBD_BASE+0X0E0) /* 锁信号寄存器 */ +#define USBD_EP0OUTADDR (USBD_BASE+0X100) /* 端点0端点号和方向 */ +#define USBD_EP0OUTBMATTR (USBD_BASE+0X104) /* 端点0类型寄存器 */ +#define USBD_EP0OUTMAXPKTSIZE (USBD_BASE+0X108) /* 端点0最大包尺寸寄存器 */ +#define USBD_EP0OUTIFNUM (USBD_BASE+0X10C) /* 端点0接口号寄存器 */ +#define USBD_EP0OUTSTAT (USBD_BASE+0X110) /* 端点0状态寄存器 */ +#define USBD_EP0OUTBMREQTYPE (USBD_BASE+0X114) /* 端点0 SETUP事务请求类 */ +#define USBD_EP0OUTBREQUEST (USBD_BASE+0X118) /* 端点0 SETUP事务请求内容 */ +#define USBD_EP0OUTWVALUE (USBD_BASE+0X11C) /* 端点0 SETUP事务请求值 */ +#define USBD_EP0OUTWINDEX (USBD_BASE+0X120) /* 端点0 SETUP事务请求索引 */ +#define USBD_EP0OUTWLENGTH (USBD_BASE+0X120) /* 端点0 SETUP事务请求长度 */ +#define USBD_EP0OUTSYNCHFRAME (USBD_BASE+0X128) /* 端点0同步包帧号 */ +#define USBD_EP1OUTADDR (USBD_BASE+0X12C) /* 端点1输出端点号和方向 */ +#define USBD_EP1OUTBMATTR (USBD_BASE+0X130) /* 端点1输出类型寄存器 */ +#define USBD_EP1OUTMAXPKTSIZE (USBD_BASE+0X134) /* 端点1输出最大包尺寸寄存器 */ +#define USBD_EP1OUTIFNUM (USBD_BASE+0X138) /* 端点1输出接口号寄存器 */ +#define USBD_EP1OUTSTAT (USBD_BASE+0X13C) /* 端点1输出状态寄存器 */ +#define USBD_EP1OUTBMREQTYPE (USBD_BASE+0X140) /* 端点1输出SETUP事务请求类型 */ +#define USBD_EP1OUTBREQUEST (USBD_BASE+0X144) /* 端点1输出SETUP事务请求内容 */ +#define USBD_EP1OUTWVALUE (USBD_BASE+0X148) /* 端点1输出SETUP事务请求值 */ +#define USBD_EP1OUTWINDX (USBD_BASE+0X14C) /* 端点1输出SETUP事务请求索引 */ +#define USBD_EP1OUTWLENGH (USBD_BASE+0X150) /* 端点1输出SETUP事务请求域长度 */ +#define USBD_EP1OUTSYNCHFRAME (USBD_BASE+0X154) /* 端点1输出同步包帧号 */ +#define USBD_EP1INADDR (USBD_BASE+0X158) /* 端点1输入端点号和方向 */ +#define USBD_EP1INBMATTR (USBD_BASE+0X15C) /* 端点1输入类型寄存器 */ +#define USBD_EP1INMAXPKTSIZE (USBD_BASE+0X160) /* 端点1输入最大包尺寸寄存器 */ +#define USBD_EP1INIFNUM (USBD_BASE+0X164) /* 端点1输入接口号寄存器 */ +#define USBD_EP1INSTAT (USBD_BASE+0X168) /* 端点1输入状态寄存器 */ +#define USBD_EP1INBMREQTYPE (USBD_BASE+0X16C) /* 端点1输入SETUP事务请求类型 */ +#define USBD_EP1INBREQUEST (USBD_BASE+0X170) /* 端点1输入SETUP事务请求内容 */ +#define USBD_EP1INWVALUE (USBD_BASE+0X174) /* 端点1输入SETUP事务请求值 */ +#define USBD_EP1INWINDEX (USBD_BASE+0X178) /* 端点1输入SETUP事务请求索引 */ +#define USBD_EP1INWLENGTH (USBD_BASE+0X17C) /* 端点1输入SETUP事务请求域长度 */ +#define USBD_EP1INSYNCHFRAME (USBD_BASE+0X180) /* 端点1输入同步包帧号 */ +#define USBD_EP2OUTADDR (USBD_BASE+0X184) /* 端点2输出端点号和方向 */ +#define USBD_EP2OUTBMATTR (USBD_BASE+0X188) /* 端点2输出类型寄存器 */ +#define USBD_EP2OUTMAXPKTSIZE (USBD_BASE+0X18C) /* 端点2输出最大包尺寸寄存器 */ +#define USBD_EP2OUTIFNUM (USBD_BASE+0X190) /* 端点2输出接口号寄存器 */ +#define USBD_EP2OUTSTAT (USBD_BASE+0X194) /* 端点2输出状态寄存器 */ +#define USBD_EP2OUTBMREQTYPE (USBD_BASE+0X198) /* 端点2输出SETUP事务请求类型 */ +#define USBD_EP2OUTBREQUEST (USBD_BASE+0X19C) /* 端点2输出SETUP事务请求内容 */ +#define USBD_EP2OUTWVALUE (USBD_BASE+0X1A0) /* 端点2输出SETUP事务请求值 */ +#define USBD_EP2OUTWINDEX (USBD_BASE+0X1A4) /* 端点2输出SETUP事务请求索引 */ +#define USBD_EP2OUTWLENGTH (USBD_BASE+0X1A8) /* 端点2输出SETUP事务请求域长度 */ +#define USBD_EP2OUTSYNCHFRAME (USBD_BASE+0X1AC) /* 端点2输出同步包帧号 */ +#define USBD_EP2INADDR (USBD_BASE+0X1B0) /* 端点2输入端点号和方向 */ +#define USBD_EP2INBMATTR (USBD_BASE+0X1B4) /* 端点2输入类型寄存器 */ +#define USBD_EP2INMAXPKTSIZE (USBD_BASE+0X1B8) /* 端点2输入最大包尺寸寄存器 */ +#define USBD_EP2INIFNUM (USBD_BASE+0X1BC) /* 端点2输入接口号寄存器 */ +#define USBD_EP2INSTAT (USBD_BASE+0X1C0) /* 端点2输入状态寄存器 */ +#define USBD_EP2INBMREQTYPE (USBD_BASE+0X1C4) /* 端点2输入SETUP事务请求类型 */ +#define USBD_EP2INBREQUEST (USBD_BASE+0X1C8) /* 端点2输入SETUP事务请求内容 */ +#define USBD_EP2INWVALUE (USBD_BASE+0X1CC) /* 端点2输入SETUP事务请求值 */ +#define USBD_EP2INWINDEX (USBD_BASE+0X1D0) /* 端点2输入SETUP事务请求索引 */ +#define USBD_EP2INWLENGTH (USBD_BASE+0X1D4) /* 端点2输入SETUP事务请求域长度 */ +#define USBD_EP2INSYNCHFRAME (USBD_BASE+0X1D8) /* 端点2输入同步包帧号 */ +#define USBD_RXFIFO (USBD_BASE+0X200) /* 接受FIFO */ +#define USBD_TXFIFO (USBD_BASE+0X300) /* 发送FIFO */ + + +/* + * GPIO模块 + * 基址: 0x1000F000 + */ + +#define GPIO_DBCLK_DIV (GPIO_BASE+0X000) /* 去毛刺采用时钟分频比配置寄存器 */ +#define GPIO_PORTA_DIR (GPIO_BASE+0X004) /* A组端口输入输出方向配置寄存器 */ +#define GPIO_PORTA_SEL (GPIO_BASE+0X008) /* A组端口通用用途选择配置寄存器 */ +#define GPIO_PORTA_INCTL (GPIO_BASE+0X00C) /* A组端口通用用途输入时类型配置寄存器 */ +#define GPIO_PORTA_INTRCTL (GPIO_BASE+0X010) /* A组端口中断触发类型配置寄存器 */ +#define GPIO_PORTA_INTRCLR (GPIO_BASE+0X014) /* A组端口通用用途中断清除配置寄存器 */ +#define GPIO_PORTA_DATA (GPIO_BASE+0X018) /* A组端口通用用途数据配置寄存器 */ +#define GPIO_PORTB_DIR (GPIO_BASE+0X01C) /* B组端口输入输出方向配置寄存器 */ +#define GPIO_PORTB_SEL (GPIO_BASE+0X020) /* B组端口通用用途选择配置寄存器 */ +#define GPIO_PORTB_DATA (GPIO_BASE+0X024) /* B组端口通用用途数据配置寄存器 */ +#define GPIO_PORTC_DIR (GPIO_BASE+0X028) /* C组端口输入输出方向配置寄存器 */ +#define GPIO_PORTC_SEL (GPIO_BASE+0X02C) /* C组端口通用用途选择配置寄存器 */ +#define GPIO_PORTC_DATA (GPIO_BASE+0X030) /* C组端口通用用途数据配置寄存器 */ +#define GPIO_PORTD_DIR (GPIO_BASE+0X034) /* D组端口输入输出方向配置寄存器 */ +#define GPIO_PORTD_SEL (GPIO_BASE+0X038) /* D组端口通用用途选择配置寄存器 */ +#define GPIO_PORTD_SPECII (GPIO_BASE+0X03C) /* D组端口专用用途2选择配置寄存器 */ +#define GPIO_PORTD_DATA (GPIO_BASE+0X040) /* D组端口通用用途数据配置寄存器 */ +#define GPIO_PORTE_DIR (GPIO_BASE+0X044) /* E组端口输入输出方向配置寄存器 */ +#define GPIO_PORTE_SEL (GPIO_BASE+0X048) /* E组端口通用用途选择配置寄存器 */ +#define GPIO_PORTE_DATA (GPIO_BASE+0X04C) /* E组端口通用用途数据配置寄存器 */ +#define GPIO_PORTF_DIR (GPIO_BASE+0X050) /* F组端口输入输出方向配置寄存器 */ +#define GPIO_PORTF_SEL (GPIO_BASE+0X054) /* F组端口通用用途选择配置寄存器 */ +#define GPIO_PORTF_INCTL (GPIO_BASE+0X058) /* F组端口通用用途输入时类型配置寄存器 */ +#define GPIO_PORTF_INTRCTL (GPIO_BASE+0X05C) /* F组端口中断触发类型配置寄存器 */ +#define GPIO_PORTF_INTRCLR (GPIO_BASE+0X060) /* F组端口通用用途中断清除配置寄存器 */ +#define GPIO_PORTF_DATA (GPIO_BASE+0X064) /* F组端口通用用途数据配置寄存器 */ +#define GPIO_PORTG_DIR (GPIO_BASE+0X068) /* G组端口输入输出方向配置寄存器 */ +#define GPIO_PORTG_SEL (GPIO_BASE+0X06C) /* G组端口通用用途选择配置寄存器 */ +#define GPIO_PORTG_DATA (GPIO_BASE+0X070) /* G组端口通用用途数据配置寄存器 */ +#define GPIO_PORTH_DIR (GPIO_BASE+0X07C) /* H组端口输入输出方向配置寄存器 */ +#define GPIO_PORTH_SEL (GPIO_BASE+0X078) /* H组端口通用用途选择配置寄存器 */ +#define GPIO_PORTH_DATA (GPIO_BASE+0X07C) /* H组端口通用用途数据配置寄存器 */ +#define GPIO_PORTI_DIR (GPIO_BASE+0X080) /* I组端口输入输出方向配置寄存器 */ +#define GPIO_PORTI_SEL (GPIO_BASE+0X084) /* I组端口通用用途选择配置寄存器 */ +#define GPIO_PORTI_DATA (GPIO_BASE+0X088) /* I组端口通用用途数据配置寄存器 */ + + + +/* + * EMI模块 + * 基址: 0x11000000 + */ + +#define EMI_CSACONF (EMI_BASE+0X000) /* CSA参数配置寄存器 */ +#define EMI_CSBCONF (EMI_BASE+0X004) /* CSB参数配置寄存器 */ +#define EMI_CSCCONF (EMI_BASE+0X008) /* CSC参数配置寄存器 */ +#define EMI_CSDCONF (EMI_BASE+0X00C) /* CSD参数配置寄存器 */ +#define EMI_CSECONF (EMI_BASE+0X010) /* CSE参数配置寄存器 */ +#define EMI_CSFCONF (EMI_BASE+0X014) /* CSF参数配置寄存器 */ +#define EMI_SDCONF1 (EMI_BASE+0X018) /* SDRAM时序配置寄存器1 */ +#define EMI_SDCONF2 (EMI_BASE+0X01C) /* SDRAM时序配置寄存器2, SDRAM初始化用到的配置信息 */ +#define EMI_REMAPCONF (EMI_BASE+0X020) /* 片选空间及地址映射REMAP配置寄存器 */ +#define EMI_NAND_ADDR1 (EMI_BASE+0X100) /* NAND FLASH的地址寄存器1 */ +#define EMI_NAND_COM (EMI_BASE+0X104) /* NAND FLASH的控制字寄存器 */ +#define EMI_NAND_STA (EMI_BASE+0X10C) /* NAND FLASH的状态寄存器 */ +#define EMI_ERR_ADDR1 (EMI_BASE+0X110) /* 读操作出错的地址寄存器1 */ +#define EMI_ERR_ADDR2 (EMI_BASE+0X114) /* 读操作出错的地址寄存器2 */ +#define EMI_NAND_CONF1 (EMI_BASE+0X118) /* NAND FLASH的配置器存器1 */ +#define EMI_NAND_INTR (EMI_BASE+0X11C) /* NAND FLASH中断寄存器 */ +#define EMI_NAND_ECC (EMI_BASE+0X120) /* ECC校验完成寄存器 */ +#define EMI_NAND_IDLE (EMI_BASE+0X124) /* NAND FLASH空闲寄存器 */ +#define EMI_NAND_CONF2 (EMI_BASE+0X128) /* NAND FLASH的配置器存器2 */ +#define EMI_NAND_ADDR2 (EMI_BASE+0X12C) /* NAND FLASH的地址寄存器2 */ +#define EMI_NAND_DATA (EMI_BASE+0X200) /* NAND FLASH的数据寄存器 */ + + +/* + * DMAC模块 + * 基址: 0x11001000 + */ + +#define DMAC_INTSTATUS (DMAC_BASE+0X020) /* DAMC中断状态寄存器。 */ +#define DMAC_INTTCSTATUS (DMAC_BASE+0X050) /* DMAC传输完成中断状态寄存器 */ +#define DMAC_INTTCCLEAR (DMAC_BASE+0X060) /* DMAC传输完成中断状态清除寄存器 */ +#define DMAC_INTERRORSTATUS (DMAC_BASE+0X080) /* DMAC传输错误中断状态寄存器 */ +#define DMAC_INTINTERRCLR (DMAC_BASE+0X090) /* DMAC传输错误中断状态清除寄存器 */ +#define DMAC_ENBLDCHNS (DMAC_BASE+0X0B0) /* DMAC通道使能状态寄存器 */ +#define DMAC_C0SRCADDR (DMAC_BASE+0X000) /* DMAC道0源地址寄存器 */ +#define DMAC_C0DESTADD (DMAC_BASE+0X004) /* DMAC道0目的地址寄存器 */ +#define DMAC_C0CONTROL (DMAC_BASE+0X00C) /* DMAC道0控制寄存器 */ +#define DMAC_C0CONFIGURATION (DMAC_BASE+0X010) /* DMAC道0配置寄存器 */ +#define DMAC_C0DESCRIPTOR (DMAC_BASE+0X01C) /* DMAC道0链表地址寄存器 */ +#define DMAC_C1SRCADDR (DMAC_BASE+0X100) /* DMAC道1源地址寄存器 */ +#define DMAC_C1DESTADDR (DMAC_BASE+0X104) /* DMAC道1目的地址寄存器 */ +#define DMAC_C1CONTROL (DMAC_BASE+0X10C) /* DMAC道1控制寄存器 */ +#define DMAC_C1CONFIGURATION (DMAC_BASE+0X110) /* DMAC道1配置寄存器 */ +#define DMAC_C1DESCRIPTOR (DMAC_BASE+0X114) /* DMAC道1链表地址寄存器 */ +#define DMAC_C2SRCADDR (DMAC_BASE+0X200) /* DMAC道2源地址寄存器 */ +#define DMAC_C2DESTADDR (DMAC_BASE+0X204) /* DMAC道2目的地址寄存器 */ +#define DMAC_C2CONTROL (DMAC_BASE+0X20C) /* DMAC道2控制寄存器 */ +#define DMAC_C2CONFIGURATION (DMAC_BASE+0X210) /* DMAC道2配置寄存器 */ +#define DMAC_C2DESCRIPTOR (DMAC_BASE+0X214) /* DMAC道2链表地址寄存器 */ +#define DMAC_C3SRCADDR (DMAC_BASE+0X300) /* DMAC道3源地址寄存器 */ +#define DMAC_C3DESTADDR (DMAC_BASE+0X304) /* DMAC道3目的地址寄存器 */ +#define DMAC_C3CONTROL (DMAC_BASE+0X30C) /* DMAC道3控制寄存器 */ +#define DMAC_C3CONFIGURATION (DMAC_BASE+0X310) /* DMAC道3配置寄存器 */ +#define DMAC_C3DESCRIPTOR (DMAC_BASE+0X314) /* DMAC道3链表地址寄存器 */ +#define DMAC_C4SRCADDR (DMAC_BASE+0X400) /* DMAC道4源地址寄存器 */ +#define DMAC_C4DESTADDR (DMAC_BASE+0X404) /* DMAC道4目的地址寄存器 */ +#define DMAC_C4CONTROL (DMAC_BASE+0X40C) /* DMAC道4控制寄存器 */ +#define DMAC_C4CONFIGURATION (DMAC_BASE+0X410) /* DMAC道4配置寄存器 */ +#define DMAC_C4DESCRIPTOR (DMAC_BASE+0X414) /* DMAC道4链表地址寄存器 */ +#define DMAC_C5SRCADDR (DMAC_BASE+0X500) /* DMAC道5源地址寄存器 */ +#define DMAC_C5DESTADDR (DMAC_BASE+0X504) /* DMAC道5目的地址寄存器 */ +#define DMAC_C5CONTROL (DMAC_BASE+0X50C) /* DMAC道5控制寄存器 */ +#define DMAC_C5CONFIGURATION (DMAC_BASE+0X510) /* DMAC道5配置寄存器 */ +#define DMAC_C5DESCRIPTOR (DMAC_BASE+0X514) /* DMAC道5链表地址寄存器 */ + + +/* + * LCDC模块 + * 基址: 0x11002000 + */ + +#define LCDC_SSA (LCDC_BASE+0X000) /* 屏幕起始地址寄存器 */ +#define LCDC_SIZE (LCDC_BASE+0X004) /* 屏幕尺寸寄存器 */ +#define LCDC_PCR (LCDC_BASE+0X008) /* 面板配置寄存器 */ +#define LCDC_HCR (LCDC_BASE+0X00C) /* 水平配置寄存器 */ +#define LCDC_VCR (LCDC_BASE+0X010) /* 垂直配置寄存器 */ +#define LCDC_PWMR (LCDC_BASE+0X014) /* PWM对比度控制寄存器 */ +#define LCDC_LECR (LCDC_BASE+0X018) /* 使能控制寄存器 */ +#define LCDC_DMACR (LCDC_BASE+0X01C) /* DMA控制寄存器 */ +#define LCDC_LCDISREN (LCDC_BASE+0X020) /* 中断使能寄存器 */ +#define LCDC_LCDISR (LCDC_BASE+0X024) /* 中断状态寄存器 */ +#define LCDC_LGPMR (LCDC_BASE+0X040) /* 灰度调色映射寄存器组 (16个32bit寄存器) */ + + +/* + * MAC模块 + * 基址: 0x11003000 + */ + +#define MAC_CTRL (MAC_BASE+0X000) /* MAC控制寄存器 */ +#define MAC_INTSRC (MAC_BASE+0X004) /* MAC中断源寄存器 */ +#define MAC_INTMASK (MAC_BASE+0X008) /* MAC中断屏蔽寄存器 */ +#define MAC_IPGT (MAC_BASE+0X00C) /* 连续帧间隔寄存器 */ +#define MAC_IPGR1 (MAC_BASE+0X010) /* 等待窗口寄存器 */ +#define MAC_IPGR2 (MAC_BASE+0X014) /* 等待窗口寄存器 */ +#define MAC_PACKETLEN (MAC_BASE+0X018) /* 帧长度寄存器 */ +#define MAC_COLLCONF (MAC_BASE+0X01C) /* 碰撞重发寄存器 */ +#define MAC_TXBD_NUM (MAC_BASE+0X020) /* 发送描述符寄存器 */ +#define MAC_FLOWCTRL (MAC_BASE+0X024) /* 流控寄存器 */ +#define MAC_MII_CTRL (MAC_BASE+0X028) /* PHY控制寄存器 */ +#define MAC_MII_CMD (MAC_BASE+0X02C) /* PHY命令寄存器 */ +#define MAC_MII_ADDRESS (MAC_BASE+0X030) /* PHY地址寄存器 */ +#define MAC_MII_TXDATA (MAC_BASE+0X034) /* PHY写数据寄存器 */ +#define MAC_MII_RXDATA (MAC_BASE+0X038) /* PHY读数据寄存器 */ +#define MAC_MII_STATUS (MAC_BASE+0X03C) /* PHY状态寄存器 */ +#define MAC_ADDR0 (MAC_BASE+0X040) /* MAC地址寄存器 */ +#define MAC_ADDR1 (MAC_BASE+0X044) /* MAC地址寄存器 */ +#define MAC_HASH0 (MAC_BASE+0X048) /* MAC HASH寄存器 */ +#define MAC_HASH1 (MAC_BASE+0X04C) /* MAC HASH寄存器 */ +#define MAC_TXPAUSE (MAC_BASE+0X050) /* MAC控制帧寄存器 */ +#define MAC_TX_BD (MAC_BASE+0X400) +#define MAC_RX_BD (MAC_BASE+0X600) + + +/* + ************************************** + * Error Codes: + * IF SUCCESS RETURN 0, ELSE RETURN OTHER ERROR CODE, + * parameter error return (-33)/E_PAR, + * hardware error reture (-99)/E_HA + ************************************** + */ + +#define E_OK 0 /* Normal completion */ +#define E_SYS (-5) /* System error */ +#define E_NOMEM (-10) /* Insufficient memory */ +#define E_NOSPT (-17) /* Feature not supported */ +#define E_INOSPT (-18) /* Feature not supported by ITRON/FILE specification */ +#define E_RSFN (-20) /* Reserved function code number */ +#define E_RSATR (-24) /* Reserved attribute */ +#define E_PAR (-33) /* Parameter error */ +#define E_ID (-35) /* Invalid ID number */ +#define E_NOEXS (-52) /* Object does not exist */ +#define E_OBJ (-63) /* Invalid object state */ +#define E_MACV (-65) /* Memory access disabled or memory access violation */ +#define E_OACV (-66) /* Object access violation */ +#define E_CTX (-69) /* Context error */ +#define E_QOVR (-73) /* Queuing or nesting overflow */ +#define E_DLT (-81) /* Object being waited for was deleted */ +#define E_TMOUT (-85) /* Polling failure or timeout exceeded */ +#define E_RLWAI (-86) /* WAIT state was forcibly released */ + +#define E_HA (-99) /* HARD WARE ERROR */ + + +/* + ************************************** + * PMU 模块时钟 + ************************************** + */ + +#define CLK_SGPT (1 << 16) +#define CLK_SI2S (1 << 15) +#define CLK_SSMC (1 << 14) +#define CLK_SMAC (1 << 13) +#define CLK_SUSB (1 << 12) +#define CLK_SUART3 (1 << 11) +#define CLK_SUART2 (1 << 10) +#define CLK_SUART1 (1 << 9) +#define CLK_SUART0 (1 << 8) +#define CLK_SSSI (1 << 7) +#define CLK_SAC97 (1 << 6) +#define CLK_SMMCSD (1 << 5) +#define CLK_SEMI (1 << 4) +#define CLK_SDMAC (1 << 3) +#define CLK_SPWM (1 << 2) +#define CLK_SLCDC (1 << 1) +#define CLK_SESRAM (1) + + +/*Interrupt Sources*/ + + +#define INTSRC_RTC 31 +#define INTSRC_DMAC 30 +#define INTSRC_EMI 29 +#define INTSRC_MAC 28 +#define INTSRC_TIMER1 27 +#define INTSRC_TIMER2 26 +#define INTSRC_TIMER3 25 +#define INTSRC_UART0 24 +#define INTSRC_UART1 23 +#define INTSRC_UART2 22 +#define INTSRC_UART3 21 +#define INTSRC_PWM 20 +#define INTSRC_LCDC 19 +#define INTSRC_I2S 18 +#define INTSRC_SSI 17 + +#define INTSRC_USB 15 +#define INTSRC_SMC0 14 +#define INTSRC_SMC1 13 +#define INTSRC_SDIO 12 +#define INTSRC_EXINT10 11 +#define INTSRC_EXINT9 10 +#define INTSRC_EXINT8 9 +#define INTSRC_EXINT7 8 +#define INTSRC_EXINT6 7 +#define INTSRC_EXINT5 6 +#define INTSRC_EXINT4 5 +#define INTSRC_EXINT3 4 +#define INTSRC_EXINT2 3 +#define INTSRC_EXINT1 2 +#define INTSRC_EXINT0 1 +#define INTSRC_NULL 0 + + +/*Sereral useful macros*/ +#define set_plevel(plevel) *(RP)INTC_IPLR = plevel //设置普通中断的优先级门限,只有优先级大于此值的中断才能通过 +#define set_int_force(intnum) *(RP)INTC_IFR = (1 << intnum) //置1后,软件强制该位对应的中断源发出中断信号 +#define enable_irq(intnum) *(RP)INTC_IER |= (1 << intnum) //置1后,允许中断源的IRQ 中断信号 +#define disable_irq( intnum) *(RP)INTC_IER &= ~(1<< intnum) //置0后,不允许中断源的IRQ 中断信号 +#define mask_irq(intnum) *(RP)INTC_IMR |= (1 << intnum) //置1后,屏蔽对应的IRQ 中断信号 +#define unmask_irq(intnum) *(RP)INTC_IMR &= ~(1 << intnum) //置0后,通过对应的IRQ 中断信号 +#define mask_all_irq() *(RP)INTC_IMR = 0xFFFFFFFF //屏蔽对应的IRQ 中断信号 +#define unmask_all_irq() *(RP)INTC_IMR = 0x00000000 //通过对应的IRQ 中断信号 +#define enable_all_irq() *(RP)INTC_IER = 0XFFFFFFFF //允许中断源的IRQ 中断信号 +#define disable_all_irq() *(RP)INTC_IER = 0X00000000 //不允许中断源的IRQ 中断信号 +#define InitInt() do{mask_all_irq(); enable_all_irq();}while(0) + +/* + ************************************** + * 所有程序中用到的Typedef + ************************************** + */ + +typedef char S8; /* signed 8-bit integer */ +typedef short S16; /* signed 16-bit integer */ +typedef long S32; /* signed 32-bit integer */ +typedef unsigned char U8; /* unsigned 8-bit integer */ +typedef unsigned short U16; /* unsigned 16-bit integer */ +typedef unsigned long U32; /* unsigned 32-bit integer */ + +typedef volatile U32 * RP; +typedef volatile U16 * RP16; +typedef volatile U8 * RP8; + +typedef void *VP; /* pointer to an unpredictable data type */ +typedef void (*FP)(); /* program start address */ + +#ifndef _BOOL_TYPE_ +#define _BOOL_TYPE_ +typedef int BOOL; /* Boolean value. TRUE (1) or FALSE (0). */ +#endif + +typedef int ER; /* Error code. A signed integer. */ + +/** + * IO definitions + * + * define access restrictions to peripheral registers + */ + +#define __I volatile const /*!< defines 'read only' permissions */ +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ +#define __iomem volatile + + +/*Macros for debug*/ + +#define EOUT(fmt,...) \ + do \ + { \ + rt_kprintf("EOUT:(%s:%i) ",__FILE__,__LINE__); \ + rt_kprintf(fmt,##__VA_ARGS__); \ + }while(0) + +#define RT_DEBUG +#ifdef RT_DEBUG + #define DBOUT(fmt,...) \ + do \ + { \ + rt_kprintf("DBOUT:(%s:%i) ",__FILE__,__LINE__); \ + rt_kprintf(fmt,##__VA_ARGS__); \ + }while(0) +#else + #define DBOUT(fmt,...) \ + do{}while(0) +#endif + +#ifdef RT_DEBUG + #define ASSERT(arg) \ + if((arg) == 0) \ + { \ + while(1) \ + { \ + rt_kprintf("have a assert failure\n"); \ + } \ + } +#else + #define ASSERT(arg) \ + do \ + { \ + }while(0) +#endif + + +#define write_reg(reg,value) \ + do \ + { \ + *(RP)(reg) = value; \ + }while(0) + +#define read_reg(reg) (*(RP)reg) + + +struct rt_hw_register +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t fp; + rt_uint32_t ip; + rt_uint32_t sp; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t cpsr; + rt_uint32_t ORIG_r0; +}; + + +/*@}*/ + +#endif diff --git a/bsp/mini4020/serial.c b/bsp/mini4020/serial.c new file mode 100644 index 000000000..c9dbc3c02 --- /dev/null +++ b/bsp/mini4020/serial.c @@ -0,0 +1,282 @@ +/* + * File : serial.c + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-13 Bernard first version + * 2009-04-20 yi.qiu modified according bernard's stm32 version + * 2010-10-6 wangmeng added sep4020 surpport + */ +#include +#include +#include "serial.h" + +/** + * @addtogroup SEP4020 + */ +/*@{*/ + +/* RT-Thread Device Interface */ +/** + * This function initializes serial + */ +static rt_err_t rt_serial_init (rt_device_t dev) +{ + struct serial_device* uart = (struct serial_device*) dev->user_data; + + if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) + { + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_memset(uart->int_rx->rx_buffer, 0, + sizeof(uart->int_rx->rx_buffer)); + uart->int_rx->read_index = uart->int_rx->save_index = 0; + } + + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + rt_memset(uart->int_tx->tx_buffer, 0, + sizeof(uart->int_tx->tx_buffer)); + uart->int_tx->write_index = uart->int_tx->save_index = 0; + } + + dev->flag |= RT_DEVICE_FLAG_ACTIVATED; + } + + return RT_EOK; +} + +/* save a char to serial buffer */ +static void rt_serial_savechar(struct serial_device* uart, char ch) +{ + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch; + uart->int_rx->save_index ++; + if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->save_index = 0; + + /* if the next position is read index, discard this 'read char' */ + if (uart->int_rx->save_index == uart->int_rx->read_index) + { + uart->int_rx->read_index ++; + if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->read_index = 0; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); +} + +static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_ASSERT(dev != RT_NULL); + return RT_EOK; +} + +static rt_err_t rt_serial_close(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + return RT_EOK; +} + +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; + rt_err_t err_code; + struct serial_device* uart; + + ptr = buffer; + err_code = RT_EOK; + uart = (struct serial_device*)dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_base_t level; + + /* interrupt mode Rx */ + while (size) + { + if (uart->int_rx->read_index != uart->int_rx->save_index) + { + *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; + size --; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + uart->int_rx->read_index ++; + if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->read_index = 0; + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + else + { + /* set error code */ + err_code = -RT_EEMPTY; + break; + } + } + } + else + { + /* polling mode */ + while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) + { + while (uart->uart_device->lsr & USTAT_RCV_READY) + { + *ptr = uart->uart_device->dlbl_fifo.txfifo & 0xff; + ptr ++; + } + } + } + + /* set error code */ + rt_set_errno(err_code); + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +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; + rt_err_t err_code; + struct serial_device* uart; + + err_code = RT_EOK; + ptr = (rt_uint8_t*)buffer; + uart = (struct serial_device*)dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + /* interrupt mode Tx */ + while (uart->int_tx->save_index != uart->int_tx->write_index) + { + /* save on tx buffer */ + uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++; + + -- size; + + /* move to next position */ + uart->int_tx->save_index ++; + + /* wrap save index */ + if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE) + uart->int_tx->save_index = 0; + } + + /* set error code */ + if (size > 0) + err_code = -RT_EFULL; + } + else + { + /* polling mode */ + while (size) + { + /* + * to be polite with serial console add a line feed + * to the carriage return character + */ + if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) + { + while (!(uart->uart_device->lsr & USTAT_TXB_EMPTY)); + uart->uart_device->dlbl_fifo.txfifo = '\r'; + } + + while (!(uart->uart_device->lsr & USTAT_TXB_EMPTY)); + uart->uart_device->dlbl_fifo.txfifo = (*ptr & 0x1FF); + + ++ptr; --size; + } + } + + /* set error code */ + rt_set_errno(err_code); + + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_SUSPEND: + /* suspend device */ + dev->flag |= RT_DEVICE_FLAG_SUSPENDED; + break; + + case RT_DEVICE_CTRL_RESUME: + /* resume device */ + dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; + break; + } + + return RT_EOK; +} + +/* + * serial register + */ +rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial) +{ + RT_ASSERT(device != RT_NULL); + + device->type = RT_Device_Class_Char; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + 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; + device->user_data = serial; + + /* register a character device */ + return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); +} + +/* ISR for serial interrupt */ +void rt_hw_serial_isr(rt_device_t device) +{ + struct serial_device* uart = (struct serial_device*) device->user_data; + + /* interrupt mode receive */ + RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); + + /* save on rx buffer */ + while (uart->uart_device->lsr & USTAT_RCV_READY) + { + rt_serial_savechar(uart, uart->uart_device->dlbl_fifo.rxfifo & 0xff); + } + + /* invoke callback */ + if (device->rx_indicate != RT_NULL) + { + rt_size_t rx_length; + + /* get rx length */ + rx_length = uart->int_rx->read_index > uart->int_rx->save_index ? + UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index : + uart->int_rx->save_index - uart->int_rx->read_index; + + device->rx_indicate(device, rx_length); + } +} + +/*@}*/ + diff --git a/bsp/mini4020/serial.h b/bsp/mini4020/serial.h new file mode 100644 index 000000000..f903c1e1a --- /dev/null +++ b/bsp/mini4020/serial.h @@ -0,0 +1,90 @@ +/* + * File : serial.c + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-13 Bernard first version + * 2009-04-20 yi.qiu modified according bernard's stm32 version + * 2010-10-6 wangmeng added sep4020 surpport + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + +#include + +#define USTAT_RCV_READY 0x01 /* receive data ready */ +#define USTAT_TXB_EMPTY 0x40 /* tx buffer empty */ +#define BPS 115200 /* serial baudrate */ + +#define UART_RX_BUFFER_SIZE 64 +#define UART_TX_BUFFER_SIZE 64 + +/*For sep4020's uart have several secondary function*/ +/*we use union to decribe it*/ + +union dlbl_fifo +{ + rt_uint32_t dlbl; + rt_uint32_t rxfifo; + rt_uint32_t txfifo; +}; + +union dlbh_ier +{ + rt_uint32_t dlbh; + rt_uint32_t ier; +}; + +union iir_fcr +{ + rt_uint32_t iir; + rt_uint32_t fcr; +}; + +struct serial_int_rx +{ + rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE]; + rt_uint32_t read_index, save_index; +}; + +struct serial_int_tx +{ + rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE]; + rt_uint32_t write_index, save_index; +}; + +typedef struct uartport +{ + union dlbl_fifo dlbl_fifo; + union dlbh_ier dlbh_ier; + union iir_fcr iir_fcr; + rt_uint32_t lcr; + rt_uint32_t mcr; + rt_uint32_t lsr; + rt_uint32_t msr; +}uartport; + +struct serial_device +{ + uartport* uart_device; + + /* rx structure */ + struct serial_int_rx* int_rx; + + /* tx structure */ + struct serial_int_tx* int_tx; +}; + +rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial); + +void rt_hw_serial_isr(rt_device_t device); + + +#endif diff --git a/bsp/mini4020/startup.c b/bsp/mini4020/startup.c new file mode 100644 index 000000000..c75eb3b2a --- /dev/null +++ b/bsp/mini4020/startup.c @@ -0,0 +1,107 @@ +#include +#include + +#include +#include +#include +#include + +#ifdef RT_USING_LWIP +#include +#include +#endif + +#define SDRAM_BASE 0x30000000 + + +#ifdef __CC_ARM +extern int Image$$RW_RAM1$$ZI$$Limit; +#endif + +extern void rt_application_init(void); +extern void finsh_system_init(void); +extern void sd_init(void); + +void rtthread_startup() +{ + /* init hardware interrupt */ + rt_hw_interrupt_init(); + + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + + /* init kernel object */ + rt_system_object_init(); + + /* init timer system */ + rt_system_timer_init(); + + /* init heap memory system */ +#ifdef __CC_ARM + rt_system_heap_init((void*)&Image$$RW_RAM1$$ZI$$Limit, (void*)(SDRAM_BASE + 0x200000)); +#else + rt_system_heap_init(&__bss_end, (void*)0x34000000); +#endif + + + /* init scheduler system */ + rt_system_scheduler_init(); + +#ifdef RT_USING_DEVICE + +#ifdef RT_USING_DFS + rt_hw_sdcard_init(); +#endif + +#ifdef RT_USING_LWIP + eth_system_device_init(); + rt_hw_dm9161_init(); +#endif + + /*init all registed devices */ + rt_device_init_all(); +#endif + + /* init application */ + rt_application_init(); + +#ifdef RT_USING_FINSH + /* init finsh */ + finsh_system_init(); +#ifdef RT_USING_DEVICE + finsh_set_device("uart0"); +#endif +#endif + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; + +} + +int main() +{ + rt_uint32_t UNUSED level; + + /* disable interrupt first */ + level = rt_hw_interrupt_disable(); + + /* startup RT-Thread RTOS */ + rtthread_startup(); + + return 0; +} + + +