diff options
| author | zhuangwei123 <[email protected]> | 2018-05-10 22:20:37 +0800 |
|---|---|---|
| committer | zhuangwei123 <[email protected]> | 2018-05-10 22:20:37 +0800 |
| commit | 6725dfa59806410dcb60b59d269a92e64503da2d (patch) | |
| tree | 0aa851cbca0223f1a5de7dd3f78339cb94eb9855 /bsp/ls1cdev/drivers | |
| parent | c13624298619508a2c8d10ce66f80564213c4fba (diff) | |
[bsp/ls1cdev]
1、uart驱动重写,采用uart驱动框架
2、添加并修改勤为本ls1c_uart
3、开启main为用户程序入口,删除application.c和startup.c,并对初始化部分做相应调整更新。
4、开启dhcp
Diffstat (limited to 'bsp/ls1cdev/drivers')
| -rw-r--r-- | bsp/ls1cdev/drivers/board.c | 70 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/drv_uart.c | 177 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/drv_uart.h (renamed from bsp/ls1cdev/drivers/uart.h) | 14 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/net/synopGMAC.c | 7 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/net/synopGMAC.h | 2 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/net/synopGMAC_plat.h | 4 | ||||
| -rw-r--r-- | bsp/ls1cdev/drivers/uart.c | 286 |
7 files changed, 225 insertions, 335 deletions
diff --git a/bsp/ls1cdev/drivers/board.c b/bsp/ls1cdev/drivers/board.c index 1b22741140..64f0db56ab 100644 --- a/bsp/ls1cdev/drivers/board.c +++ b/bsp/ls1cdev/drivers/board.c @@ -18,9 +18,22 @@ #include <rthw.h> #include "board.h" -#include "uart.h" +#include "drv_uart.h" #include "ls1c.h" +#define A_K0BASE 0x80000000 + +extern unsigned char __bss_end; + + +extern void tlb_refill_exception(void); +extern void general_exception(void); +extern void irq_exception(void); +extern void rt_hw_cache_init(void); +extern void invalidate_writeback_dcache_all(void); +extern void invalidate_icache_all(void); + + /** * @addtogroup Loongson LS1B */ @@ -81,6 +94,24 @@ void rt_hw_fpu_init(void) */ void rt_hw_board_init(void) { + /* init cache */ + rt_hw_cache_init(); + + /* init hardware interrupt */ + rt_hw_interrupt_init(); + + /* copy vector */ + rt_memcpy((void *)A_K0BASE, tlb_refill_exception, 0x80); + rt_memcpy((void *)(A_K0BASE + 0x180), general_exception, 0x80); + rt_memcpy((void *)(A_K0BASE + 0x200), irq_exception, 0x80); + + invalidate_writeback_dcache_all(); + invalidate_icache_all(); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)&__bss_end, (void*)RT_HW_HEAP_END); +#endif + #ifdef RT_USING_SERIAL /* init hardware UART device */ rt_hw_uart_init(); @@ -105,41 +136,4 @@ void rt_hw_board_init(void) rt_kprintf("current sr: 0x%08x\n", read_c0_status()); } -#define __raw_out_put(unr) \ - while (*ptr) \ - { \ - if (*ptr == '\n') \ - { \ - /* FIFO status, contain valid data */ \ - while (!(UART_LSR(UART##unr##_BASE) & (UARTLSR_TE | UARTLSR_TFE))); \ - /* write data */ \ - UART_DAT(UART##unr##_BASE) = '\r'; \ - } \ - /* FIFO status, contain valid data */ \ - while (!(UART_LSR(UART##unr##_BASE) & (UARTLSR_TE | UARTLSR_TFE))); \ - /* write data */ \ - UART_DAT(UART##unr##_BASE) = *ptr; \ - ptr ++; \ - } - -/* UART line status register value */ -#define UARTLSR_ERROR (1 << 7) -#define UARTLSR_TE (1 << 6) -#define UARTLSR_TFE (1 << 5) -#define UARTLSR_BI (1 << 4) -#define UARTLSR_FE (1 << 3) -#define UARTLSR_PE (1 << 2) -#define UARTLSR_OE (1 << 1) -#define UARTLSR_DR (1 << 0) -void rt_hw_console_output(const char *ptr) -{ -#if defined(RT_USING_UART0) - __raw_out_put(0); -#elif defined(RT_USING_UART2) - __raw_out_put(2); -#elif defined(RT_USING_UART3) - __raw_out_put(3); -#endif -} - /*@}*/ diff --git a/bsp/ls1cdev/drivers/drv_uart.c b/bsp/ls1cdev/drivers/drv_uart.c new file mode 100644 index 0000000000..3466c07bd3 --- /dev/null +++ b/bsp/ls1cdev/drivers/drv_uart.c @@ -0,0 +1,177 @@ +/* + * File : drv_uart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-08 zhuangwei the first version + */ +#include <rtthread.h> +#include <rtdevice.h> +#include <rthw.h> +#include "drv_uart.h" +#include "ls1c_pin.h" +#include "ls1c_uart.h" + +/* STM32 uart driver */ +struct rt_uart_ls1c +{ + ls1c_uart_t UARTx; + rt_uint32_t IRQ; +}; + +static rt_err_t ls1c_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct rt_uart_ls1c *uart_dev = RT_NULL; + ls1c_uart_info_t uart_info = {0}; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data; + + // 初始化串口 + uart_info.UARTx = uart_dev->UARTx; + uart_info.baudrate = cfg->baud_rate; + uart_info.rx_enable= TRUE; + uart_init(&uart_info); + + return RT_EOK; + +} + +static rt_err_t ls1c_uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct rt_uart_ls1c *uart_dev = RT_NULL; + + RT_ASSERT(serial != RT_NULL); + uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: /* disable rx irq */ + rt_hw_interrupt_mask(uart_dev->IRQ); + break; + + case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */ + rt_hw_interrupt_umask(uart_dev->IRQ); + break; + + default: + break; + } + + return RT_EOK; + +} + +static int ls1c_uart_putc(struct rt_serial_device *serial, char c) +{ + struct rt_uart_ls1c *uart_dev = RT_NULL; + + RT_ASSERT(serial != RT_NULL); + + uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data; + uart_putc(uart_dev->UARTx, c); + + return 1; +} + +static int ls1c_uart_getc(struct rt_serial_device *serial) +{ + struct rt_uart_ls1c *uart_dev = RT_NULL; + + RT_ASSERT(serial != RT_NULL); + + uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data; + void *uart_base = uart_get_base(uart_dev->UARTx); + + if(LSR_RXRDY & reg_read_8(uart_base + LS1C_UART_LSR_OFFSET)) + { + return reg_read_8(uart_base + LS1C_UART_DAT_OFFSET); + } + + return -1; +} + +/* UART interrupt handler */ +static void uart_irq_handler(int vector, void *param) +{ + struct rt_serial_device *serial = (struct rt_serial_device*)param; + struct rt_uart_ls1c *uart_dev = RT_NULL; + + RT_ASSERT(serial != RT_NULL); + + uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data; + void *uart_base = uart_get_base(uart_dev->UARTx); + unsigned char iir = reg_read_8(uart_base + LS1C_UART_IIR_OFFSET); + + // 判断是否为接收超时或接收到有效数据 + if ((IIR_RXTOUT & iir) || (IIR_RXRDY & iir)) + { + rt_interrupt_enter(); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + rt_interrupt_leave(); + } + +} + +static const struct rt_uart_ops stm32_uart_ops = +{ + ls1c_uart_configure, + ls1c_uart_control, + ls1c_uart_putc, + ls1c_uart_getc, +}; + +#if defined(RT_USING_UART2) +struct rt_uart_ls1c uart2 = +{ + LS1C_UART2, + LS1C_UART2_IRQ, +}; +struct rt_serial_device serial2; +#endif /* RT_USING_UART1 */ + +void rt_hw_uart_init(void) +{ + struct rt_uart_ls1c *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef RT_USING_UART2 + uart = &uart2; + + serial2.ops = &stm32_uart_ops; + serial2.config = config; + + pin_set_purpose(36, PIN_PURPOSE_OTHER); + pin_set_purpose(37, PIN_PURPOSE_OTHER); + pin_set_remap(36, PIN_REMAP_SECOND); + pin_set_remap(37, PIN_REMAP_SECOND); + + rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial2, "UART2"); + + /* register UART1 device */ + rt_hw_serial_register(&serial2, + "uart2", + //RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); +#endif /* RT_USING_UART1 */ +} + diff --git a/bsp/ls1cdev/drivers/uart.h b/bsp/ls1cdev/drivers/drv_uart.h index f5f1cc0d90..0904df5b10 100644 --- a/bsp/ls1cdev/drivers/uart.h +++ b/bsp/ls1cdev/drivers/drv_uart.h @@ -1,20 +1,19 @@ /* - * File : uart.h + * File : drv_uart.h * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006-2012, RT-Thread Develop Team + * COPYRIGHT (C) 2009, 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-08 lgnq first version for LS1B - * 2015-07-06 chinesebear modified for loongson 1c + * Date Author Notes + * 2018-05-08 zhuangwei the first version */ -#ifndef __UART_H__ -#define __UART_H__ +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ #include "ls1c.h" @@ -100,4 +99,5 @@ void rt_hw_uart_init(void); + #endif diff --git a/bsp/ls1cdev/drivers/net/synopGMAC.c b/bsp/ls1cdev/drivers/net/synopGMAC.c index 2b15f87eff..7e665d3964 100644 --- a/bsp/ls1cdev/drivers/net/synopGMAC.c +++ b/bsp/ls1cdev/drivers/net/synopGMAC.c @@ -860,7 +860,7 @@ void eth_rx_irq(int irqno,void *param) return; } -void rt_hw_eth_init(void) +int rt_hw_eth_init(void) { u64 base_addr = Gmac_base; struct synopGMACNetworkAdapter * synopGMACadapter; @@ -925,4 +925,9 @@ void rt_hw_eth_init(void) eth_dev.parent.eth_rx = rt_eth_rx; eth_device_init(&(eth_dev.parent), "e0"); + + return 0; } + +INIT_DEVICE_EXPORT(rt_hw_eth_init); + diff --git a/bsp/ls1cdev/drivers/net/synopGMAC.h b/bsp/ls1cdev/drivers/net/synopGMAC.h index 2988d5c4ba..d4d06e6a65 100644 --- a/bsp/ls1cdev/drivers/net/synopGMAC.h +++ b/bsp/ls1cdev/drivers/net/synopGMAC.h @@ -32,6 +32,6 @@ #include "mii.h" #include "synopGMAC_types.h" -void rt_hw_eth_init(void); +int rt_hw_eth_init(void); #endif /*__SYNOPGMAC__H*/ diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_plat.h b/bsp/ls1cdev/drivers/net/synopGMAC_plat.h index 4809598bfa..1b1283f2fc 100644 --- a/bsp/ls1cdev/drivers/net/synopGMAC_plat.h +++ b/bsp/ls1cdev/drivers/net/synopGMAC_plat.h @@ -117,8 +117,8 @@ typedef int bool; */ //sw: nothing to display -#define TR0(fmt, args...) rt_kprintf(fmt, ##args) -#define TR(fmt, args...) rt_kprintf(fmt, ##args) +#define TR0(fmt, args...) //rt_kprintf(fmt, ##args) +#define TR(fmt, args...) //rt_kprintf(fmt, ##args) //#define TR rt_kprintf //typedef int bool; diff --git a/bsp/ls1cdev/drivers/uart.c b/bsp/ls1cdev/drivers/uart.c deleted file mode 100644 index 01bb2d0f8d..0000000000 --- a/bsp/ls1cdev/drivers/uart.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * File : board.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006-2012, 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 - * 2011-08-08 lgnq first version - * 2015-07-09 chinesebear modified for loongson 1c - */ - -#include <rthw.h> -#include <rtthread.h> - -#include "uart.h" - -/** - * @addtogroup Loongson LS1B - */ - -/*@{*/ - -#if defined(RT_USING_SERIAL) && defined(RT_USING_DEVICE) - -struct rt_uart_ls1c -{ - struct rt_device parent; - - rt_uint32_t hw_base; - rt_uint32_t irq; - - /* buffer for reception */ - rt_uint8_t read_index, save_index; - rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; -}uart_device; - -static void rt_uart_irqhandler(int irqno, void *param) -{ - rt_ubase_t level; - rt_uint8_t isr; - struct rt_uart_ls1c *uart = &uart_device; - - /* read interrupt status and clear it */ - isr = UART_IIR(uart->hw_base); - isr = (isr >> 1) & 0x3; - - /* receive data available */ - if (isr & 0x02) - { - /* Receive Data Available */ - while (UART_LSR(uart->hw_base) & UARTLSR_DR) - { - uart->rx_buffer[uart->save_index] = UART_DAT(uart->hw_base); - - level = rt_hw_interrupt_disable(); - uart->save_index ++; - if (uart->save_index >= RT_UART_RX_BUFFER_SIZE) - uart->save_index = 0; - rt_hw_interrupt_enable(level); - } - - /* invoke callback */ - if (uart->parent.rx_indicate != RT_NULL) - { - rt_size_t length; - if (uart->read_index > uart->save_index) - length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index; - else - length = uart->save_index - uart->read_index; - - uart->parent.rx_indicate(&uart->parent, length); - } - } - - return; -} - -static rt_err_t rt_uart_init(rt_device_t dev) -{ - rt_uint32_t baud_div; - struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev; - - RT_ASSERT(uart != RT_NULL); - -//#if 0 - /* init UART Hardware */ - UART_IER(uart->hw_base) = 0; /* clear interrupt */ - UART_FCR(uart->hw_base) = 0xc3; /* reset UART Rx/Tx */ - - /* enable UART clock */ - /* set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ - UART_LCR(uart->hw_base) = 0x80; - - /* set baudrate */ - baud_div = DEV_CLK / 16 / UART_BAUDRATE /2; - - UART_MSB(uart->hw_base) = (baud_div >> 8) & 0xff; - UART_LSB(uart->hw_base) = baud_div & 0xff; - - UART_LCR(uart->hw_base) = 0x03; - - /* Enable UART unit, enable and clear FIFO */ - //UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS; - - /* enable RX interrupt */ - UART_IER(uart->hw_base) = UARTIER_IRXE|UARTIER_ILE; - -//#endif - - return RT_EOK; -} - -static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag) -{ - struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev; - - RT_ASSERT(uart != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* Enable the UART Interrupt */ - UART_IER(uart->hw_base) |= UARTIER_IRXE; - - /* install interrupt */ - rt_hw_interrupt_install(uart->irq, rt_uart_irqhandler, RT_NULL, "UART"); - rt_hw_interrupt_umask(uart->irq); - } - return RT_EOK; -} - -static rt_err_t rt_uart_close(rt_device_t dev) -{ - struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev; - - RT_ASSERT(uart != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* Disable the UART Interrupt */ - UART_IER(uart->hw_base) &= ~(UARTIER_IRXE); - } - - return RT_EOK; -} - -static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - rt_uint8_t *ptr; - struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev; - - RT_ASSERT(uart != RT_NULL); - - /* point to buffer */ - ptr = (rt_uint8_t *)buffer; - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - while (size) - { - /* interrupt receive */ - rt_base_t level; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - if (uart->read_index != uart->save_index) - { - *ptr = uart->rx_buffer[uart->read_index]; - - uart->read_index ++; - if (uart->read_index >= RT_UART_RX_BUFFER_SIZE) - uart->read_index = 0; - } - else - { - /* no data in rx buffer */ - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - break; - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - ptr ++; - size --; - } - - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; - } - - return 0; -} - -static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - char *ptr; - struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev; - - RT_ASSERT(uart != RT_NULL); - - ptr = (char *)buffer; - - if (dev->flag & RT_DEVICE_FLAG_STREAM) - { - /* stream mode */ - while (size) - { - if (*ptr == '\n') - { - /* FIFO status, contain valid data */ - while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); - /* write data */ - UART_DAT(uart->hw_base) = '\r'; - } - - /* FIFO status, contain valid data */ - while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); - /* write data */ - UART_DAT(uart->hw_base) = *ptr; - - ptr ++; - size --; - } - } - else - { - while (size != 0) - { - /* FIFO status, contain valid data */ - while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); - - /* write data */ - UART_DAT(uart->hw_base) = *ptr; - - ptr++; - size--; - } - } - - return (rt_size_t)ptr - (rt_size_t)buffer; -} - -void rt_hw_uart_init(void) -{ - struct rt_uart_ls1c *uart; - - /* get uart device */ - uart = &uart_device; - - /* device initialization */ - uart->parent.type = RT_Device_Class_Char; - rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer)); - uart->read_index = uart->save_index = 0; - -#if defined(RT_USING_UART0) - uart->hw_base = UART0_BASE; - uart->irq = LS1C_UART0_IRQ; -#elif defined(RT_USING_UART2) - uart->hw_base = UART2_BASE; - uart->irq = LS1C_UART2_IRQ; -#elif defined(RT_USING_UART3) - uart->hw_base = UART3_BASE; - uart->irq = LS1C_UART3_IRQ; -#endif - - /* device interface */ - uart->parent.init = rt_uart_init; - uart->parent.open = rt_uart_open; - uart->parent.close = rt_uart_close; - uart->parent.read = rt_uart_read; - uart->parent.write = rt_uart_write; - uart->parent.control = RT_NULL; - uart->parent.user_data = RT_NULL; - - rt_device_register(&uart->parent, "uart2", - RT_DEVICE_FLAG_RDWR | - RT_DEVICE_FLAG_STREAM | - RT_DEVICE_FLAG_INT_RX); -} -#endif /* end of UART */ - - - -/*@}*/ |
