diff --git a/bsp/ls1cdev/.config b/bsp/ls1cdev/.config new file mode 100644 index 0000000000..d7ee691625 --- /dev/null +++ b/bsp/ls1cdev/.config @@ -0,0 +1,287 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=10 +CONFIG_RT_ALIGN_SIZE=8 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_DEBUG=y +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_DEBUG_INIT=0 +CONFIG_RT_DEBUG_THREAD=0 +CONFIG_RT_USING_HOOK=y +CONFIG_IDLE_THREAD_STACK_SIZE=1024 +# CONFIG_RT_USING_TIMER_SOFT is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_MEMHEAP=y +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart2" +# CONFIG_RT_USING_MODULE is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +# CONFIG_RT_USING_USER_MAIN is not set + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_USING_DESCRIPTION=y +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_CMD_SIZE=80 +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_USING_MSH_DEFAULT=y +# CONFIG_FINSH_USING_MSH_ONLY is not set + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=2 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 +CONFIG_DFS_FD_MAX=4 +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# elm-chan's FatFs, Generic FAT Filesystem Module +# +CONFIG_RT_DFS_ELM_CODE_PAGE=936 +CONFIG_RT_DFS_ELM_WORD_ACCESS=y +CONFIG_RT_DFS_ELM_USE_LFN_0=y +# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set +CONFIG_RT_DFS_ELM_USE_LFN=0 +CONFIG_RT_DFS_ELM_MAX_LFN=64 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +CONFIG_RT_DFS_ELM_REENTRANT=y +# CONFIG_RT_USING_DFS_DEVFS is not set +# CONFIG_RT_USING_DFS_NET is not set +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_UFFS is not set +# CONFIG_RT_USING_DFS_JFFS2 is not set +# CONFIG_RT_USING_DFS_NFS is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_CAN=y +CONFIG_RT_CAN_USING_HDR=y +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +CONFIG_RT_USING_I2C_BITOPS=y +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +CONFIG_RT_USING_SPI=y +CONFIG_RT_USING_SPI_MSD=y +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_W25QXX is not set +# CONFIG_RT_USING_GD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +CONFIG_RT_USING_LIBC=y +CONFIG_RT_USING_PTHREADS=y +# CONFIG_RT_USING_POSIX is not set +# CONFIG_HAVE_SYS_SIGNALS is not set + +# +# Network stack +# + +# +# light weight TCP/IP stack +# +CONFIG_RT_USING_LWIP=y +CONFIG_RT_USING_LWIP141=y +# CONFIG_RT_USING_LWIP202 is not set +CONFIG_RT_LWIP_IGMP=y +CONFIG_RT_LWIP_ICMP=y +# CONFIG_RT_LWIP_SNMP is not set +CONFIG_RT_LWIP_DNS=y +# CONFIG_RT_LWIP_DHCP is not set + +# +# Static IPv4 Address +# +CONFIG_RT_LWIP_IPADDR="192.168.1.254" +CONFIG_RT_LWIP_GWADDR="192.168.1.1" +CONFIG_RT_LWIP_MSKADDR="255.255.255.0" +CONFIG_RT_LWIP_UDP=y +CONFIG_RT_LWIP_TCP=y +# CONFIG_RT_LWIP_RAW is not set +# CONFIG_RT_LWIP_PPP is not set +CONFIG_RT_MEMP_NUM_NETCONN=8 +CONFIG_RT_LWIP_PBUF_NUM=4 +CONFIG_RT_LWIP_RAW_PCB_NUM=4 +CONFIG_RT_LWIP_UDP_PCB_NUM=4 +CONFIG_RT_LWIP_TCP_PCB_NUM=3 +CONFIG_RT_LWIP_TCP_SEG_NUM=40 +CONFIG_RT_LWIP_TCP_SND_BUF=4096 +CONFIG_RT_LWIP_TCP_WND=2048 +CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=12 +CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8 +CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=4096 +CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=14 +CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=512 +CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8 +# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set +CONFIG_LWIP_NETIF_STATUS_CALLBACK=1 +CONFIG_SO_REUSE=1 +CONFIG_LWIP_SO_RCVTIMEO=1 +CONFIG_LWIP_SO_SNDTIMEO=1 +CONFIG_LWIP_SO_RCVBUF=1 +# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=0 + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set +# CONFIG_LWIP_USING_DHCPD is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_LOGTRACE is not set +# CONFIG_RT_USING_RYM is not set + +# +# RT-Thread online packages +# + +# +# system packages +# +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set + +# +# language packages +# +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_RT_USING_UART2=y +CONFIG_RT_UART_RX_BUFFER_SIZE=64 +CONFIG_RT_USING_GMAC_INT_MODE=y +CONFIG_RT_USING_FPU=y +CONFIG_RT_USING_SPI0=y +CONFIG_RT_USING_SPI1=y +CONFIG_RT_USING_I2C1=y +CONFIG_RT_USING_I2C2=y +CONFIG_USING_BXCAN0=y +CONFIG_USING_BXCAN1=y diff --git a/bsp/ls1cdev/applications/application.c b/bsp/ls1cdev/applications/application.c index 97f3f5d7a5..d4be2e4b59 100644 --- a/bsp/ls1cdev/applications/application.c +++ b/bsp/ls1cdev/applications/application.c @@ -12,6 +12,7 @@ * 2010-06-25 Bernard first version * 2011-08-08 lgnq modified for Loongson LS1B * 2015-07-06 chinesebear modified for Loongson LS1C + * 2018-02-08 sundm75 modified for Loongson LS1C SmartLoongV3 */ #include @@ -20,23 +21,41 @@ void rt_init_thread_entry(void *parameter) { - /* initialization RT-Thread Components */ - rt_components_init(); +#ifdef RT_USING_COMPONENTS_INIT + /* initialization RT-Thread Components */ + rt_components_init(); +#endif +#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) + /* mount sd card fat partition 1 as root directory */ + if( dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + rt_kprintf("File System initialized!\n"); + } + else + { + rt_kprintf("File System initialzation failed!\n"); + } +#endif /* RT_USING_DFS && RT_USING_DFS_ELMFAT */ + +/*网口EMAC初始化*/ + rt_hw_eth_init(); +#if defined(RT_USING_RTGUI) +/*触摸屏使用SPI总线SPI1 CS0 初始化*/ + rtgui_touch_hw_init("spi10"); +#endif - // EMACʼ - rt_hw_eth_init(); } int rt_application_init(void) { - rt_thread_t tid; + rt_thread_t tid; - /* create initialization thread */ - tid = rt_thread_create("init", - rt_init_thread_entry, RT_NULL, - 4096, RT_THREAD_PRIORITY_MAX/3, 20); - if (tid != RT_NULL) - rt_thread_startup(tid); + /* create initialization thread */ + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 4096, RT_THREAD_PRIORITY_MAX/3, 20); + if (tid != RT_NULL) + rt_thread_startup(tid); - return 0; + return 0; } diff --git a/bsp/ls1cdev/drivers/SConscript b/bsp/ls1cdev/drivers/SConscript index 3e76809efb..2363e655a8 100644 --- a/bsp/ls1cdev/drivers/SConscript +++ b/bsp/ls1cdev/drivers/SConscript @@ -5,6 +5,10 @@ src = Glob('*.c') CPPPATH = [cwd] + +if GetDepend('RT_USING_RTGUI') == False: + SrcRemove(src, 'touch.c') + group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) objs = [] diff --git a/bsp/ls1cdev/drivers/board.c b/bsp/ls1cdev/drivers/board.c index cb5fbdae09..1b22741140 100644 --- a/bsp/ls1cdev/drivers/board.c +++ b/bsp/ls1cdev/drivers/board.c @@ -60,12 +60,12 @@ void rt_hw_fpu_init(void) rt_uint32_t c0_status = 0; rt_uint32_t c1_status = 0; - // ʹЭ1--FPU + // 使能协处理器1--FPU c0_status = read_c0_status(); c0_status |= (ST0_CU1 | ST0_FR); write_c0_status(c0_status); - // FPU + // 配置FPU c1_status = read_c1_status(); c1_status |= (FPU_CSR_FS | FPU_CSR_FO | FPU_CSR_FN); // set FS, FO, FN c1_status &= ~(FPU_CSR_ALL_E); // disable exception @@ -81,25 +81,28 @@ void rt_hw_fpu_init(void) */ void rt_hw_board_init(void) { -#ifdef RT_USING_UART +#ifdef RT_USING_SERIAL /* init hardware UART device */ rt_hw_uart_init(); #endif #ifdef RT_USING_CONSOLE /* set console device */ - rt_console_set_device("uart2"); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif - - /* init operating system timer */ - rt_hw_timer_init(); + /* init operating system timer */ + rt_hw_timer_init(); #ifdef RT_USING_FPU /* init hardware fpu */ rt_hw_fpu_init(); #endif - rt_kprintf("current sr: 0x%08x\n", read_c0_status()); +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + + rt_kprintf("current sr: 0x%08x\n", read_c0_status()); } #define __raw_out_put(unr) \ diff --git a/bsp/ls1cdev/drivers/display_controller.c b/bsp/ls1cdev/drivers/display_controller.c new file mode 100644 index 0000000000..a09fe0269f --- /dev/null +++ b/bsp/ls1cdev/drivers/display_controller.c @@ -0,0 +1,263 @@ +/* + * File :display_controller.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, 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 + * 2011-08-09 lgnq first version for LS1B DC + * 2015-07-06 chinesebear modified for loongson 1c + * 2018-01-06 sundm75 modified for smartloong + */ + +#include +#include "display_controller.h" +#include "../../libraries/ls1c_pwm.h" +#include "../../libraries/ls1c_public.h" +#include "../../libraries/ls1c_gpio.h" +#include "../../libraries/ls1c_pin.h" + +#ifdef RT_USING_RTGUI + +struct vga_struct vga_mode[] = +{ + {/*"480x272_60.00"*/ 111000, 480, 482, 523, 525, 272, 274, 284, 286, }, + {/*"640x480_70.00"*/ 28560, 640, 664, 728, 816, 480, 481, 484, 500, }, + {/*"640x640_60.00"*/ 33100, 640, 672, 736, 832, 640, 641, 644, 663, }, + {/*"640x768_60.00"*/ 39690, 640, 672, 736, 832, 768, 769, 772, 795, }, + {/*"640x800_60.00"*/ 42130, 640, 680, 744, 848, 800, 801, 804, 828, }, + {/*"800x480_70.00"*/ 35840, 800, 832, 912, 1024, 480, 481, 484, 500, }, + {/*"800x600_60.00"*/ 38220, 800, 832, 912, 1024, 600, 601, 604, 622, }, + {/*"800x640_60.00"*/ 40730, 800, 832, 912, 1024, 640, 641, 644, 663, }, + {/*"832x600_60.00"*/ 40010, 832, 864, 952, 1072, 600, 601, 604, 622, }, + {/*"832x608_60.00"*/ 40520, 832, 864, 952, 1072, 608, 609, 612, 630, }, + {/*"1024x480_60.00"*/ 38170, 1024, 1048, 1152, 1280, 480, 481, 484, 497, }, + {/*"1024x600_60.00"*/ 48960, 1024, 1064, 1168, 1312, 600, 601, 604, 622, }, + {/*"1024x640_60.00"*/ 52830, 1024, 1072, 1176, 1328, 640, 641, 644, 663, }, + {/*"1024x768_60.00"*/ 64110, 1024, 1080, 1184, 1344, 768, 769, 772, 795, }, + {/*"1152x764_60.00"*/ 71380, 1152, 1208, 1328, 1504, 764, 765, 768, 791, }, + {/*"1280x800_60.00"*/ 83460, 1280, 1344, 1480, 1680, 800, 801, 804, 828, }, + {/*"1280x1024_55.00"*/ 98600, 1280, 1352, 1488, 1696, 1024, 1025, 1028, 1057, }, + {/*"1440x800_60.00"*/ 93800, 1440, 1512, 1664, 1888, 800, 801, 804, 828, }, + {/*"1440x900_67.00"*/ 120280, 1440, 1528, 1680, 1920, 900, 901, 904, 935, }, +}; + +ALIGN(16) +volatile rt_uint16_t _rt_framebuffer[FB_YSIZE][FB_XSIZE]; +static struct rt_device_graphic_info _dc_info; + +static void pwminit(void) +{ + pwm_info_t pwm_info; + pwm_info.gpio = LS1C_PWM0_GPIO06; // pwm引脚位gpio06 + pwm_info.mode = PWM_MODE_NORMAL; // 正常模式--连续输出pwm波形 + pwm_info.duty = 0.85; // pwm占空比 85% + pwm_info.period_ns = 5*1000*1000; // pwm周期5ms + + /*pwm初始化,初始化后立即产生pwm波形*/ + pwm_init(&pwm_info); + + /* 使能pwm */ + pwm_enable(&pwm_info); +} +int caclulate_freq(rt_uint32_t XIN, rt_uint32_t PCLK) +{ + rt_uint32_t divider_int; + rt_uint32_t needed_pixclk; + rt_uint32_t pll_clk, pix_div; + rt_uint32_t regval; + + + pll_clk = PLL_FREQ; // 读CPU的 PLL及SDRAM 分频系数 + pll_clk =( pll_clk>>8 )& 0xff; + pll_clk = XIN * pll_clk / 4 ; + pix_div = PLL_DIV_PARAM;//读CPU的 CPU/CAMERA/DC 分频系数 + pix_div = (pix_div>>24)&0xff; + rt_kprintf("old pll_clk=%d, pix_div=%d\n", pll_clk, pix_div); + + divider_int = pll_clk/(1000000) *PCLK/1000; + if(divider_int%1000>=500) + divider_int = divider_int/1000+1; + else + divider_int = divider_int/1000; + rt_kprintf("divider_int = %d\n", divider_int); + + /* check whether divisor is too small. */ + if (divider_int < 1) { + rt_kprintf("Warning: clock source is too slow.Try smaller resolution\n"); + divider_int = 1; + } + else if(divider_int > 100) { + rt_kprintf("Warning: clock source is too fast.Try smaller resolution\n"); + divider_int = 100; + } + /* 配置分频寄存器 */ + { + rt_uint32_t regval = 0; + regval = PLL_DIV_PARAM; + /*首先需要把分频使能位清零 */ + regval &= ~0x80000030; //PIX_DIV_VALID PIX_SEL 置0 + regval &= ~(0x3f<<24); //PIX_DIV 清零 + regval |= divider_int << 24; + PLL_DIV_PARAM = regval; + regval |= 0x80000030; //PIX_DIV_VALID PIX_SEL 置1 + PLL_DIV_PARAM = regval; + } + rt_kprintf("new PLL_FREQ=0x%x, PLL_DIV_PARAM=0x%x\n", PLL_FREQ, PLL_DIV_PARAM); + rt_thread_delay(10); + return 0; +} + +static rt_err_t rt_dc_init(rt_device_t dev) +{ + int i, out, mode=-1; + int val; + + rt_kprintf("PWM initied\n"); + /* Set the back light PWM. */ + pwminit(); + + for (i=0; itype = RT_Device_Class_Graphic; + dc->init = rt_dc_init; + dc->open = RT_NULL; + dc->close = RT_NULL; + dc->control = rt_dc_control; + dc->user_data = (void*)&_dc_info; + + /* register Display Controller device to RT-Thread */ + rt_device_register(dc, "dc", RT_DEVICE_FLAG_RDWR); + + rt_device_init(dc); +} + +#include +#include "display_controller.h" + +/* initialize for gui driver */ +int rtgui_lcd_init(void) +{ + rt_device_t dc; + rt_kprintf("DC initied\n"); + + pin_set_purpose(76, PIN_PURPOSE_OTHER); + pin_set_remap(76, PIN_REMAP_DEFAULT); + + /* init Display Controller */ + rt_hw_dc_init(); + + /* find Display Controller device */ + dc = rt_device_find("dc"); + + /* set Display Controller device as rtgui graphic driver */ + rtgui_graphic_set_device(dc); + + return 0; +} + +INIT_DEVICE_EXPORT(rtgui_lcd_init); + +#endif diff --git a/bsp/ls1cdev/drivers/display_controller.h b/bsp/ls1cdev/drivers/display_controller.h new file mode 100644 index 0000000000..ad252a9c2f --- /dev/null +++ b/bsp/ls1cdev/drivers/display_controller.h @@ -0,0 +1,59 @@ +/* + * File : display_controller.h + * 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 for LS1B + * 2015-07-06 chinesebear modified for loongson 1c + * 2018-01-06 sundm75 modified for smartloong +*/ + +#ifndef __DISPLAY_CONTROLLER_H__ +#define __DISPLAY_CONTROLLER_H__ + +#include +#include "ls1c.h" + +#define DC_BASE 0xBC301240 //Display Controller + +/* Frame Buffer registers */ +#define DC_FB_CONFIG __REG32(DC_BASE + 0x000) +#define DC_FB_BUFFER_ADDR0 __REG32(DC_BASE + 0x020) +#define DC_FB_BUFFER_STRIDE __REG32(DC_BASE + 0x040) +#define DC_FB_BUFFER_ORIGIN __REG32(DC_BASE + 0x060) +#define DC_DITHER_CONFIG __REG32(DC_BASE + 0x120) +#define DC_DITHER_TABLE_LOW __REG32(DC_BASE + 0x140) +#define DC_DITHER_TABLE_HIGH __REG32(DC_BASE + 0x160) +#define DC_PANEL_CONFIG __REG32(DC_BASE + 0x180) +#define DC_PANEL_TIMING __REG32(DC_BASE + 0x1A0) +#define DC_HDISPLAY __REG32(DC_BASE + 0x1C0) +#define DC_HSYNC __REG32(DC_BASE + 0x1E0) +#define DC_VDISPLAY __REG32(DC_BASE + 0x240) +#define DC_VSYNC __REG32(DC_BASE + 0x260) +#define DC_FB_BUFFER_ADDR1 __REG32(DC_BASE + 0x340) + +/* Display Controller driver for 1024x768 16bit */ +#define FB_XSIZE 480 +#define FB_YSIZE 272 +#define CONFIG_VIDEO_16BPP + +#define OSC 24000000 /* Hz */ + +#define K1BASE 0xA0000000 +#define KSEG1(addr) ((void *)(K1BASE | (rt_uint32_t)(addr))) +#define HW_FB_ADDR KSEG1(_rt_framebuffer) + +struct vga_struct +{ + long pclk; + int hr,hss,hse,hfl; + int vr,vss,vse,vfl; +}; + +#endif diff --git a/bsp/ls1cdev/drivers/drv_can.c b/bsp/ls1cdev/drivers/drv_can.c new file mode 100644 index 0000000000..92095d0669 --- /dev/null +++ b/bsp/ls1cdev/drivers/drv_can.c @@ -0,0 +1,541 @@ +/* + * File : drv_can.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2018, 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-01-06 sundm75 first version + */ + +#include +#include +#include +#include + +#include + +#include "ls1c.h" +#include "../libraries/ls1c_public.h" +#include "../libraries/ls1c_regs.h" +#include "../libraries/ls1c_clock.h" +#include "../libraries/ls1c_can.h" +#include "../libraries/ls1c_pin.h" + + +#ifdef RT_USING_CAN + +CanRxMsg RxMessage; + +struct ls1c_bxcan +{ + CAN_TypeDef *reg; + void * irq; +}; + +static rt_err_t bxmodifyfilter(struct ls1c_bxcan *pbxcan, struct rt_can_filter_item *pitem, rt_uint32_t actived) +{ + rt_int32_t fcase; + rt_err_t res; + rt_int32_t hdr, fbase, foff; + CAN_TypeDef* CANx; + CANx = pbxcan->reg; + + /*pitem->mode 1-掩码模式; 0- 滤波器模式 SJA1000中使用以下方式*/ + /*SJA1000中AFM 1-单滤波器模式; 0- 双滤波器模式 */ + + fcase = pitem->mode;/*1-单滤波器模式; 0- 双滤波器模式*/ + { + if (!actived) + { + return RT_EOK; + } + else if (pitem->hdr == -1) + { + res = -1; + if (res != RT_EOK) + { + return res; + } + } + else if (pitem->hdr >= 0) + { + rt_enter_critical(); + res = RT_EOK; + if (res != RT_EOK) + { + return res; + } + hdr = pitem->hdr; + rt_exit_critical(); + } + } + + CAN_FilterInitTypeDef CAN_FilterInitStruct; + unsigned char ide, rtr, id , idmask, mode; + ide = (unsigned char) pitem->ide; + rtr = (unsigned char) pitem->rtr; + id = pitem->id; + idmask = pitem->mask; + mode = (unsigned char) pitem->mode; + CAN_FilterInitStruct.IDE = ide; + CAN_FilterInitStruct.RTR = rtr; + CAN_FilterInitStruct.ID = id; + CAN_FilterInitStruct.IDMASK = idmask; + CAN_FilterInitStruct.MODE = mode; + CAN_FilterInit(CANx, &CAN_FilterInitStruct); + + return RT_EOK; +} + +static rt_err_t setfilter(struct ls1c_bxcan *pbxcan, struct rt_can_filter_config *pconfig) +{ + struct rt_can_filter_item *pitem = pconfig->items; + rt_uint32_t count = pconfig->count; + rt_err_t res; + while (count) + { + res = bxmodifyfilter(pbxcan, pitem, pconfig->actived); + if (res != RT_EOK) + { + return res; + } + pitem++; + count--; + } + return RT_EOK; +} +static void bxcan0_filter_init(struct rt_can_device *can) +{ + struct ls1c_bxcan *pbxcan; + pbxcan = (struct ls1c_bxcan *) can->parent.user_data; + +} + +static void bxcan1_filter_init(struct rt_can_device *can) +{ + struct ls1c_bxcan *pbxcan; + pbxcan = (struct ls1c_bxcan *) can->parent.user_data; + +} + +static void bxcan_init(CAN_TypeDef *pcan, rt_uint32_t baud, rt_uint32_t mode) +{ + CAN_InitTypeDef CAN_InitStructure; + + Ls1c_CanBPS_t bps ; + + switch(baud) + { + case CAN1MBaud: + bps = LS1C_CAN1MBaud; + break; + case CAN800kBaud: + bps = LS1C_CAN800kBaud; + break; + case CAN500kBaud: + bps = LS1C_CAN500kBaud; + break; + case CAN250kBaud: + bps = LS1C_CAN250kBaud; + break; + case CAN125kBaud: + bps = LS1C_CAN125kBaud; + break; + case CAN50kBaud: + bps = LS1C_CAN40kBaud; + break; + default: + bps = LS1C_CAN250kBaud; + break; + } + + switch (mode) + { + case RT_CAN_MODE_NORMAL: + CAN_InitStructure.CAN_Mode = 0x00; + break; + case RT_CAN_MODE_LISEN: + CAN_InitStructure.CAN_Mode = CAN_Mode_LOM; + break; + case RT_CAN_MODE_LOOPBACK: + CAN_InitStructure.CAN_Mode = CAN_Mode_STM; + + break; + case RT_CAN_MODE_LOOPBACKANLISEN: + CAN_InitStructure.CAN_Mode = CAN_Mode_STM|CAN_Mode_LOM; + break; + } + CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; + + switch (bps) + { + case LS1C_CAN1MBaud: + CAN_InitStructure.CAN_Prescaler = 9; + CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN800kBaud: + CAN_InitStructure.CAN_Prescaler = 8; + CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN500kBaud: + CAN_InitStructure.CAN_Prescaler = 9; + CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN250kBaud: + CAN_InitStructure.CAN_Prescaler = 36; + CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN125kBaud: + CAN_InitStructure.CAN_Prescaler = 36; + CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN100kBaud: + CAN_InitStructure.CAN_Prescaler = 63; + CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN50kBaud: + CAN_InitStructure.CAN_Prescaler = 63; + CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; + break; + default: //250K + CAN_InitStructure.CAN_Prescaler = 36; + CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; + CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; + break; + } + + CAN_Init(pcan, &CAN_InitStructure); +} + +#ifdef USING_BXCAN0 +static void bxcan0_hw_init(void) +{ + pin_set_purpose(54, PIN_PURPOSE_OTHER); + pin_set_purpose(55, PIN_PURPOSE_OTHER); + pin_set_remap(54, PIN_REMAP_THIRD); + pin_set_remap(55, PIN_REMAP_THIRD); +} +#endif + +#ifdef USING_BXCAN1 +static void bxcan1_hw_init(void) +{ + pin_set_purpose(56, PIN_PURPOSE_GPIO); + pin_set_purpose(57, PIN_PURPOSE_GPIO); + pin_set_remap(56, PIN_REMAP_DEFAULT); + pin_set_remap(57, PIN_REMAP_DEFAULT); +} +#endif + + +static rt_err_t configure(struct rt_can_device *can, struct can_configure *cfg) +{ + CAN_TypeDef *pbxcan; + + pbxcan = ((struct ls1c_bxcan *) can->parent.user_data)->reg; + if (pbxcan == CAN0) + { +#ifdef USING_BXCAN0 + bxcan0_hw_init(); + bxcan_init(pbxcan, cfg->baud_rate, cfg->mode); +#endif + } + else if (pbxcan == CAN1) + { +#ifdef USING_BXCAN1 + bxcan1_hw_init(); + bxcan_init(pbxcan, cfg->baud_rate, cfg->mode); +#endif + } + return RT_EOK; +} + +static rt_err_t control(struct rt_can_device *can, int cmd, void *arg) +{ + struct ls1c_bxcan *pbxcan; + rt_uint32_t argval; + + pbxcan = (struct ls1c_bxcan *) can->parent.user_data; + switch (cmd) + { + case RT_CAN_CMD_SET_FILTER: + return setfilter(pbxcan, (struct rt_can_filter_config *) arg); + break; + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_NORMAL || + argval != RT_CAN_MODE_LISEN || + argval != RT_CAN_MODE_LOOPBACK || + argval != RT_CAN_MODE_LOOPBACKANLISEN) + { + return RT_ERROR; + } + if (argval != can->config.mode) + { + can->config.mode = argval; + return CAN_SetMode(pbxcan->reg, argval); + } + break; + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + if (argval != CAN1MBaud && + argval != CAN800kBaud && + argval != CAN500kBaud && + argval != CAN250kBaud && + argval != CAN125kBaud && + argval != CAN100kBaud && + argval != CAN50kBaud ) + { + return RT_ERROR; + } + if (argval != can->config.baud_rate) + { + can->config.baud_rate = argval; + Ls1c_CanBPS_t bps; + switch(argval) + { + case CAN1MBaud: + bps = LS1C_CAN1MBaud; + break; + case CAN800kBaud: + bps = LS1C_CAN800kBaud; + break; + case CAN500kBaud: + bps = LS1C_CAN500kBaud; + break; + case CAN250kBaud: + bps = LS1C_CAN250kBaud; + break; + case CAN125kBaud: + bps = LS1C_CAN125kBaud; + break; + case CAN50kBaud: + bps = LS1C_CAN40kBaud; + break; + default: + bps = LS1C_CAN250kBaud; + break; + } + return CAN_SetBps( pbxcan->reg, bps); + } + break; + case RT_CAN_CMD_GET_STATUS: + { + rt_uint32_t errtype; + + errtype = pbxcan->reg->RXERR; + can->status.rcverrcnt = errtype ; + errtype = pbxcan->reg->TXERR; + can->status.snderrcnt = errtype ; + errtype = pbxcan->reg->ECC; + can->status.errcode = errtype ; + if (arg != &can->status) + { + rt_memcpy(arg, &can->status, sizeof(can->status)); + } + } + break; + } + + return RT_EOK; +} + +static int sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno) +{ + CAN_TypeDef *pbxcan; + CanTxMsg TxMessage; + struct rt_can_msg *pmsg = (struct rt_can_msg *) buf; + int i; + + pbxcan = ((struct ls1c_bxcan *) can->parent.user_data)->reg; + + TxMessage.StdId = pmsg->id; + TxMessage.ExtId = pmsg->id; + TxMessage.RTR = pmsg->rtr; + TxMessage.IDE = pmsg->ide; + TxMessage.DLC = pmsg->len; + for( i=0; idata[i]; + } + CAN_Transmit(pbxcan, &TxMessage); + + return RT_EOK; +} + +static int recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno) +{ + CAN_TypeDef *pbxcan; + + struct rt_can_msg *pmsg = (struct rt_can_msg *) buf; + int i; + + pbxcan = ((struct ls1c_bxcan *) can->parent.user_data)->reg; + + pmsg->ide = (rt_uint32_t) RxMessage.IDE; + if(RxMessage.IDE == 1) + pmsg->id = RxMessage.ExtId; + else + pmsg->id = RxMessage.StdId; + pmsg->len = RxMessage.DLC; + pmsg->rtr = RxMessage.RTR; + pmsg->hdr = 0; + for(i= 0;i< RxMessage.DLC; i++) + { + pmsg->data[i] = RxMessage.Data[i]; + } + return RT_EOK; +} + +static const struct rt_can_ops canops = +{ + configure, + control, + sendmsg, + recvmsg, +}; + +#ifdef USING_BXCAN0 +struct rt_can_device bxcan0; +void ls1c_can0_irqhandler(int irq, void *param) +{ + CAN_TypeDef* CANx; + unsigned char status; + CANx = CAN0; + /*读寄存器清除中断*/ + status = CANx->IR; + + /*接收中断*/ + if (( status & CAN_IR_RI) == CAN_IR_RI) + { + /*清除RI 中断*/ + CAN_Receive(CANx, &RxMessage); + CANx->CMR |= CAN_CMR_RRB; + CANx->CMR |= CAN_CMR_CDO; + rt_hw_can_isr(&bxcan0, RT_CAN_EVENT_RX_IND); + rt_kprintf("\r\nCan0 int RX happened!\r\n"); + } + /*发送中断*/ + else if (( status & CAN_IR_TI) == CAN_IR_TI) + { + rt_hw_can_isr(&bxcan0, RT_CAN_EVENT_TX_DONE | 0 << 8); + rt_kprintf("\r\nCan0 int TX happened!\r\n"); + } + /*数据溢出中断*/ + else if (( status & CAN_IR_TI) == CAN_IR_DOI) + { + rt_hw_can_isr(&bxcan0, RT_CAN_EVENT_RXOF_IND); + rt_kprintf("\r\nCan0 int RX OF happened!\r\n"); + } +} +static struct ls1c_bxcan bxcan0data = +{ + .reg = CAN0, + .irq = ls1c_can0_irqhandler, +}; +#endif /*USING_BXCAN0*/ + +#ifdef USING_BXCAN1 +struct rt_can_device bxcan1; +void ls1c_can1_irqhandler(int irq, void *param) +{ + CAN_TypeDef* CANx; + unsigned char status; + CANx = CAN1; + /*读寄存器清除中断*/ + status = CANx->IR; + + /*接收中断*/ + if (( status & CAN_IR_RI) == CAN_IR_RI) + { + /*清除RI 中断*/ + CAN_Receive(CANx, &RxMessage); + CANx->CMR |= CAN_CMR_RRB; + CANx->CMR |= CAN_CMR_CDO; + rt_hw_can_isr(&bxcan1, RT_CAN_EVENT_RX_IND); + rt_kprintf("\r\nCan1 int RX happened!\r\n"); + } + /*发送中断*/ + else if (( status & CAN_IR_TI) == CAN_IR_TI) + { + rt_hw_can_isr(&bxcan1, RT_CAN_EVENT_TX_DONE | 0 << 8); + rt_kprintf("\r\nCan1 int TX happened!\r\n"); + } + /*数据溢出中断*/ + else if (( status & CAN_IR_TI) == CAN_IR_DOI) + { + rt_hw_can_isr(&bxcan1, RT_CAN_EVENT_RXOF_IND); + rt_kprintf("\r\nCan1 int RX OF happened!\r\n"); + } +} +static struct ls1c_bxcan bxcan1data = +{ + .reg = CAN1, + .irq = ls1c_can1_irqhandler, +}; + +#endif /*USING_BXCAN1*/ + +int ls1c_bxcan_init(void) +{ + +#ifdef USING_BXCAN0 + bxcan0.config.baud_rate = CAN250kBaud; + bxcan0.config.msgboxsz = 1; + bxcan0.config.sndboxnumber = 1; + bxcan0.config.mode = RT_CAN_MODE_NORMAL; + bxcan0.config.privmode = 0; + bxcan0.config.ticks = 50; +#ifdef RT_CAN_USING_HDR + bxcan0.config.maxhdr = 2; +#endif + rt_hw_can_register(&bxcan0, "bxcan0", &canops, &bxcan0data); + rt_kprintf("\r\ncan0 register! \r\n"); + + rt_hw_interrupt_install(LS1C_CAN0_IRQ,( rt_isr_handler_t)bxcan0data.irq , RT_NULL, "can0"); + rt_hw_interrupt_umask(LS1C_CAN0_IRQ); +#endif +#ifdef USING_BXCAN1 + bxcan1.config.baud_rate = CAN250kBaud; + bxcan1.config.msgboxsz = 1; + bxcan1.config.sndboxnumber = 1; + bxcan1.config.mode = RT_CAN_MODE_NORMAL; + bxcan1.config.privmode = 0; + bxcan1.config.ticks = 50; +#ifdef RT_CAN_USING_HDR + bxcan1.config.maxhdr = 2; +#endif + rt_hw_can_register(&bxcan1, "bxcan1", &canops, &bxcan1data); + rt_kprintf("\r\ncan1 register! \r\n"); + + rt_hw_interrupt_install(LS1C_CAN1_IRQ,( rt_isr_handler_t)bxcan1data.irq , RT_NULL, "can1"); + rt_hw_interrupt_umask(LS1C_CAN1_IRQ); +#endif + return RT_EOK; +} + +INIT_BOARD_EXPORT(ls1c_bxcan_init); + +#endif /*RT_USING_CAN*/ diff --git a/bsp/ls1cdev/drivers/drv_can.h b/bsp/ls1cdev/drivers/drv_can.h new file mode 100644 index 0000000000..0d846dee25 --- /dev/null +++ b/bsp/ls1cdev/drivers/drv_can.h @@ -0,0 +1,30 @@ +/* + * File : bxcan.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2018, 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-01-06 sundm75 first version + */ + +#ifndef LS1C_DRV_CAN_H +#define LS1C_DRV_CAN_H + +extern int ls1c_bxcan_init(void); + +#endif /*DRV_CAN_H_*/ diff --git a/bsp/ls1cdev/drivers/drv_spi.c b/bsp/ls1cdev/drivers/drv_spi.c index b26de557db..900f7e4aad 100644 --- a/bsp/ls1cdev/drivers/drv_spi.c +++ b/bsp/ls1cdev/drivers/drv_spi.c @@ -25,7 +25,9 @@ #include #include #include "drv_spi.h" +#include "../libraries/ls1c_pin.h" +#ifdef RT_USING_SPI //#define DEBUG @@ -226,4 +228,66 @@ rt_err_t ls1c_spi_bus_register(rt_uint8_t SPI, const char *spi_bus_name) return rt_spi_bus_register(spi_bus, spi_bus_name, &ls1c_spi_ops); } +int ls1c_hw_spi_init(void) +{ +#ifdef RT_USING_SPI0 + pin_set_purpose(78, PIN_PURPOSE_OTHER); + pin_set_purpose(79, PIN_PURPOSE_OTHER); + pin_set_purpose(80, PIN_PURPOSE_OTHER); + pin_set_purpose(83, PIN_PURPOSE_OTHER);//cs2 - SD card + pin_set_purpose(82, PIN_PURPOSE_OTHER);//cs1 + + pin_set_remap(78, PIN_REMAP_FOURTH); + pin_set_remap(79, PIN_REMAP_FOURTH); + pin_set_remap(80, PIN_REMAP_FOURTH); + pin_set_remap(83, PIN_REMAP_FOURTH);//cs2 - SD card + pin_set_remap(82, PIN_REMAP_FOURTH);//cs1 + ls1c_spi_bus_register(LS1C_SPI_0,"spi0"); +#endif + +#ifdef RT_USING_SPI1 + pin_set_purpose(46, PIN_PURPOSE_OTHER); + pin_set_purpose(47, PIN_PURPOSE_OTHER); + pin_set_purpose(48, PIN_PURPOSE_OTHER); + pin_set_purpose(49, PIN_PURPOSE_OTHER);//CS0 - touch screen + pin_set_remap(46, PIN_REMAP_THIRD); + pin_set_remap(47, PIN_REMAP_THIRD); + pin_set_remap(48, PIN_REMAP_THIRD); + pin_set_remap(49, PIN_REMAP_THIRD);//CS0 - touch screen + ls1c_spi_bus_register(LS1C_SPI_1,"spi1"); + +#endif + + +#ifdef RT_USING_SPI0 + /* attach cs */ + { + static struct rt_spi_device spi_device1; + static struct rt_spi_device spi_device2; + static struct ls1c_spi_cs spi_cs1; + static struct ls1c_spi_cs spi_cs2; + + /* spi02: CS2 SD Card*/ + spi_cs2.cs = LS1C_SPI_CS_2; + rt_spi_bus_attach_device(&spi_device2, "spi02", "spi0", (void*)&spi_cs2); + spi_cs1.cs = LS1C_SPI_CS_1; + rt_spi_bus_attach_device(&spi_device1, "spi01", "spi0", (void*)&spi_cs1); + msd_init("sd0", "spi02"); + } +#endif +#ifdef RT_USING_SPI1 + { + static struct rt_spi_device spi_device; + static struct ls1c_spi_cs spi_cs; + + /* spi10: CS0 Touch*/ + spi_cs.cs = LS1C_SPI_CS_0; + rt_spi_bus_attach_device(&spi_device, "spi10", "spi1", (void*)&spi_cs); + } +#endif +} + +INIT_BOARD_EXPORT(ls1c_hw_spi_init); + +#endif diff --git a/bsp/ls1cdev/drivers/hw_i2c.c b/bsp/ls1cdev/drivers/hw_i2c.c new file mode 100644 index 0000000000..6d427701ed --- /dev/null +++ b/bsp/ls1cdev/drivers/hw_i2c.c @@ -0,0 +1,176 @@ +/* + * File :hw_i2c.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, 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-01-04 Sundm75 the first version + */ + +#include +#include +#include "ls1c_i2c.h" +#include "../libraries/ls1c_pin.h" + +#ifdef RT_USING_I2C + +struct ls1c_i2c_bus +{ + struct rt_i2c_bus_device parent; + rt_uint32_t u32Module; +}; + +rt_size_t rt_i2c_master_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg *msgs, + rt_uint32_t num) +{ + struct ls1c_i2c_bus * i2c_bus = (struct ls1c_i2c_bus *)bus; + ls1c_i2c_info_t i2c_info; + struct rt_i2c_msg *msg; + int i; + rt_int32_t ret = RT_EOK; + i2c_info.clock = 50000; // 50kb/s + i2c_info.I2Cx = i2c_bus->u32Module; + i2c_init(&i2c_info); + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + if (msg->flags == RT_I2C_RD) + { + i2c_send_start_and_addr(&i2c_info, msg->addr, LS1C_I2C_DIRECTION_READ); + i2c_receive_ack(&i2c_info); + i2c_receive_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len); + i2c_send_stop(&i2c_info); + } + else if(msg->flags == RT_I2C_WR) + { + i2c_send_start_and_addr(&i2c_info, msg->addr, LS1C_I2C_DIRECTION_WRITE); + i2c_receive_ack(&i2c_info); + i2c_send_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len); + i2c_send_stop(&i2c_info); + } + ret++; + } + return ret; +} + +rt_err_t rt_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t cmd, + rt_uint32_t arg) +{ + struct ls1c_i2c_bus * i2c_bus = (struct ls1c_i2c_bus *)bus; + + RT_ASSERT(bus != RT_NULL); + i2c_bus = (struct ls1c_i2c_bus *)bus->parent.user_data; + + RT_ASSERT(i2c_bus != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_CONFIG : + break; + } + + return RT_EOK; +} + +static const struct rt_i2c_bus_device_ops ls1c_i2c_ops = +{ + rt_i2c_master_xfer, + RT_NULL, + rt_i2c_bus_control +}; + + +#ifdef RT_USING_I2C0 +static struct ls1c_i2c_bus ls1c_i2c_bus_0 = +{ + {1}, + LS1C_I2C_0, +}; +#endif + +#ifdef RT_USING_I2C1 +static struct ls1c_i2c_bus ls1c_i2c_bus_1 = +{ + {1}, + LS1C_I2C_1, +}; +#endif + +#ifdef RT_USING_I2C2 +static struct ls1c_i2c_bus ls1c_i2c_bus_2 = +{ + {1}, + LS1C_I2C_2, +}; +#endif + +int ls1c_hw_i2c_init(void) +{ + struct ls1c_i2c_bus* ls1c_i2c; + +#ifdef RT_USING_I2C0 +/* + pin_set_purpose(2, PIN_PURPOSE_OTHER); + pin_set_purpose(3, PIN_PURPOSE_OTHER); + pin_set_remap(2, PIN_REMAP_SECOND); + pin_set_remap(3, PIN_REMAP_SECOND); + */ +#endif +#ifdef RT_USING_I2C1 + pin_set_purpose(2, PIN_PURPOSE_OTHER); + pin_set_purpose(3, PIN_PURPOSE_OTHER); + pin_set_remap(2, PIN_REMAP_SECOND); + pin_set_remap(3, PIN_REMAP_SECOND); +#endif +#ifdef RT_USING_I2C2 + pin_set_purpose(51, PIN_PURPOSE_OTHER); + pin_set_purpose(50, PIN_PURPOSE_OTHER); + pin_set_remap(51, PIN_REMAP_FOURTH); + pin_set_remap(50, PIN_REMAP_FOURTH); +#endif + + +#ifdef RT_USING_I2C0 + ls1c_i2c = &ls1c_i2c_bus_0; + ls1c_i2c->parent.ops = &ls1c_i2c_ops; + rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c0"); + rt_kprintf("i2c0_init!\n"); +#endif +#ifdef RT_USING_I2C1 + ls1c_i2c = &ls1c_i2c_bus_1; + ls1c_i2c->parent.ops = &ls1c_i2c_ops; + rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c1"); + rt_kprintf("i2c1_init!\n"); +#endif + +#ifdef RT_USING_I2C2 + ls1c_i2c = &ls1c_i2c_bus_2; + ls1c_i2c->parent.ops = &ls1c_i2c_ops; + rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c2"); + rt_kprintf("i2c2_init!\n"); +#endif + + return RT_EOK; +} + +INIT_BOARD_EXPORT(ls1c_hw_i2c_init); + +#endif diff --git a/bsp/ls1cdev/drivers/hw_i2c.h b/bsp/ls1cdev/drivers/hw_i2c.h new file mode 100644 index 0000000000..1bd4e991ed --- /dev/null +++ b/bsp/ls1cdev/drivers/hw_i2c.h @@ -0,0 +1,32 @@ +/* + * File : hw_i2c.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, 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-01-04 Sundm75 the first version + */ + +#ifndef LS1C_I2C_H +#define LS1C_I2C_H + +#include + +int rt_i2c_init(void); + +#endif diff --git a/bsp/ls1cdev/drivers/touch.c b/bsp/ls1cdev/drivers/touch.c new file mode 100644 index 0000000000..249e7682bf --- /dev/null +++ b/bsp/ls1cdev/drivers/touch.c @@ -0,0 +1,611 @@ +/* + * File : touch.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, 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 + * 2017-12-30 Sundm75 first version + */ + +#include +#include +#include +#include +#include "ls1c.h" +#include "ls1c_gpio.h" +#include "ls1c_spi.h" +#include "drv_spi.h" +#include "touch.h" + +#ifdef RT_USING_RTGUI + +#include +#include +#include +#include +#include + +//Ļ Ҫ _ILI_HORIZONTAL_DIRECTION_ +//Ļ Ҫ _ILI_HORIZONTAL_DIRECTION_ + +//#define _ILI_HORIZONTAL_DIRECTION_ + +#if defined(_ILI_HORIZONTAL_DIRECTION_) +#define X_WIDTH 272 +#define Y_WIDTH 480 +#else +#define X_WIDTH 480 +#define Y_WIDTH 272 +#endif +/* +TOUCH INT: 84 +*/ +#define IS_TOUCH_UP() gpio_get(TOUCH_INT_PIN) + +#define led_gpio 52 // led1ָʾ + +#define DUMMY 0x00 + +/* +7 6 - 4 3 2 1-0 +s A2-A0 MODE SER/DFR PD1-PD0 +*/ +/* bit[1:0] power-down */ +#define POWER_MODE0 (0) /* Power-Down Between Conversions. When */ + /* each conversion is finished, the converter */ + /* enters a low-power mode. At the start of the */ + /* next conversion, the device instantly powers up */ + /* to full power. There is no need for additional */ + /* delays to ensure full operation, and the very first */ + /* conversion is valid. The Y? switch is on when in */ + /* power-down.*/ +#define POWER_MODE1 (1) /* Reference is off and ADC is on. */ +#define POWER_MODE2 (2) /* Reference is on and ADC is off. */ +#define POWER_MODE3 (3) /* Device is always powered. Reference is on and */ + /* ADC is on. */ +/* bit[2] SER/DFR */ +#define DIFFERENTIAL (0<<2) +#define SINGLE_ENDED (1<<2) +/* bit[3] mode */ +#define MODE_12BIT (0<<3) +#define MODE_8BIT (1<<3) +/* bit[6:4] differential mode */ +#define MEASURE_X (((1<<2) | (0<<1) | (1<<0))<<4) +#define MEASURE_Y (((0<<2) | (0<<1) | (1<<0))<<4) +#define MEASURE_Z1 (((0<<2) | (1<<1) | (1<<0))<<4) +#define MEASURE_Z2 (((1<<2) | (0<<1) | (0<<0))<<4) +/* bit[7] start */ +#define START (1<<7) + +/* X Y change. */ +#define TOUCH_MSR_X (START | MEASURE_X | MODE_12BIT | DIFFERENTIAL | POWER_MODE0) +#define TOUCH_MSR_Y (START | MEASURE_Y | MODE_12BIT | DIFFERENTIAL | POWER_MODE0) + + +/* ¶XPT2046 Ĵλ*/ +#if defined(_ILI_HORIZONTAL_DIRECTION_) +#define MIN_X_DEFAULT 2047 +#define MAX_X_DEFAULT 47 +#define MIN_Y_DEFAULT 102 +#define MAX_Y_DEFAULT 1939 +#else +#define MIN_X_DEFAULT 47 +#define MAX_X_DEFAULT 2047 +#define MIN_Y_DEFAULT 1939 +#define MAX_Y_DEFAULT 102 +#endif + + + +#define SAMP_CNT 8 //the adc array size +#define SAMP_CNT_DIV2 4 //the middle of the adc array +#define SH 10 // Valve value + + +/*궨 */ +#define TOUCH_SPI_X SPI1 +#define TOUCH_INT_PIN 84 +#define TOUCH_CS_PIN 49 +#define TOUCH_SCK_PIN 46 +#define TOUCH_MISO_PIN 47 +#define TOUCH_MOSI_PIN 48 + + +/*ṹ彫ҪõĶд*/ +struct rtgui_touch_device +{ + struct rt_device parent; /* ע豸*/ + + rt_uint16_t x, y; /* ¼ȡλֵ */ + + rt_bool_t calibrating; /* У׼־ */ + rt_touch_calibration_func_t calibration_func;/* ָ */ + + rt_uint16_t min_x, max_x; /* У׼ X С ֵ */ + rt_uint16_t min_y, max_y; /* У׼ Y С ֵ */ + + struct rt_spi_device * spi_device; /* SPI 豸 ͨ */ + struct rt_event event; /* ¼ͬڡжϡ */ +}; +static struct rtgui_touch_device *touch = RT_NULL; + +static rt_err_t touch_send_then_recv(struct rt_spi_device *device, + const void *send_buf, + rt_size_t send_length, + void *recv_buf, + rt_size_t recv_length) +{ + rt_err_t result; + struct rt_spi_message message; + rt_uint8_t dummy[128] ; + + rt_memset(dummy, DUMMY, sizeof(dummy)); + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + + result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); + if (result == RT_EOK) + { + if (device->bus->owner != device) + { + /* not the same owner as current, re-configure SPI bus */ + result = device->bus->ops->configure(device, &device->config); + if (result == RT_EOK) + { + /* set SPI bus owner */ + device->bus->owner = device; + } + else + { + /* configure SPI bus failed */ + result = -RT_EIO; + goto __exit; + } + } + + /* send data */ + message.send_buf = send_buf; + message.recv_buf = RT_NULL; + message.length = send_length; + message.cs_take = 1; + message.cs_release = 0; + message.next = RT_NULL; + + result = device->bus->ops->xfer(device, &message); + if (result == 0) + { + result = -RT_EIO; + goto __exit; + } + + /* recv data */ + message.send_buf = dummy; + message.recv_buf = recv_buf; + message.length = recv_length; + message.cs_take = 0; + message.cs_release = 1; + message.next = RT_NULL; + + result = device->bus->ops->xfer(device, &message); + if (result == 0) + { + result = -RT_EIO; + goto __exit; + } + + result = RT_EOK; + } + else + { + return -RT_EIO; + } + +__exit: + rt_mutex_release(&(device->bus->lock)); + + return result; +} + + +static void rtgui_touch_calculate(void) +{ + if (touch != RT_NULL) + { + /* read touch */ + { + rt_uint8_t i, j, k, min; + rt_uint16_t temp; + rt_uint16_t tmpxy[2][SAMP_CNT]; + rt_uint8_t send_buffer[1]; + rt_uint8_t recv_buffer[2]; + for(i=0; ispi_device, send_buffer, 1, recv_buffer, 2); + rt_kprintf("touch x: %d ",(recv_buffer[0]*256|recv_buffer[1])>>4); +#if defined(_ILI_HORIZONTAL_DIRECTION_) + tmpxy[1][i] = (recv_buffer[0]<<8)|recv_buffer[1] ; + tmpxy[1][i] >>= 4; +#else + tmpxy[0][i] = (recv_buffer[0]<<8)|recv_buffer[1] ; + tmpxy[0][i] >>=4; + +#endif + send_buffer[0] = TOUCH_MSR_Y; + touch_send_then_recv(touch->spi_device, send_buffer, 1, recv_buffer, 2); + rt_kprintf("touch y: %d \n",(recv_buffer[0]*256|recv_buffer[1])>>4); + +#if defined(_ILI_HORIZONTAL_DIRECTION_) + tmpxy[0][i] = (recv_buffer[0]<<8)|recv_buffer[1] ; + tmpxy[0][i] >>= 4; +#else + tmpxy[1][i] = (recv_buffer[0]<<8)|recv_buffer[1] ; + tmpxy[1][i] >>= 4; +#endif + } + /*ٴδ򿪴ж*/ + send_buffer[0] = 1 << 7; + touch_send_then_recv(touch->spi_device, send_buffer, 1, recv_buffer, 2); + touch_send_then_recv(touch->spi_device, send_buffer, 1, recv_buffer, 2); + /* calculate average */ + { + rt_uint32_t total_x = 0; + rt_uint32_t total_y = 0; + for(k=0; k<2; k++) + { + // sorting the ADC value + for(i=0; i tmpxy[k][j]) + min=j; + } + temp = tmpxy[k][i]; + tmpxy[k][i] = tmpxy[k][min]; + tmpxy[k][min] = temp; + } + //check value for Valve value + if((tmpxy[k][SAMP_CNT_DIV2+1]-tmpxy[k][SAMP_CNT_DIV2-2]) > SH) + { + return; + } + } + total_x=tmpxy[0][SAMP_CNT_DIV2-2]+tmpxy[0][SAMP_CNT_DIV2-1]+tmpxy[0][SAMP_CNT_DIV2]+tmpxy[0][SAMP_CNT_DIV2+1]; + total_y=tmpxy[1][SAMP_CNT_DIV2-2]+tmpxy[1][SAMP_CNT_DIV2-1]+tmpxy[1][SAMP_CNT_DIV2]+tmpxy[1][SAMP_CNT_DIV2+1]; + //calculate average value + touch->x=total_x>>2; + touch->y=total_y>>2; + rt_kprintf("touch->x:%d touch->y:%d\r\n", touch->x, touch->y); + } /* calculate average */ + } /* read touch */ + + /* if it's not in calibration status */ + /*ֵ*/ + if (touch->calibrating != RT_TRUE) + { + if (touch->max_x > touch->min_x) + { + touch->x = (touch->x - touch->min_x) * X_WIDTH/(touch->max_x - touch->min_x); + } + else + { + touch->x = (touch->min_x - touch->x) * X_WIDTH/(touch->min_x - touch->max_x); + } + + if (touch->max_y > touch->min_y) + { + touch->y = (touch->y - touch->min_y) * Y_WIDTH /(touch->max_y - touch->min_y); + } + else + { + touch->y = (touch->min_y - touch->y) * Y_WIDTH /(touch->min_y - touch->max_y); + } + } + } +} +#include "ls1c_regs.h" +#define TOUCH_INT_EN __REG32(LS1C_INT4_EN) +rt_inline void touch_int_cmd(rt_bool_t NewState) +{ + if(NewState == RT_TRUE) + { + //TOUCH_INT_EN |= (1<<(TOUCH_INT_PIN-64)); + reg_set_one_bit(LS1C_INT4_EN, 1<<(TOUCH_INT_PIN-64)); + } + else + { + //TOUCH_INT_EN &=(~ (1<<(TOUCH_INT_PIN-64))); + reg_clr_one_bit(LS1C_INT4_EN, 1<<(TOUCH_INT_PIN-64)); + } + +} + +void ls1c_touch_irqhandler(void) /* TouchScreen */ +{ + if(gpio_get(TOUCH_INT_PIN)==0) + { + /* º */ + if (gpio_level_low == gpio_get(led_gpio)) + gpio_set(led_gpio, gpio_level_high); + else + gpio_set(led_gpio, gpio_level_low); + touch_int_cmd(RT_FALSE); + rt_event_send(&touch->event, 1); + } +} + +/*ܽųʼжϴSPI1 CS0 豸*/ +rt_inline void touch_init(void) +{ + unsigned int touch_int_gpio = TOUCH_INT_PIN; // ж + int touch_irq = LS1C_GPIO_TO_IRQ(touch_int_gpio); + + // ʼж + gpio_set_irq_type(touch_int_gpio, IRQ_TYPE_EDGE_FALLING); + rt_hw_interrupt_install(touch_irq, ls1c_touch_irqhandler, RT_NULL, "touch"); + rt_hw_interrupt_umask(touch_irq); + gpio_init(touch_int_gpio, gpio_mode_input); + + // ʼled + gpio_init(led_gpio, gpio_mode_output); + gpio_set(led_gpio, gpio_level_high); +} + + +/* RT-Thread Device Interface */ +static rt_err_t rtgui_touch_init (rt_device_t dev) +{ + rt_uint8_t send; + rt_uint8_t recv_buffer[2]; + struct rtgui_touch_device * touch_device = (struct rtgui_touch_device *)dev; + + touch_init(); + rt_kprintf("touch_init ...\n"); + send = START | DIFFERENTIAL | POWER_MODE0; + touch_send_then_recv(touch->spi_device, &send, 1, recv_buffer, 2); + + return RT_EOK; +} + +static rt_err_t rtgui_touch_control (rt_device_t dev, int cmd, void *args) +{ + switch (cmd) + { + case RT_TOUCH_CALIBRATION: + touch->calibrating = RT_TRUE; + touch->calibration_func = (rt_touch_calibration_func_t)args; + break; + + case RT_TOUCH_NORMAL: + touch->calibrating = RT_FALSE; + break; + + case RT_TOUCH_CALIBRATION_DATA: + { + struct calibration_data* data; + data = (struct calibration_data*) args; + + //update + touch->min_x = data->min_x; + touch->max_x = data->max_x; + touch->min_y = data->min_y; + touch->max_y = data->max_y; + } + break; + } + + return RT_EOK; +} + +void _set_mouse_position(rt_uint32_t X, rt_uint32_t Y) +{} +static void touch_thread_entry(void *parameter) +{ + rt_bool_t touch_down = RT_FALSE; + rt_uint32_t event_value; + struct rtgui_event_mouse emouse; + static struct _touch_previous + { + rt_uint32_t x; + rt_uint32_t y; + } touch_previous; + + RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse); + emouse.wid = RT_NULL; + + while(1) + { + /* յж¼ */ + if(rt_event_recv(&touch->event, + 1, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + 100, + &event_value) + == RT_EOK) + { + while(1) + { + if (IS_TOUCH_UP()) + { + /* ̧ */ + /* touch up */ + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP); + + /* use old value */ + emouse.x = touch->x; + emouse.y = touch->y; + + if(touch_down != RT_TRUE) + { + touch_int_cmd(RT_TRUE); + break; + } + + if ((touch->calibrating == RT_TRUE) && (touch->calibration_func != RT_NULL)) + { + /* У׼ */ + /* callback function */ + touch->calibration_func(emouse.x, emouse.y); + + } + else + { + /* uiʹ */ + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + } + rt_kprintf("touch up: (%d, %d)\n", emouse.x, emouse.y); + + /* clean */ + touch_previous.x = touch_previous.y = 0; + touch_down = RT_FALSE; + + touch_int_cmd(RT_TRUE); + break; + } /* touch up */ + else /* touch down or move */ + { + if(touch_down == RT_FALSE) + { + rt_thread_delay(RT_TICK_PER_SECOND / 10); + } + else + { + rt_thread_delay(5); + } + + if(IS_TOUCH_UP()) continue; + + /* calculation */ + rtgui_touch_calculate(); + + /* send mouse event */ + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.parent.sender = RT_NULL; + + emouse.x = touch->x; + emouse.y = touch->y; + _set_mouse_position(emouse.x, emouse.y); + /* */ + /* init mouse button */ + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN); + + /* send event to server */ + if (touch->calibrating != RT_TRUE) + { +#define previous_keep 8 + /* filter. */ + if((touch_previous.x > touch->x + previous_keep) + || (touch_previous.x < touch->x - previous_keep) + || (touch_previous.y > touch->y + previous_keep) + || (touch_previous.y < touch->y - previous_keep)) + { + touch_previous.x = touch->x; + touch_previous.y = touch->y; + /* uiʹ */ + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + if(touch_down == RT_FALSE) + { + touch_down = RT_TRUE; + rt_kprintf("touch down: (%d, %d)\n", emouse.x, emouse.y); + } + else + { + rt_kprintf("touch motion: (%d, %d)\n", emouse.x, emouse.y); + } + } + } + else + { + touch_down = RT_TRUE; + } + } /* touch down or move */ + } /* read touch */ + } /* event recv */ + } /* thread while(1) */ +} + + +rt_err_t rtgui_touch_hw_init(const char * spi_device_name) +{ + rt_uint32_t arg[2]; + struct rt_device * spi_device; + struct rt_thread * touch_thread; + rt_err_t err; + + rt_kprintf("spi1 cs0 start...\n"); + spi_device = rt_device_find("spi10"); + if(spi_device == RT_NULL) + { + rt_kprintf("Did not find spi1, exit thread....\n"); + return; + } + err = rt_device_open(spi_device, RT_DEVICE_OFLAG_RDWR); + if(err != RT_EOK) + { + rt_kprintf("Open spi1 failed %08X, exit thread....\n", err); + return; + } + + /* config spi */ + { + struct rt_spi_configuration cfg; + cfg.data_width = 8; + cfg.mode = RT_SPI_MODE_0; + cfg.max_hz = 200 * 1000; /* 200K */ + rt_spi_configure((struct rt_spi_device *)spi_device, &cfg); + } + + touch = (struct rtgui_touch_device*)rt_malloc (sizeof(struct rtgui_touch_device)); + if (touch == RT_NULL) return RT_ENOMEM; /* no memory yet */ + + /* clear device structure */ + rt_memset(&(touch->parent), 0, sizeof(struct rt_device)); + + rt_event_init(&touch->event, "touch", RT_IPC_FLAG_FIFO); + + touch->spi_device = (struct rt_spi_device *)spi_device; + touch->calibrating = false; + + touch->min_x = MIN_X_DEFAULT; + touch->max_x = MAX_X_DEFAULT; + touch->min_y = MIN_Y_DEFAULT; + touch->max_y = MAX_Y_DEFAULT; + + /* init device structure */ + touch->parent.type = RT_Device_Class_Miscellaneous; + touch->parent.init = rtgui_touch_init; + touch->parent.control = rtgui_touch_control; + touch->parent.user_data = RT_NULL; + + /* register touch device to RT-Thread */ + rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR); + + + touch_thread = rt_thread_create("touch_thread", + touch_thread_entry, RT_NULL, + 4096, RTGUI_SVR_THREAD_PRIORITY-1, 1); + if (touch_thread != RT_NULL) rt_thread_startup(touch_thread); + + rt_device_init((rt_device_t)touch); + return RT_EOK; +} + +#endif diff --git a/bsp/ls1cdev/drivers/touch.h b/bsp/ls1cdev/drivers/touch.h new file mode 100644 index 0000000000..0892d2858f --- /dev/null +++ b/bsp/ls1cdev/drivers/touch.h @@ -0,0 +1,43 @@ +/* + * File : touch.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, 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 + * 2017-12-30 Sundm75 first version + */ + #ifndef __TOUCH_H__ +#define __TOUCH_H__ + +#define RT_TOUCH_NORMAL 0 +#define RT_TOUCH_CALIBRATION_DATA 1 +#define RT_TOUCH_CALIBRATION 2 + +//#define SAVE_CALIBRATION + + +rt_uint16_t touch_read_x(void); +rt_uint16_t touch_read_y(void); +void touch_config(void); + + +rt_err_t rtgui_touch_hw_init(const char * spi_device_name); + +#endif + + diff --git a/bsp/ls1cdev/drivers/uart.c b/bsp/ls1cdev/drivers/uart.c index c5207b21db..01bb2d0f8d 100644 --- a/bsp/ls1cdev/drivers/uart.c +++ b/bsp/ls1cdev/drivers/uart.c @@ -24,7 +24,7 @@ /*@{*/ -#if defined(RT_USING_UART) && defined(RT_USING_DEVICE) +#if defined(RT_USING_SERIAL) && defined(RT_USING_DEVICE) struct rt_uart_ls1c { diff --git a/bsp/ls1cdev/kconfig b/bsp/ls1cdev/kconfig new file mode 100644 index 0000000000..f305eb5768 --- /dev/null +++ b/bsp/ls1cdev/kconfig @@ -0,0 +1,79 @@ +mainmenu "RT-Thread Configuration" + + +config $BSP_DIR + string + option env="BSP_ROOT" + default "." + +config $RTT_DIR + string + option env="RTT_ROOT" + default "../.." + +config $PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/KConfig" +source "$PKGS_DIR/KConfig" + +if RT_USING_SERIAL +config RT_USING_UART2 + bool "Using RT_USING_UART2" + default y + +config RT_UART_RX_BUFFER_SIZE + int "The rx buffer size" + default 64 if RT_USING_SERIAL + default 64 +endif + +config RT_USING_GMAC_INT_MODE + bool "Using RT_USING_GMAC_INT_MODE" + default y + +config RT_USING_FPU + bool "Using RT_USING_FPU" + default y + +config RT_USING_SPI0 + bool "Enable SPI0" + select RT_USING_SPI + default y + +config RT_USING_SPI1 + bool "Enable SPI1" + select RT_USING_SPI + default y + +if RT_USING_I2C +config RT_USING_I2C1 + bool "Enable I2C1" + default y + +config RT_USING_I2C2 + bool "Enable I2C2" + default y +endif + + +config USING_BXCAN0 + bool "Enable CAN0" + select RT_USING_CAN + default y + +config USING_BXCAN1 + bool "Enable CAN1" + select RT_USING_CAN + default y + +if RT_USING_CAN +config RT_CAN_USING_HDR + bool "Using RT_CAN_USING_HDR" + select RT_USING_CAN + default y +endif + + \ No newline at end of file diff --git a/bsp/ls1cdev/libraries/ls1c_can.c b/bsp/ls1cdev/libraries/ls1c_can.c new file mode 100644 index 0000000000..f113e60990 --- /dev/null +++ b/bsp/ls1cdev/libraries/ls1c_can.c @@ -0,0 +1,460 @@ +/* + * File : ls1c_can.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2018, 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-01-06 sundm75 first version + */ + +#include "ls1c.h" +#include "ls1c_public.h" +#include "ls1c_can.h" + +unsigned char set_reset_mode(CAN_TypeDef* CANx) +{ + unsigned char status; + int i; + + /*检查复位标志*/ + status = CANx->MOD; + + /* 关闭中断 */ + CANx->IER = 0x00; + + for (i = 0; i < 100; i++) + { + if((status & CAN_Mode_RM) == CAN_Mode_RM) + return 1; + + /* 设置复位*/ + CANx->MOD |= ((unsigned char)CAN_Mode_RM); + + /*延时*/ + delay_us(10); + + /*检查复位标志*/ + status = CANx->MOD; + } + rt_kprintf("\r\nSetting SJA1000 into reset mode failed!\r\n"); + return 0; +} + +static unsigned char set_normal_mode(CAN_TypeDef* CANx) +{ + unsigned char status; + int i; + + /*检查复位标志*/ + status = CANx->MOD; + + for (i = 0; i < 100; i++) + { + if((status & CAN_Mode_RM) != CAN_Mode_RM) + { + /*开所有中断 (总线错误中断不开)*/ + CANx->IER |= (~(unsigned char)CAN_IR_BEI); + return 1; + } + /* 设置正常工作模式*/ + CANx->MOD &= (~(unsigned char) CAN_Mode_RM); + /*延时*/ + delay_us(10); + status = CANx->MOD; + } + rt_kprintf("\r\nSetting SJA1000 into normal mode failed!\r\n"); + return 0; +} + +unsigned char set_start(CAN_TypeDef* CANx) +{ + /*复位TX错误计数器*/ + CANx->TXERR = 0; + /*复位RX错误计数器*/ + CANx->RXERR = 0; + /*时钟分频寄存器: PeliCAN模式; CBP=1,中止输入比较器, RX0激活*/ + CANx->CDR = 0xC0; + + return set_normal_mode(CANx); +} + +unsigned char CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct) +{ + unsigned char InitStatus = CAN_InitStatus_Failed; + unsigned long wait_ack = 0x00000000; + unsigned char status; + + status = CANx->MOD; + if( status == 0xFF) + { + rt_kprintf("\n Probe can0 failed \r\n"); + return CAN_InitStatus_Failed; + } + + /* 进入复位模式 */ + InitStatus = set_reset_mode(CANx); + + if((CAN_InitStruct->CAN_Mode & CAN_Mode_SM) == CAN_Mode_SM) + { + /* 睡眠模式 1: 睡眠 0: 唤醒*/ + CANx->MOD|= (unsigned char)CAN_Mode_SM; + } + else + { + CANx->MOD&=~ (unsigned char)CAN_Mode_SM; + } + + if((CAN_InitStruct->CAN_Mode & CAN_Mode_LOM) == CAN_Mode_LOM) + { + /*只听模式 1:只听 0:正常 */ + CANx->MOD|= (unsigned char)CAN_Mode_LOM; + } + else + { + CANx->MOD&=~ (unsigned char)CAN_Mode_LOM; + } + + if((CAN_InitStruct->CAN_Mode & CAN_Mode_AFM) == CAN_Mode_AFM) + { + /*单滤波模式 1:单 0: 双*/ + CANx->MOD |= (unsigned char)CAN_Mode_AFM; + } + else + { + CANx->MOD&=~ (unsigned char)CAN_Mode_AFM; + } + + if((CAN_InitStruct->CAN_Mode & CAN_Mode_STM) == CAN_Mode_STM) + { + /*自检测模式 1:自检测 0:正常 */ + CANx->MOD |= (unsigned char)CAN_Mode_STM; + } + else + { + CANx->MOD&=~ (unsigned char)CAN_Mode_STM; + } + + /* 配置时钟频率 */ + CANx->BTR0 = (( unsigned char )( unsigned char )CAN_InitStruct->CAN_Prescaler -1) | \ + (unsigned char)CAN_InitStruct->CAN_SJW << 6; + + CANx->BTR1 = ((unsigned char)CAN_InitStruct->CAN_BS1) | \ + ((unsigned char)CAN_InitStruct->CAN_BS2 << 4) | \ + ((unsigned char)CAN_InitStruct->CAN_SJW<<7); + + /* 进入工作模式 */ + set_start(CANx); + + /* 返回初始化结果 */ + return InitStatus; +} + +void CAN_FilterInit(CAN_TypeDef* CANx, CAN_FilterInitTypeDef * CAN_FilterInitStruct) +{ + unsigned long rtr; + unsigned long fcase; + unsigned long ide; + unsigned long thisid, thisid1, thisid2; + unsigned long thismask, thismask1, thismask2; + unsigned long firstdata; + unsigned long datamask; + unsigned char CAN_FilterId0, CAN_FilterId1, CAN_FilterId2, CAN_FilterId3 ; + unsigned char CAN_FilterMaskId0, CAN_FilterMaskId1, CAN_FilterMaskId2, CAN_FilterMaskId3; + + thisid = CAN_FilterInitStruct->ID; + thismask = CAN_FilterInitStruct->IDMASK; + thisid1 = (CAN_FilterInitStruct->ID & 0xFFFF0000 )>>16; + thismask1 = (CAN_FilterInitStruct->IDMASK & 0xFFFF0000 )>>16; + thisid2 = (CAN_FilterInitStruct->ID & 0x0000FFFF ); + thismask2 = ( CAN_FilterInitStruct->IDMASK& 0x0000FFFF ); + rtr = CAN_FilterInitStruct->RTR; + ide = CAN_FilterInitStruct->IDE; + firstdata = CAN_FilterInitStruct->First_Data; + datamask = CAN_FilterInitStruct->Data_Mask; + fcase = CAN_FilterInitStruct->MODE; + + if(ide == 0)//标准帧 + { + if(fcase == 0)// 0- 双滤波器模式 + { + CAN_FilterId0 = thisid1>>3; + CAN_FilterMaskId0 = thismask1>>3; + CAN_FilterId1 = thisid1<<5 | firstdata>>4| rtr<<4; + CAN_FilterMaskId1 = thismask1<<4 | datamask>>4 ; + CAN_FilterId2 = thisid2 >> 3; + CAN_FilterMaskId2 = thismask2 >>3; + CAN_FilterId3 = firstdata & 0x0F | thisid2 <<5 | rtr<<4; + CAN_FilterMaskId3 = datamask <<4 ; + } + else if(fcase == 1)// 1-单滤波器模式 + { + CAN_FilterId0 = thisid>>3; + CAN_FilterMaskId0 = thismask>>3; + CAN_FilterId1 = thisid<<5 | rtr<<4; + CAN_FilterMaskId1 = thismask<<5 ; + CAN_FilterMaskId1 |= 0x0F ; + CAN_FilterId2 = 0x00; + CAN_FilterMaskId2 = 0xFF; + CAN_FilterId3 = 0x00; + CAN_FilterMaskId3 = 0xFF ; + } + } + else if(ide == 1)//扩展帧 + { + if(fcase == 0)// 0- 双滤波器模式 + { + CAN_FilterId0 = thisid1>>8; + CAN_FilterMaskId0 = thismask1>>8; + CAN_FilterId1 = thisid1 ; + CAN_FilterMaskId1 = thismask1 ; + CAN_FilterId2 = thisid2>>8; + CAN_FilterMaskId2 = thismask2>>8; + CAN_FilterId3 = thisid2 ; + CAN_FilterMaskId3 = thismask2 ; + } + else if(fcase == 1)// 1-单滤波器模式 + { + CAN_FilterId0 = thisid>>21; + CAN_FilterMaskId0 = thismask>>21; + CAN_FilterId1 = thisid>>13 ; + CAN_FilterMaskId1 = thismask>>13 ; + CAN_FilterId2 = thisid>>5; + CAN_FilterMaskId2 = thismask>>5; + CAN_FilterId3 = thisid<<3 | rtr<<2; + CAN_FilterMaskId3 = thismask<<3; + CAN_FilterMaskId3 |= 0x03; + } + } + + /* 进入复位模式 */ + set_reset_mode(CANx); + + if(fcase == 1)// 1-单滤波器模式 + { + /*单滤波模式 */ + CANx->MOD |= (unsigned char)CAN_Mode_AFM; + } + else if(fcase == 1)// 0- 双滤波器模式 + { + /*双滤波模式 */ + CANx->MOD &=(~ (unsigned char) CAN_Mode_AFM); + } + + CANx->IDE_RTR_DLC = CAN_FilterId0; + CANx->ID[0] = CAN_FilterId1; + CANx->ID[1] = CAN_FilterId2; + CANx->ID[2] = CAN_FilterId3; + CANx->ID[3] = CAN_FilterMaskId0; + CANx->BUF[0] = CAN_FilterMaskId1; + CANx->BUF[1] = CAN_FilterMaskId2; + CANx->BUF[2] = CAN_FilterMaskId3; + /* 进入工作模式 */ + set_start(CANx); +} + +unsigned char CAN_SetBps(CAN_TypeDef* CANx, Ls1c_CanBPS_t Bps) +{ + unsigned char InitStatus = CAN_InitStatus_Failed; + unsigned char CAN_Prescaler, CAN_BS1, CAN_BS2, CAN_SJW; + CAN_SJW = CAN_SJW_1tq; + /* 进入复位模式 */ + InitStatus = set_reset_mode(CANx); + if( InitStatus == CAN_InitStatus_Failed) + return CAN_InitStatus_Failed; + + /* BaudRate= f(APB)/((1+BS1+BS2)(SJW*2*Prescaler))=126000000/[(1+7+2)*1*2*63]=100000=100K*/ + /* BPS PRE BS1 BS2 最低40K + 1M 9 4 2 + 800K 8 7 2 + 500K 9 11 2 + 250K 36 4 2 + 125K 36 11 2 + 100K 63 7 2 + 50K 63 16 3` + 40K 63 16 8 + */ + switch (Bps) + { + case LS1C_CAN1MBaud: + CAN_Prescaler = 9; + CAN_BS1 = CAN_BS1_4tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN800kBaud: + CAN_Prescaler = 8; + CAN_BS1 = CAN_BS1_7tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN500kBaud: + CAN_Prescaler = 9; + CAN_BS1 = CAN_BS1_11tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN250kBaud: + CAN_Prescaler = 36; + CAN_BS1 = CAN_BS1_4tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN125kBaud: + CAN_Prescaler = 36; + CAN_BS1 = CAN_BS1_11tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN100kBaud: + CAN_Prescaler = 63; + CAN_BS1 = CAN_BS1_7tq; + CAN_BS2 = CAN_BS2_2tq; + break; + case LS1C_CAN50kBaud: + CAN_Prescaler = 63; + CAN_BS1 = CAN_BS1_16tq; + CAN_BS2 = CAN_BS2_3tq; + break; + case LS1C_CAN40kBaud: + CAN_Prescaler = 63; + CAN_BS1 = CAN_BS1_16tq; + CAN_BS2 = CAN_BS2_8tq; + break; + default: //100K + CAN_Prescaler = 63; + CAN_BS1 = CAN_BS1_7tq; + CAN_BS2 = CAN_BS2_2tq; + break; + } + /* 配置时钟频率 */ + CANx->BTR0 = (( unsigned char )CAN_Prescaler -1) | \ + (unsigned char)CAN_SJW << 6; + + CANx->BTR1 = ((unsigned char)CAN_BS1) | \ + ((unsigned char)CAN_BS2 << 4) | \ + ((unsigned char)CAN_SJW<<7); + + /* 进入工作模式 */ + set_start(CANx); + /* 返回初始化结果 */ + return CAN_InitStatus_Failed; +} + + +unsigned char CAN_SetMode(CAN_TypeDef* CANx, unsigned char mode) +{ + unsigned char InitStatus = CAN_InitStatus_Failed; + unsigned long wait_ack = 0x00000000; + CAN_InitTypeDef CAN_InitStructure; + + /* 进入复位模式 */ + InitStatus = set_reset_mode(CANx); + if( InitStatus == CAN_InitStatus_Failed) + return CAN_InitStatus_Failed; + + switch( mode ) + { + case 0://正常 + CANx->MOD &= ~(unsigned char)CAN_Mode_STM; + CANx->MOD &= ~(unsigned char)CAN_Mode_LOM; + break; + case 1://只听 + CANx->MOD &= ~(unsigned char)CAN_Mode_STM; + CANx->MOD |= (unsigned char)CAN_Mode_LOM; + break; + case 2://回环 + CANx->MOD |= (unsigned char)CAN_Mode_STM; + CANx->MOD &= ~(unsigned char)CAN_Mode_LOM; + break; + case 3://只听回环 + CANx->MOD |= (unsigned char)CAN_Mode_STM; + CANx->MOD |= (unsigned char)CAN_Mode_LOM; + break; + } + /* 进入工作模式 */ + set_start(CANx); + + /* 返回初始化结果 */ + return CAN_InitStatus_Failed; + } + +unsigned char CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) +{ + int i; + if (TxMessage->IDE == CAN_Id_Extended) + { + CANx->ID[0]= TxMessage ->ExtId>> 21; + CANx->ID[1]= TxMessage ->ExtId>> 13; + CANx->ID[2]= TxMessage ->ExtId>> 5; + CANx->ID[3]= TxMessage ->ExtId<<3; + CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\ + (TxMessage ->RTR & 0x01) << 6 |\ + (TxMessage ->DLC & 0x0F); + for( i=0;iDLC; i++) + { + CANx->BUF[i]= TxMessage->Data[i]; + } + } + else if (TxMessage->IDE ==CAN_Id_Standard) + { + CANx->ID[0]= TxMessage ->StdId>> 3; + CANx->ID[1]= TxMessage ->StdId<< 5; + CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\ + (TxMessage ->RTR & 0x01) << 6 |\ + (TxMessage ->DLC & 0x0F); + CANx->ID[2]= TxMessage ->Data[0]; + CANx->ID[3]= TxMessage ->Data[1]; + for( i=0;iDLC-2; i++) + { + CANx->BUF[i]= TxMessage->Data[i+2]; + } + } + CANx->CMR = CAN_CMR_TR ; +} + +void CAN_Receive(CAN_TypeDef* CANx, CanRxMsg* RxMessage) +{ + /* 获取 IDE */ + RxMessage->IDE = (CANx->IDE_RTR_DLC & 0x80)>>7; + /* 获取 RTR */ + RxMessage->RTR = (CANx->IDE_RTR_DLC & 0x40)>>4; + /* 获取 DLC */ + RxMessage->DLC= (CANx->IDE_RTR_DLC & 0x0F); + if (RxMessage->IDE == CAN_Id_Standard) + { + RxMessage->StdId = CANx->ID[0]<<3 |CANx->ID[1]>>5 ; + /* 获取数据 */ + RxMessage->Data[0] = (unsigned char)CANx->ID[2]; + RxMessage->Data[1] = (unsigned char)CANx->ID[3]; + RxMessage->Data[2] = (unsigned char)CANx->BUF[0]; + RxMessage->Data[3] = (unsigned char)CANx->BUF[1]; + RxMessage->Data[4] = (unsigned char)CANx->BUF[2]; + RxMessage->Data[5] = (unsigned char)CANx->BUF[3]; + RxMessage->Data[6] = (unsigned char)CANx->BUF[4]; + RxMessage->Data[7] = (unsigned char)CANx->BUF[5]; + } + else if (RxMessage->IDE == CAN_Id_Extended) + { + RxMessage->ExtId= CANx->ID[0]<<21 |CANx->ID[1]<<13|CANx->ID[2]<<5|CANx->ID[3]>>3 ; + /* 获取数据 */ + RxMessage->Data[0] = (unsigned char)CANx->BUF[0]; + RxMessage->Data[1] = (unsigned char)CANx->BUF[1]; + RxMessage->Data[2] = (unsigned char)CANx->BUF[2]; + RxMessage->Data[3] = (unsigned char)CANx->BUF[3]; + RxMessage->Data[4] = (unsigned char)CANx->BUF[4]; + RxMessage->Data[5] = (unsigned char)CANx->BUF[5]; + RxMessage->Data[6] = (unsigned char)CANx->BUF[6]; + RxMessage->Data[7] = (unsigned char)CANx->BUF[7]; + } +} + diff --git a/bsp/ls1cdev/libraries/ls1c_can.h b/bsp/ls1cdev/libraries/ls1c_can.h new file mode 100644 index 0000000000..4e27a4b075 --- /dev/null +++ b/bsp/ls1cdev/libraries/ls1c_can.h @@ -0,0 +1,227 @@ + +/* + * File : ls1c_can.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2018, 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: (Pelican Mode) + * Date Author Notes + * 2018-01-06 sundm75 first version + */ + +#ifndef __OPENLOONGSON_CAN_H +#define __OPENLOONGSON_CAN_H + +#define CAN0 ( (CAN_TypeDef* )LS1C_REG_BASE_CAN0) +#define CAN1 ( (CAN_TypeDef* )LS1C_REG_BASE_CAN1) + +#define CAN_InitStatus_Failed ((unsigned char)0x00) /*!< CAN initialization failed */ +#define CAN_InitStatus_Success ((unsigned char)0x01) /*!< CAN initialization OK */ + +#define CAN_SJW_1tq ((unsigned char)0x00) /*!< 1 time quantum */ +#define CAN_SJW_2tq ((unsigned char)0x01) /*!< 2 time quantum */ +#define CAN_SJW_3tq ((unsigned char)0x02) /*!< 3 time quantum */ +#define CAN_SJW_4tq ((unsigned char)0x03) /*!< 4 time quantum */ + +#define CAN_BS1_1tq ((unsigned char)0x00) /*!< 1 time quantum */ +#define CAN_BS1_2tq ((unsigned char)0x01) /*!< 2 time quantum */ +#define CAN_BS1_3tq ((unsigned char)0x02) /*!< 3 time quantum */ +#define CAN_BS1_4tq ((unsigned char)0x03) /*!< 4 time quantum */ +#define CAN_BS1_5tq ((unsigned char)0x04) /*!< 5 time quantum */ +#define CAN_BS1_6tq ((unsigned char)0x05) /*!< 6 time quantum */ +#define CAN_BS1_7tq ((unsigned char)0x06) /*!< 7 time quantum */ +#define CAN_BS1_8tq ((unsigned char)0x07) /*!< 8 time quantum */ +#define CAN_BS1_9tq ((unsigned char)0x08) /*!< 9 time quantum */ +#define CAN_BS1_10tq ((unsigned char)0x09) /*!< 10 time quantum */ +#define CAN_BS1_11tq ((unsigned char)0x0A) /*!< 11 time quantum */ +#define CAN_BS1_12tq ((unsigned char)0x0B) /*!< 12 time quantum */ +#define CAN_BS1_13tq ((unsigned char)0x0C) /*!< 13 time quantum */ +#define CAN_BS1_14tq ((unsigned char)0x0D) /*!< 14 time quantum */ +#define CAN_BS1_15tq ((unsigned char)0x0E) /*!< 15 time quantum */ +#define CAN_BS1_16tq ((unsigned char)0x0F) /*!< 16 time quantum */ + +#define CAN_BS2_1tq ((unsigned char)0x00) /*!< 1 time quantum */ +#define CAN_BS2_2tq ((unsigned char)0x01) /*!< 2 time quantum */ +#define CAN_BS2_3tq ((unsigned char)0x02) /*!< 3 time quantum */ +#define CAN_BS2_4tq ((unsigned char)0x03) /*!< 4 time quantum */ +#define CAN_BS2_5tq ((unsigned char)0x04) /*!< 5 time quantum */ +#define CAN_BS2_6tq ((unsigned char)0x05) /*!< 6 time quantum */ +#define CAN_BS2_7tq ((unsigned char)0x06) /*!< 7 time quantum */ +#define CAN_BS2_8tq ((unsigned char)0x07) /*!< 8 time quantum */ + +#define CAN_Id_Standard 0 +#define CAN_Id_Extended 1 +#define CAN_RTR_DATA 0 +#define CAN_RTR_Remote 1 + +#define CAN_MODE_NORMAL 0 +#define CAN_MODE_LISEN 1 +#define CAN_MODE_LOOPBACK 2 +#define CAN_MODE_LOOPBACKANLISEN 3 + +/*!< CAN 控制状态寄存器 */ +/************************** CAN_MOD 寄存器位定义*******************************/ +#define CAN_Mode_RM ((unsigned char)0x01) /*!< 复位模式 */ +#define CAN_Mode_LOM ((unsigned char)0x02) /*!< 只听模式 1:只听 0:正常 */ +#define CAN_Mode_STM ((unsigned char)0x04) /*!< 正常工作模式1:自检测 0:正常 */ +#define CAN_Mode_AFM ((unsigned char)0x08) /*!< 单/双滤波模式 1:单 0: 双*/ +#define CAN_Mode_SM ((unsigned char)0x10) /*!< 睡眠模式1: 睡眠 0: 唤醒 */ + +/************************** CAN_CMR 寄存器位定义*******************************/ + #define CAN_CMR_TR ((unsigned char)0x01) /*!< 发送请求 1: 当前信息被发送 0: 空 */ + #define CAN_CMR_AT ((unsigned char)0x02) /*!< 中止发送 1: 等待发送的信息取消 0: 空缺 */ + #define CAN_CMR_RRB ((unsigned char)0x04) /*!< 释放接收缓冲器 1:释放 0: 无动作 */ + #define CAN_CMR_CDO ((unsigned char)0x08) /*!< 清除数据溢出 1:清除 0: 无动作 */ +//#define CAN_CMR_GTS ((unsigned char)0x10) /*!< STD模式< 睡眠: 1:进入睡眠 0: 唤醒 */ + #define CAN_CMR_SRR ((unsigned char)0x10) /*!< 自接收请求 1: 0: */ + #define CAN_CMR_EFF ((unsigned char)0x80) /*!< 扩展模式 1:扩展帧 0: 标准帧 */ + +/************************** CAN_SR 寄存器位定义********************************/ + #define CAN_SR_BBS ((unsigned char)0x01) /*!< 接收缓存器状态1: 满 0: 空 */ + #define CAN_SR_DOS ((unsigned char)0x02) /*!< 数据溢出状态 1: 溢出 0: 空缺 */ + #define CAN_SR_TBS ((unsigned char)0x04) /*!< 发送缓存器状态1: 释放 0: 锁定 */ + #define CAN_SR_TCS ((unsigned char)0x08) /*!< 发送完毕状态1: 完毕 0: 未完毕 */ + #define CAN_SR_RS ((unsigned char)0x10) /*!< 接收状态1: 接收 0: 空闲 */ + #define CAN_SR_TS ((unsigned char)0x20) /*!< 发送状态1: 发送 0: 空闲*/ + #define CAN_SR_ES ((unsigned char)0x40) /*!< 出错状态1:出错 0: 正常 */ + #define CAN_SR_BS ((unsigned char)0x80) /*!< 总线状态1: 关闭 0: 开启 */ + +/************************** CAN_IR 中断寄存器位定义****************************/ + #define CAN_IR_RI ((unsigned char)0x01) /*!< 接收中断 */ + #define CAN_IR_TI ((unsigned char)0x02) /*!< 发送中断 */ + #define CAN_IR_EI ((unsigned char)0x04) /*!< 错误中断 */ + #define CAN_IR_DOI ((unsigned char)0x08) /*!< 数据溢出中断 */ + #define CAN_IR_WUI ((unsigned char)0x10) /*!< 唤醒中断 */ + #define CAN_IR_EPI ((unsigned char)0x20) /*!< 错误消极中断 */ + #define CAN_IR_ALI ((unsigned char)0x40) /*!< 仲裁丢失中断 */ + #define CAN_IR_BEI ((unsigned char)0x80) /*!< 总线错误中断 */ + +/************************* CAN_IER 中断使能寄存器位定义************************/ + #define CAN_IER_RIE ((unsigned char)0x01) /*!< 接收中断使能 */ + #define CAN_IER_TIE ((unsigned char)0x02) /*!< 发送中断使能 */ + #define CAN_IER_EIE ((unsigned char)0x04) /*!< 错误中断使能 */ + #define CAN_IER_DOIE ((unsigned char)0x08) /*!< 数据溢出中断使能 */ + #define CAN_IER_WUIE ((unsigned char)0x10) /*!< 唤醒中断使能 */ + #define CAN_IER_EPIE ((unsigned char)0x20) /*!< 错误消极中断使能 */ + #define CAN_IER_ALIE ((unsigned char)0x40) /*!< 仲裁丢失中断使能 */ + #define CAN_IER_BEIE ((unsigned char)0x80) /*!< 总线错误中断使能 */ + +typedef enum +{ + LS1C_CAN1MBaud=0, // 1 MBit/sec + LS1C_CAN800kBaud, // 800 kBit/sec + LS1C_CAN500kBaud, // 500 kBit/sec + LS1C_CAN250kBaud, // 250 kBit/sec + LS1C_CAN125kBaud, // 125 kBit/sec + LS1C_CAN100kBaud, // 100 kBit/sec + LS1C_CAN50kBaud, // 50 kBit/sec + LS1C_CAN40kBaud, // 40 kBit/sec +}Ls1c_CanBPS_t; + +typedef struct +{ + unsigned char MOD; + unsigned char CMR; + unsigned char SR; + unsigned char IR; + unsigned char IER; + unsigned char reserved0; + unsigned char BTR0; + unsigned char BTR1; + unsigned char OCR; + unsigned char reserved[2]; + unsigned char ALC; + unsigned char ECC ; + unsigned char EMLR; + unsigned char RXERR; + unsigned char TXERR; + unsigned char IDE_RTR_DLC; + unsigned char ID[4]; + unsigned char BUF[8]; + unsigned char RMCR; + unsigned char CDR; +} CAN_TypeDef; + +typedef struct +{ + unsigned char CAN_Prescaler; /* 波特率分频系数1 to 31. */ + unsigned char CAN_Mode; /*0x10:睡眠0x08:单,双滤波 0x40:正常工作0x20:只听 0x01:复位*/ + unsigned char CAN_SJW; /*同步跳转宽度 */ + unsigned char CAN_BS1; /*时间段1计数值*/ + unsigned char CAN_BS2; /*时间段2计数值*/ + +} CAN_InitTypeDef; + +typedef struct +{ + unsigned char IDE; /*0: 使用标准标识符1: 使用扩展标识符*/ + unsigned char RTR; /*0: 数据帧 1: 远程帧*/ + unsigned char MODE; /* 0- 双滤波器模式;1-单滤波器模式*/ + unsigned long First_Data; /*双滤波器模式下信息第一个数据字节*/ + unsigned long Data_Mask; /*双滤波器模式下信息第一个数据字节屏蔽*/ + unsigned long ID; /*验收代码*/ + /* + 双滤波器- 扩展帧: 2个滤波器的前16位,分别放在ID 的前16位和 ID的后16位. + 双滤波器- 标准帧: 2个滤波器的11位,分别放在ID 的前16位和 ID的后16位,第1个滤波器同时使用First_Data和Data_Mask + 单滤波器- 扩展帧: 使用29位, 放在ID 的后29位. + 单滤波器- 标准帧: 使用11位, 放在ID 的后11位. + */ + unsigned long IDMASK; /*验收屏蔽*/ +} CAN_FilterInitTypeDef; + +typedef struct +{ + unsigned long StdId; /* 11位ID*/ + unsigned long ExtId; /*29位ID**/ + unsigned char IDE; /*IDE: 标识符选择 + 该位决定发送邮箱中报文使用的标识符类型 + 0: 使用标准标识符 + 1: 使用扩展标识符*/ + unsigned char RTR; /*远程发送请求 + 0: 数据帧 + 1: 远程帧*/ + unsigned char DLC; /*数据帧长度*/ + unsigned char Data[8]; /*8字节数据*/ +} CanRxMsg; + +typedef struct +{ + unsigned long StdId; /* 11位ID*/ + unsigned long ExtId; /*29位ID**/ + unsigned char IDE; /*IDE: 标识符选择 + 该位决定发送邮箱中报文使用的标识符类型 + 0: 使用标准标识符 + 1: 使用扩展标识符*/ + unsigned char RTR; /*远程发送请求 + 0: 数据帧 + 1: 远程帧*/ + unsigned char DLC; /*数据帧长度*/ + unsigned char Data[8]; /*8字节数据*/ +} CanTxMsg; + +unsigned char CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); +unsigned char CAN_SetBps(CAN_TypeDef* CANx, Ls1c_CanBPS_t Bps); +unsigned char CAN_SetMode(CAN_TypeDef* CANx, unsigned char mode); +void CAN_FilterInit(CAN_TypeDef* CANx, CAN_FilterInitTypeDef* CAN_FilterInitStruct); +unsigned char CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); +void CAN_Receive(CAN_TypeDef* CANx, CanRxMsg* RxMessage); + +unsigned char set_reset_mode(CAN_TypeDef* CANx); +unsigned char set_start(CAN_TypeDef* CANx); + +#endif + diff --git a/bsp/ls1cdev/libraries/ls1c_pin.c b/bsp/ls1cdev/libraries/ls1c_pin.c index 2dd71d79b1..15b4157b15 100644 --- a/bsp/ls1cdev/libraries/ls1c_pin.c +++ b/bsp/ls1cdev/libraries/ls1c_pin.c @@ -42,6 +42,15 @@ void pin_set_remap(unsigned int gpio, pin_remap_t remap) volatile unsigned int *reg = NULL; // üĴ unsigned int port = GPIO_GET_PORT(gpio); unsigned int pin = GPIO_GET_PIN(gpio); + int i; + + /*ָȫpinΪ0*/ + for(i =0; i <=4; i++) + { + reg = (volatile unsigned int *)((LS1C_CBUS_FIRST0)+((port)*0x04)+((i)*0x10)); + // 0 + reg_clr_one_bit(reg, pin); + } switch (port) { diff --git a/bsp/ls1cdev/libraries/ls1c_pin.h b/bsp/ls1cdev/libraries/ls1c_pin.h index ca8ef31585..c483f5659a 100644 --- a/bsp/ls1cdev/libraries/ls1c_pin.h +++ b/bsp/ls1cdev/libraries/ls1c_pin.h @@ -20,6 +20,7 @@ typedef enum PIN_REMAP_THIRD, // PIN_REMAP_FOURTH, // ĸ PIN_REMAP_FIFTH, // 帴 + PIN_REMAP_DEFAULT, //ȱʡ }pin_remap_t; diff --git a/bsp/ls1cdev/libraries/ls1c_regs.h b/bsp/ls1cdev/libraries/ls1c_regs.h index 9d6c21dea6..630b45ccbe 100644 --- a/bsp/ls1cdev/libraries/ls1c_regs.h +++ b/bsp/ls1cdev/libraries/ls1c_regs.h @@ -1,4 +1,4 @@ -// о1cĴ +// 龙芯1c外设寄存器 #ifndef __OPENLOONGSON_LS1C_REGS_H @@ -7,12 +7,12 @@ -// ʱؼĴַ +// 时钟相关寄存器地址 #define LS1C_START_FREQ (0xbfe78030) #define LS1C_CLK_DIV_PARAM (0xbfe78034) -// gpioؼĴַ +// gpio相关寄存器地址 #define LS1C_GPIO_CFG0 (0xbfd010c0) #define LS1C_GPIO_EN0 (0xbfd010d0) #define LS1C_GPIO_IN0 (0xbfd010e0) @@ -35,7 +35,7 @@ -// ؼĴ +// 复用相关寄存器 #define LS1C_CBUS_FIRST0 (0xbfd011c0) #define LS1C_CBUS_SECOND0 (0xbfd011d0) #define LS1C_CBUS_THIRD0 (0xbfd011e0) @@ -61,20 +61,22 @@ #define LS1C_CBUS_FIFTH3 (0xbfd0120c) -// PWMĴƫ +// PWM寄存器偏移 #define LS1C_PWM_CNTR (0x0) #define LS1C_PWM_HRC (0x4) #define LS1C_PWM_LRC (0x8) #define LS1C_PWM_CTRL (0xC) -// PWMַ +// PWM基地址 #define LS1C_REG_BASE_PWM0 (0xbfe5c000) #define LS1C_REG_BASE_PWM1 (0xbfe5c010) #define LS1C_REG_BASE_PWM2 (0xbfe5c020) #define LS1C_REG_BASE_PWM3 (0xbfe5c030) +//CAN基地址 +#define LS1C_REG_BASE_CAN0 (0xbfe50000) +#define LS1C_REG_BASE_CAN1 (0xbfe54000) - -// жüĴ +// 中断配置寄存器 #define LS1C_INT0_SR (0xbfd01040) #define LS1C_INT0_EN (0xbfd01044) #define LS1C_INT0_SET (0xbfd01048) @@ -111,18 +113,18 @@ #define LS1C_INT4_EDGE (0xbfd010b4) -// I2CĴ +// I2C寄存器 #define LS1C_I2C0_BASE (0xbfe58000) #define LS1C_I2C1_BASE (0xbfe68000) #define LS1C_I2C2_BASE (0xbfe70000) -// SPIĴ +// SPI寄存器 #define LS1C_SPI0_BASE (0xbfe80000) #define LS1C_SPI1_BASE (0xbfec0000) -// ڼĴ +// 串口寄存器 #define LS1C_UART0_BASE (0xbfe40000) #define LS1C_UART1_BASE (0xbfe44000) #define LS1C_UART2_BASE (0xbfe48000) diff --git a/bsp/ls1cdev/libraries/ls1c_spi.c b/bsp/ls1cdev/libraries/ls1c_spi.c index 7da50e1c37..e3df729064 100644 --- a/bsp/ls1cdev/libraries/ls1c_spi.c +++ b/bsp/ls1cdev/libraries/ls1c_spi.c @@ -19,10 +19,10 @@ * * Change Logs: * Date Author Notes - * 2017-10-23 Ϊ first version + * 2017-10-23 勤为本 first version */ -// ӲspiӿԴļ +// 硬件spi接口源文件 #include @@ -35,8 +35,8 @@ /* - * ȡָSPIģĻַ - * @SPIx SPIģı + * 获取指定SPI模块的基地址 + * @SPIx SPI模块的编号 */ inline void *ls1c_spi_get_base(unsigned char SPIx) { @@ -62,8 +62,8 @@ inline void *ls1c_spi_get_base(unsigned char SPIx) /* - * ӡָSPIģмĴֵ - * @spi_base ַ + * 打印指定SPI模块的所有寄存器的值 + * @spi_base 基地址 */ void ls1c_spi_print_all_regs_info(void *spi_base) { @@ -81,9 +81,9 @@ void ls1c_spi_print_all_regs_info(void *spi_base) /* - * SPIʱƵʼƵϵ - * @max_speed_hz SPIͨٶ - * @ret Ƶϵ + * 根据SPI时钟频率计算分频系数 + * @max_speed_hz SPI最大通信速度 + * @ret 分频系数 */ unsigned int ls1c_spi_get_div(unsigned int max_speed_hz) { @@ -145,28 +145,28 @@ unsigned int ls1c_spi_get_div(unsigned int max_speed_hz) /* - * ʱ - * @spi_base ַ - * @max_hz Ƶʣλhz + * 设置时钟 + * @spi_base 基地址 + * @max_hz 最大频率,单位hz */ void ls1c_spi_set_clock(void *spi_base, unsigned long max_hz) { unsigned int div = 0; unsigned char val = 0; - // ȡƵϵ + // 获取分频系数 div = ls1c_spi_get_div(max_hz); - // spr + // 设置spr val = reg_read_8(spi_base + LS1C_SPI_SPCR_OFFSET); - val &= (~LS1C_SPI_SPCR_SPR_MASK); // spr - val |= (div & LS1C_SPI_SPCR_SPR_MASK); // µspr + val &= (~LS1C_SPI_SPCR_SPR_MASK); // spr清零 + val |= (div & LS1C_SPI_SPCR_SPR_MASK); // 设置新的spr reg_write_8(val, spi_base + LS1C_SPI_SPCR_OFFSET); - // spre + // 设置spre val = reg_read_8(spi_base + LS1C_SPI_SPER_OFFSET); - val &= (~LS1C_SPI_SPER_SPRE_MASK); // spre - val |= ((div >> 2) & LS1C_SPI_SPER_SPRE_MASK); // µspre + val &= (~LS1C_SPI_SPER_SPRE_MASK); // spre清零 + val |= ((div >> 2) & LS1C_SPI_SPER_SPRE_MASK); // 设置新的spre reg_write_8(val, spi_base + LS1C_SPI_SPER_OFFSET); return ; @@ -174,10 +174,10 @@ void ls1c_spi_set_clock(void *spi_base, unsigned long max_hz) /* - * ͨģʽ(ʱӼԺλ) - * @spi_base ַ - * @cpol ʱӼ - * @cpha ʱλ + * 设置通信模式(时钟极性和相位) + * @spi_base 基地址 + * @cpol 时钟极性 + * @cpha 时钟相位 */ void ls1c_spi_set_mode(void *spi_base, unsigned char cpol, unsigned char cpha) { @@ -185,13 +185,13 @@ void ls1c_spi_set_mode(void *spi_base, unsigned char cpol, unsigned char cpha) val = reg_read_8(spi_base + LS1C_SPI_SPCR_OFFSET); - // ʱӼ--cpol - val &= (~LS1C_SPI_SPCR_CPOL_MASK); // cpol0 - val |= (cpol << LS1C_SPI_SPCR_CPOL_BIT); // дµcpol + // 设置时钟极性--cpol + val &= (~LS1C_SPI_SPCR_CPOL_MASK); // cpol清0 + val |= (cpol << LS1C_SPI_SPCR_CPOL_BIT); // 写入新的cpol - // ʱλ--cpha - val &= (~LS1C_SPI_SPCR_CPHA_MASK); // cpha0 - val |= (cpha << LS1C_SPI_SPCR_CPHA_BIT); // дµcpha + // 设置时钟相位--cpha + val &= (~LS1C_SPI_SPCR_CPHA_MASK); // cpha清0 + val |= (cpha << LS1C_SPI_SPCR_CPHA_BIT); // 写入新的cpha reg_write_8(val, spi_base + LS1C_SPI_SPCR_OFFSET); @@ -200,23 +200,24 @@ void ls1c_spi_set_mode(void *spi_base, unsigned char cpol, unsigned char cpha) /* - * ָƬѡΪָ״̬ - * @spi_base ַ - * @cs Ƭѡ - * @new_status Ƭѡŵ״̬ȡֵΪ01ߵƽ͵ƽ + * 设置指定片选为指定状态 + * @spi_base 基地址 + * @cs 片选 + * @new_status 片选引脚的新状态,取值为0或1,即高电平或低电平 */ void ls1c_spi_set_cs(void *spi_base, unsigned char cs, int new_status) { unsigned char val = 0; - val = 0xf0 | (0x01 << cs); // ȫcsn=1ָcsen=1 + val = reg_read_8(spi_base + LS1C_SPI_SFC_SOFTCS_OFFSET); + val |= 0x01 << cs ; //对应的csen=1 if (new_status) // cs = 1 { - val |= (0x10 << cs); // ָcsn=1 + val |= (0x10 << cs); // 指定csn=1 } else // cs = 0 { - val &= ~(0x10 << cs); // ָcsn=0 + val &= ~(0x10 << cs); // 指定csn=0 } reg_write_8(val, spi_base + LS1C_SPI_SFC_SOFTCS_OFFSET); @@ -225,8 +226,8 @@ void ls1c_spi_set_cs(void *spi_base, unsigned char cs, int new_status) /* - * ȴշ - * @spi_base ַ + * 等待收发完成 + * @spi_base 基地址 */ inline void ls1c_spi_wait_txrx_done(void *spi_base) { @@ -243,25 +244,25 @@ inline void ls1c_spi_wait_txrx_done(void *spi_base) /* - * жϺͱ־λ - * @spi_base ַ + * 清中断和标志位 + * @spi_base 基地址 */ inline void ls1c_spi_clear(void *spi_base) { unsigned char val = 0; - // ж + // 清中断 val = reg_read_8(spi_base + LS1C_SPI_SPSR_OFFSET); val |= LS1C_SPI_SPSR_SPIF_MASK; reg_write_8(val, spi_base + LS1C_SPI_SPSR_OFFSET); - // ־λ(Write-Collision Clear) + // 清溢出标志位(Write-Collision Clear) val = reg_read_8(spi_base + LS1C_SPI_SPSR_OFFSET); if (LS1C_SPI_SPSR_WCOL_MASK & val) { - rt_kprintf("[%s] clear register SPSR's wcol!\r\n"); // ֲlinuxԴвһӸӡ - reg_write_8(val & ~LS1C_SPI_SPSR_WCOL_MASK, spi_base + LS1C_SPI_SPSR_OFFSET); // д0linuxԴд0 -// reg_write_8(val | LS1C_SPI_SPSR_WCOL_MASK, spi_base + LS1C_SPI_SPSR_OFFSET); // д11cֲᣬӦд1 + rt_kprintf("[%s] clear register SPSR's wcol!\r\n"); // 手册和linux源码中不一样,加个打印看看 + reg_write_8(val & ~LS1C_SPI_SPSR_WCOL_MASK, spi_base + LS1C_SPI_SPSR_OFFSET); // 写0,linux源码中是写0 +// reg_write_8(val | LS1C_SPI_SPSR_WCOL_MASK, spi_base + LS1C_SPI_SPSR_OFFSET); // 写1,按照1c手册,应该写1 } return ; @@ -270,23 +271,23 @@ inline void ls1c_spi_clear(void *spi_base) /* - * ָͨSPIͽһֽ - * ע⣬ڶϵͳУ˺Ҫ⡣ - * ֤ںij豸շijֽڵĹУܱлͬʱͬһSPIϵĴ豸ͨ - * Ϊо1cÿ·SPIϿܽвͬĴ豸ͨƵʡģʽȿܲͬ - * @spi_base ַ - * @tx_ch ͵ - * @ret յ + * 通过指定SPI发送接收一个字节 + * 注意,在多任务的系统中,此函数需要互斥。 + * 即保证在和某个从设备收发某个字节的过程中,不能被切换到其它任务同时与另外的在同一个SPI总线上的从设备通信 + * 因为龙芯1c的每路SPI上可能接有不同的从设备,通信频率、模式等可能不同 + * @spi_base 基地址 + * @tx_ch 待发送的数据 + * @ret 收到的数据 */ unsigned char ls1c_spi_txrx_byte(void *spi_base, unsigned char tx_ch) { unsigned char rx_ch = 0; - // շ - reg_write_8(tx_ch, spi_base + LS1C_SPI_TxFIFO_OFFSET); // ʼ - ls1c_spi_wait_txrx_done(spi_base); // ȴշ - rx_ch = reg_read_8(spi_base + LS1C_SPI_RxFIFO_OFFSET); // ȡյ - ls1c_spi_clear(spi_base); // жϺͱ־λ + // 收发数据 + reg_write_8(tx_ch, spi_base + LS1C_SPI_TxFIFO_OFFSET); // 开始发送 + ls1c_spi_wait_txrx_done(spi_base); // 等待收发完成 + rx_ch = reg_read_8(spi_base + LS1C_SPI_RxFIFO_OFFSET); // 读取收到的数据 + ls1c_spi_clear(spi_base); // 清中断和标志位 return rx_ch; } diff --git a/bsp/ls1cdev/rtconfig.h b/bsp/ls1cdev/rtconfig.h index 117282ded0..5850d269a5 100644 --- a/bsp/ls1cdev/rtconfig.h +++ b/bsp/ls1cdev/rtconfig.h @@ -1,243 +1,260 @@ -#ifndef __RTTHREAD_CFG_H__ -#define __RTTHREAD_CFG_H__ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ -// +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ -// -#define RT_NAME_MAX 10 -// -#define RT_ALIGN_SIZE 8 -// -// 8 -// 32 -// 256 -// -#define RT_THREAD_PRIORITY_MAX 32 -// -#define RT_TICK_PER_SECOND 1000 -//
+/* RT-Thread Kernel */ + +#define RT_NAME_MAX 10 +#define RT_ALIGN_SIZE 8 +/* RT_THREAD_PRIORITY_8 is not set */ +#define RT_THREAD_PRIORITY_32 +/* RT_THREAD_PRIORITY_256 is not set */ +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 #define RT_DEBUG -// -// #define RT_THREAD_DEBUG -// #define RT_USING_OVERFLOW_CHECK -// -#define RT_USING_INTERRUPT_INFO -// -#define IDLE_THREAD_STACK_SIZE 1024 -//
- -// +#define RT_DEBUG_INIT 0 +#define RT_DEBUG_THREAD 0 #define RT_USING_HOOK -//
-// #define RT_USING_TIMER_SOFT -// -#define RT_TIMER_THREAD_PRIO 4 -// -#define RT_TIMER_THREAD_STACK_SIZE 512 -// -#define RT_TIMER_TICK_PER_SECOND 10 -//
+#define IDLE_THREAD_STACK_SIZE 1024 +/* RT_USING_TIMER_SOFT is not set */ + +/* Inter-Thread communication */ -//
-// #define RT_USING_SEMAPHORE -// #define RT_USING_MUTEX -// #define RT_USING_EVENT -// #define RT_USING_MAILBOX -// #define RT_USING_MESSAGEQUEUE -//
+/* RT_USING_SIGNALS is not set */ + +/* Memory Management */ -//
-// #define RT_USING_MEMPOOL -// #define RT_USING_MEMHEAP -// -#define RT_USING_HEAP -// +/* RT_USING_NOHEAP is not set */ #define RT_USING_SMALL_MEM -// -// #define RT_USING_SLAB -//
+/* RT_USING_SLAB is not set */ +/* RT_USING_MEMHEAP_AS_HEAP is not set */ +/* RT_USING_MEMTRACE is not set */ +#define RT_USING_HEAP + +/* Kernel Device Object */ -//
#define RT_USING_DEVICE -// -#define RT_USING_UART -// -#define RT_USING_UART2 -// -#define RT_UART_RX_BUFFER_SIZE 64 -//
- -#define RT_USING_FPU - -//
+#define RT_USING_INTERRUPT_INFO #define RT_USING_CONSOLE -// -#define RT_CONSOLEBUF_SIZE 128 -// -#define RT_CONSOLE_DEVICE_NAME "uart2" -//
+#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart2" +/* RT_USING_MODULE is not set */ + +/* RT-Thread Components */ -// #define RT_USING_COMPONENTS_INIT -//
+/* RT_USING_USER_MAIN is not set */ + +/* C++ features */ + +/* RT_USING_CPLUSPLUS is not set */ + +/* Command shell */ + #define RT_USING_FINSH -// +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB -// #define FINSH_USING_DESCRIPTION -// -#define FINSH_THREAD_STACK_SIZE 4096 -// +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +/* FINSH_USING_AUTH is not set */ #define FINSH_USING_MSH -// #define FINSH_USING_MSH_DEFAULT -//
+/* FINSH_USING_MSH_ONLY is not set */ -//
-#define RT_USING_LIBC -// -#define RT_USING_PTHREADS -//
+/* Device virtual file system */ -//
-// #define RT_USING_DFS -// -// #define DFS_USING_WORKDIR -// -#define DFS_FILESYSTEMS_MAX 2 -// -#define DFS_FD_MAX 4 -// +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 4 #define RT_USING_DFS_ELMFAT -// -// 1 -// 2 -// -#define RT_DFS_ELM_USE_LFN 1 -// -#define RT_DFS_ELM_MAX_LFN 64 -// -// #define RT_USING_DFS_YAFFS2 -// -// #define RT_USING_DFS_UFFS -// -// #define RT_USING_DFS_DEVFS -// -// #define RT_USING_DFS_NFS -// -#define RT_NFS_HOST_EXPORT "192.168.1.254:/" -//
-//
-#define RT_USING_LWIP -#define RT_USING_GMAC_INT_MODE -#define RT_USING_LWIP141 -//#define RT_LWIP_DEBUG +/* elm-chan's FatFs, Generic FAT Filesystem Module */ -// -#define RT_LWIP_ICMP -// -#define RT_LWIP_IGMP -// -#define RT_LWIP_UDP -// -#define RT_LWIP_TCP -// -#define RT_LWIP_DNS -// -#define RT_LWIP_PBUF_NUM 4 -#define RT_LWIP_PBUF_POOL_BUFSIZE 2048 -// -#define RT_LWIP_TCP_PCB_NUM 3 -// -#define RT_LWIP_TCP_SND_BUF 4096 -// -#define RT_LWIP_TCP_WND 2048 -// -// #define RT_LWIP_SNMP -// -// #define RT_LWIP_DHCP -// -#define RT_LWIP_TCP_SEG_NUM 40 -// -#define RT_LWIP_TCPTHREAD_PRIORITY 12 -// -#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 -// -#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 -// -#define RT_LWIP_ETHTHREAD_PRIORITY 14 -// -#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 -// -#define RT_LWIP_ETHTHREAD_STACKSIZE 512 +#define RT_DFS_ELM_CODE_PAGE 936 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_0 +/* RT_DFS_ELM_USE_LFN_1 is not set */ +/* RT_DFS_ELM_USE_LFN_2 is not set */ +/* RT_DFS_ELM_USE_LFN_3 is not set */ +#define RT_DFS_ELM_USE_LFN 0 +#define RT_DFS_ELM_MAX_LFN 64 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +/* RT_DFS_ELM_USE_ERASE is not set */ +#define RT_DFS_ELM_REENTRANT +/* RT_USING_DFS_DEVFS is not set */ +/* RT_USING_DFS_NET is not set */ +/* RT_USING_DFS_ROMFS is not set */ +/* RT_USING_DFS_RAMFS is not set */ +/* RT_USING_DFS_UFFS is not set */ +/* RT_USING_DFS_JFFS2 is not set */ +/* RT_USING_DFS_NFS is not set */ -/* ip address of target */ -#define RT_LWIP_IPADDR "192.168.1.254" - -/* gateway address of target */ -#define RT_LWIP_GWADDR "192.168.1.1" - -/* mask address of target */ -#define RT_LWIP_MSKADDR "255.255.255.0" - -//
- -//
-// #define RT_USING_MODULE -// -// #define RT_USING_LIBDL -//
- -//
-// #define RT_USING_RTGUI -// -#define RTGUI_NAME_MAX 16 -// -#define RTGUI_USING_FONT16 -// -#define RTGUI_USING_FONT12 -// -#define RTGUI_USING_FONTHZ -// -#define RTGUI_USING_DFS_FILERW -// -// #define RTGUI_USING_HZ_FILE -// -#define RTGUI_USING_HZ_BMP -// -#define RTGUI_USING_SMALL_SIZE -// -// #define RTGUI_USING_MOUSE_CURSOR -// -#define RTGUI_IMAGE_XPM -// -// #define RTGUI_IMAGE_JPEG -// -// #define RTGUI_IMAGE_PNG -// -#define RTGUI_IMAGE_BMP -//
- -#define RT_USING_SPI -#define RT_USING_SPI0 -#define RT_USING_SPI1 +/* Device Drivers */ +#define RT_USING_DEVICE_IPC +#define RT_USING_SERIAL +#define RT_USING_CAN +#define RT_CAN_USING_HDR +/* RT_USING_HWTIMER is not set */ +/* RT_USING_CPUTIME is not set */ #define RT_USING_I2C #define RT_USING_I2C_BITOPS - - #define RT_USING_PIN +/* RT_USING_MTD_NOR is not set */ +/* RT_USING_MTD_NAND is not set */ +/* RT_USING_RTC is not set */ +/* RT_USING_SDIO is not set */ +#define RT_USING_SPI +#define RT_USING_SPI_MSD +/* RT_USING_SFUD is not set */ +/* RT_USING_W25QXX is not set */ +/* RT_USING_GD is not set */ +/* RT_USING_ENC28J60 is not set */ +/* RT_USING_SPI_WIFI is not set */ +/* RT_USING_WDT is not set */ +/* RT_USING_WIFI is not set */ +/* Using USB */ -//
+/* RT_USING_USB_HOST is not set */ +/* RT_USING_USB_DEVICE is not set */ + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_PTHREADS +/* RT_USING_POSIX is not set */ +/* HAVE_SYS_SIGNALS is not set */ + +/* Network stack */ + +/* light weight TCP/IP stack */ + +#define RT_USING_LWIP +#define RT_USING_LWIP141 +/* RT_USING_LWIP202 is not set */ +#define RT_LWIP_IGMP +#define RT_LWIP_ICMP +/* RT_LWIP_SNMP is not set */ +#define RT_LWIP_DNS +/* RT_LWIP_DHCP is not set */ + +/* Static IPv4 Address */ + +#define RT_LWIP_IPADDR "192.168.1.254" +#define RT_LWIP_GWADDR "192.168.1.1" +#define RT_LWIP_MSKADDR "255.255.255.0" +#define RT_LWIP_UDP +#define RT_LWIP_TCP +/* RT_LWIP_RAW is not set */ +/* RT_LWIP_PPP is not set */ +#define RT_MEMP_NUM_NETCONN 8 +#define RT_LWIP_PBUF_NUM 4 +#define RT_LWIP_RAW_PCB_NUM 4 +#define RT_LWIP_UDP_PCB_NUM 4 +#define RT_LWIP_TCP_PCB_NUM 3 +#define RT_LWIP_TCP_SEG_NUM 40 +#define RT_LWIP_TCP_SND_BUF 4096 +#define RT_LWIP_TCP_WND 2048 +#define RT_LWIP_TCPTHREAD_PRIORITY 12 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 +#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 +#define RT_LWIP_ETHTHREAD_PRIORITY 14 +#define RT_LWIP_ETHTHREAD_STACKSIZE 512 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 +/* RT_LWIP_REASSEMBLY_FRAG is not set */ +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define SO_REUSE 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_SO_RCVBUF 1 +/* RT_LWIP_NETIF_LOOPBACK is not set */ +#define LWIP_NETIF_LOOPBACK 0 + +/* Modbus master and slave stack */ + +/* RT_USING_MODBUS is not set */ +/* LWIP_USING_DHCPD is not set */ + +/* VBUS(Virtual Software BUS) */ + +/* RT_USING_VBUS is not set */ + +/* Utilities */ + +/* RT_USING_LOGTRACE is not set */ +/* RT_USING_RYM is not set */ + +/* RT-Thread online packages */ + +/* system packages */ + +/* PKG_USING_PARTITION is not set */ +/* PKG_USING_SQLITE is not set */ +/* PKG_USING_RTI is not set */ + +/* IoT - internet of things */ + +/* PKG_USING_PAHOMQTT is not set */ +/* PKG_USING_WEBCLIENT is not set */ +/* PKG_USING_MONGOOSE is not set */ +/* PKG_USING_WEBTERMINAL is not set */ +/* PKG_USING_CJSON is not set */ +/* PKG_USING_EZXML is not set */ +/* PKG_USING_NANOPB is not set */ + +/* security packages */ + +/* PKG_USING_MBEDTLS is not set */ +/* PKG_USING_libsodium is not set */ + +/* language packages */ + +/* PKG_USING_JERRYSCRIPT is not set */ +/* PKG_USING_MICROPYTHON is not set */ + +/* multimedia packages */ + +/* tools packages */ + +/* PKG_USING_CMBACKTRACE is not set */ +/* PKG_USING_EASYLOGGER is not set */ +/* PKG_USING_SYSTEMVIEW is not set */ + +/* miscellaneous packages */ + +/* PKG_USING_FASTLZ is not set */ +/* PKG_USING_MINILZO is not set */ + +/* example package: hello */ + +/* PKG_USING_HELLO is not set */ +#define RT_USING_UART2 +#define RT_UART_RX_BUFFER_SIZE 64 +#define RT_USING_GMAC_INT_MODE +#define RT_USING_FPU +#define RT_USING_SPI0 +#define RT_USING_SPI1 +#define RT_USING_I2C1 +#define RT_USING_I2C2 +#define USING_BXCAN0 +#define USING_BXCAN1 #endif