From b40a8f816b7333dc42ef9a723d9ff710803de236 Mon Sep 17 00:00:00 2001 From: yufanyufan77 <765637468@qq.com> Date: Fri, 14 Dec 2018 08:58:40 +0800 Subject: 添加cpu复位函数 RT_WEAK void rt_hw_cpu_reset(void) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/cortex-m0/cpuport.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'libcpu') diff --git a/libcpu/arm/cortex-m0/cpuport.c b/libcpu/arm/cortex-m0/cpuport.c index f5ff8ec113..5d36fa11fe 100644 --- a/libcpu/arm/cortex-m0/cpuport.c +++ b/libcpu/arm/cortex-m0/cpuport.c @@ -114,3 +114,22 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *contex) while (1); } + +#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */ +#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ +#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ +#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */ +#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ + +#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ +#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */ +#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */ + +/** + * reset CPU + */ +RT_WEAK void rt_hw_cpu_reset(void) +{ + SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk); +} -- cgit v1.3.1 From fd347fdb9026af8f2b15d362c1118cab46ffc2c9 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sat, 15 Dec 2018 11:47:10 +0800 Subject: [libcpu][risc-v] fix the rt_thread_switch_interrupt_flag issue --- libcpu/risc-v/e310/interrupt_gcc.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libcpu') diff --git a/libcpu/risc-v/e310/interrupt_gcc.S b/libcpu/risc-v/e310/interrupt_gcc.S index 297851d71e..1eac7af90a 100644 --- a/libcpu/risc-v/e310/interrupt_gcc.S +++ b/libcpu/risc-v/e310/interrupt_gcc.S @@ -69,9 +69,9 @@ trap_entry: /* need to switch new thread */ la s0, rt_thread_switch_interrupt_flag - LOAD s2, 0(s0) + lw s2, 0(s0) beqz s2, spurious_interrupt - STORE zero, 0(s0) + sw zero, 0(s0) csrr a0, mepc STORE a0, 0 * REGBYTES(sp) -- cgit v1.3.1 From 885d99ee9b76bfdd838d5b3f358137fe255d92e7 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sat, 15 Dec 2018 11:47:59 +0800 Subject: [libcpu][risc-v] fix rt_thread_switch_interrupt_flag issue. --- libcpu/risc-v/rv32m1/interrupt_gcc.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libcpu') diff --git a/libcpu/risc-v/rv32m1/interrupt_gcc.S b/libcpu/risc-v/rv32m1/interrupt_gcc.S index d74cf441bc..eacf667c67 100644 --- a/libcpu/risc-v/rv32m1/interrupt_gcc.S +++ b/libcpu/risc-v/rv32m1/interrupt_gcc.S @@ -69,10 +69,10 @@ IRQ_Handler: /* need to switch new thread */ la s0, rt_thread_switch_interrupt_flag - LOAD s2, 0(s0) + lw s2, 0(s0) beqz s2, spurious_interrupt /* clear switch interrupt flag */ - STORE zero, 0(s0) + sw zero, 0(s0) csrr a0, mepc STORE a0, 0 * REGBYTES(sp) -- cgit v1.3.1 From 5e0f8cb3aa0d9459985bf0345eef0192857d1b41 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Tue, 18 Dec 2018 21:01:03 +0800 Subject: [libcpu] Add k210 BSP. --- bsp/k210/.config | 374 +++++++++++++++++++++++++++++++++++++ bsp/k210/Kconfig | 31 +++ bsp/k210/README.md | 93 +++++++++ bsp/k210/SConscript | 14 ++ bsp/k210/SConstruct | 35 ++++ bsp/k210/applications/SConscript | 9 + bsp/k210/applications/main.c | 19 ++ bsp/k210/applications/mnt.c | 15 ++ bsp/k210/driver/Kconfig | 25 +++ bsp/k210/driver/SConscript | 38 ++++ bsp/k210/driver/board.c | 115 ++++++++++++ bsp/k210/driver/board.h | 22 +++ bsp/k210/driver/drv_uart.c | 209 +++++++++++++++++++++ bsp/k210/driver/drv_uart.h | 16 ++ bsp/k210/images/flash.png | Bin 0 -> 7624 bytes bsp/k210/images/k210.png | Bin 0 -> 7493 bytes bsp/k210/link.lds | 160 ++++++++++++++++ bsp/k210/link_stacksize.lds | 1 + bsp/k210/rtconfig.h | 178 ++++++++++++++++++ bsp/k210/rtconfig.py | 58 ++++++ libcpu/risc-v/k210/interrupt.c | 203 ++++++++++++++++++++ libcpu/risc-v/k210/interrupt_gcc.S | 137 ++++++++++++++ libcpu/risc-v/k210/startup_gcc.S | 128 +++++++++++++ libcpu/risc-v/k210/tick.c | 48 +++++ libcpu/risc-v/k210/tick.h | 17 ++ 25 files changed, 1945 insertions(+) create mode 100644 bsp/k210/.config create mode 100644 bsp/k210/Kconfig create mode 100644 bsp/k210/README.md create mode 100644 bsp/k210/SConscript create mode 100644 bsp/k210/SConstruct create mode 100644 bsp/k210/applications/SConscript create mode 100644 bsp/k210/applications/main.c create mode 100644 bsp/k210/applications/mnt.c create mode 100644 bsp/k210/driver/Kconfig create mode 100644 bsp/k210/driver/SConscript create mode 100644 bsp/k210/driver/board.c create mode 100644 bsp/k210/driver/board.h create mode 100644 bsp/k210/driver/drv_uart.c create mode 100644 bsp/k210/driver/drv_uart.h create mode 100644 bsp/k210/images/flash.png create mode 100644 bsp/k210/images/k210.png create mode 100644 bsp/k210/link.lds create mode 100644 bsp/k210/link_stacksize.lds create mode 100644 bsp/k210/rtconfig.h create mode 100644 bsp/k210/rtconfig.py create mode 100644 libcpu/risc-v/k210/interrupt.c create mode 100644 libcpu/risc-v/k210/interrupt_gcc.S create mode 100644 libcpu/risc-v/k210/startup_gcc.S create mode 100644 libcpu/risc-v/k210/tick.c create mode 100644 libcpu/risc-v/k210/tick.h (limited to 'libcpu') diff --git a/bsp/k210/.config b/bsp/k210/.config new file mode 100644 index 0000000000..d1279d3b74 --- /dev/null +++ b/bsp/k210/.config @@ -0,0 +1,374 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_SMP is not set +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=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=1024 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_INIT_CONFIG=y +CONFIG_RT_DEBUG_INIT=1 +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uarths" +CONFIG_RT_VER_NUM=0x40000 +CONFIG_ARCH_CPU_64BIT=y +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_RISCV64=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# 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_ECHO_DISABLE_DEFAULT is not set +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=y +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +CONFIG_DFS_FD_MAX=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# 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 + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_MTD is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set + +# +# Using WiFi +# +# 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 is not set +CONFIG_RT_USING_POSIX=y +# CONFIG_RT_USING_POSIX_MMAP is not set +# CONFIG_RT_USING_POSIX_TERMIOS is not set +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT 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 +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET 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_JSMN is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTKIT is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_PCF8574 is not set +CONFIG_PKG_USING_KENDRYTE_SDK=y +CONFIG_PKG_KENDRYTE_SDK_PATH="/packages/peripherals/kendryte-sdk" +CONFIG_PKG_USING_KENDRYTE_SDK_V052=y +# CONFIG_PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set +CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2" + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set + +# +# sample package +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set + +# +# Privated Packages of RealThread +# +# CONFIG_PKG_USING_CODEC is not set +# CONFIG_PKG_USING_PLAYER is not set +# CONFIG_PKG_USING_PERSIMMON_SRC is not set +# CONFIG_PKG_USING_JS_PERSIMMON is not set +# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set + +# +# Network Utilities +# +# CONFIG_PKG_USING_WICED is not set +# CONFIG_PKG_USING_CLOUDSDK is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_POWER_MANAGER is not set +# CONFIG_PKG_USING_RT_OTA is not set +# CONFIG_PKG_USING_RDBD_SRC is not set +# CONFIG_PKG_USING_RTINSIGHT is not set +# CONFIG_PKG_USING_SMARTCONFIG is not set +# CONFIG_PKG_USING_RTX is not set +CONFIG_BOARD_K210_EVB=y +CONFIG_BSP_USING_UART_HS=y +# CONFIG_BSP_USING_UART1 is not set +# CONFIG_BSP_USING_UART2 is not set +# CONFIG_BSP_USING_UART3 is not set +# CONFIG_BSP_USING_I2C1 is not set +# CONFIG_BSP_USING_SPI1 is not set +CONFIG___STACKSIZE__=4096 diff --git a/bsp/k210/Kconfig b/bsp/k210/Kconfig new file mode 100644 index 0000000000..ccb4adf6dc --- /dev/null +++ b/bsp/k210/Kconfig @@ -0,0 +1,31 @@ +mainmenu "RT-Thread Project 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" + +config BOARD_K210_EVB + bool + select ARCH_RISCV64 + select PKG_USING_KENDRYTE_SDK + default y + +source "driver/Kconfig" + +config __STACKSIZE__ + int "stack size for interrupt" + default 4096 diff --git a/bsp/k210/README.md b/bsp/k210/README.md new file mode 100644 index 0000000000..6de922d7a2 --- /dev/null +++ b/bsp/k210/README.md @@ -0,0 +1,93 @@ +# Kendryte K210板级支持包说明 + +## 1. 简介 + +Kendryte K210 是集成机器视觉与机器听觉能力的系统级芯片(SoC)。使用台积电 (TSMC) 超低功耗的 28 纳米先进制程,具有双核64位处理器,拥有较好的功耗性能,稳定性与可靠性。该方案力求零门槛开发,可在最短时效部署于用户的产品中,赋予产品人工智能。 + +Kendryte K210 定位于AI与IoT市场的SoC,同时是使用非常方便的MCU。 + +Kendryte中文含义为勘智,而勘智取自勘物探智。这颗芯片主要应用领域为物联网领域,在物联网领域进行开发,因此为勘物;这颗芯片主要提供的是人工智能解决方案,在人工智能领域探索,因此为探智。 + +* 具备机器视觉能力 +* 具备机器听觉能力 +* 更好的低功耗视觉处理速度与准确率 +* 具备卷积人工神经网络硬件加速器KPU,可高性能进行卷积人工神经网络运算 +* TSMC 28nm先进制程,温度范围-40°C到125°C,稳定可靠 +* 支持固件加密,难以使用普通方法破解 +* 独特的可编程IO阵列,使产品设计更加灵活 +* 低电压,与相同处理能力的系统相比具有更低功耗 +* 3.3V/1.8V双电压支持,无需电平转换,节约成本 + +芯片规格包括如下: + +| 硬件 | 描述 | +| -- | -- | +|芯片型号| K210 | +|CPU| 双核RV64GC | +|主频| 400MHz | +|片内SRAM| 8MB | +| 外设 | 内嵌AES与SHA256算法加速器 | +| | DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM | + +## 2. 编译说明 + +编译K210,需要先下载K210 BSP以及RT-Thread代码: + + git clone https://github.com/BernardXiong/K210.git + cd K210 + git submodule init + git submodule update + + git clone https://github.com/RT-Thread/rt-thread.git + cd rt-thread + git checkout -b dev-4.0.x origin/dev-4.0.x + +注意,因为RT-Thread整体代码太庞大,所以并未把RT-Thread git repo以一个submodule方式加入到K210 BSP git repo中, +而是需要把RT-Thread代码克隆到K210目录下,并切换到dev-4.0.x分支。 + +编译推荐使用[env工具][1],可以在console下进入到`K210`目录中,运行以下命令: + + set RTT_EXEC_PATH=your_toolchains + scons + +来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin需要烧写到设备中进行运行。 + +## 3. 烧写及执行 + +连接好串口,然后使用[K-Flash](https://kendryte.com/downloads/)工具进行烧写bin文件。 + +![K-Flash](images/flash.png) + +### 3.1 运行结果 + +如果编译 & 烧写无误,当复位设备后,会在串口上看到RT-Thread的启动logo信息: + +![terminal](images/k210.png) + +## 4. 驱动支持情况及计划 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | 高速UART,用于shell | + +## 5. 联系人信息 + +维护人:[bernard](https://github.com/BernardXiong) + +## 6. 注意事项 + +在进行系统menuconfig配置时,以下项是必选的 + +| 配置项 | 强制配置值 | +| ----- | --------- | +| Alignment size for CPU architecture data access | 8 | +| The stack size of idle thread | > 1024 | +| the device name for console | "uarths" | +| Set main thread stack size | 4096 | + +## 7. 参考 + +* 芯片[datasheet][2] + + [1]: https://www.rt-thread.org/page/download.html + [2]: https://s3.cn-north-1.amazonaws.com.cn/dl.kendryte.com/documents/kendryte_datasheet_20180919020633.pdf diff --git a/bsp/k210/SConscript b/bsp/k210/SConscript new file mode 100644 index 0000000000..c7ef7659ec --- /dev/null +++ b/bsp/k210/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/k210/SConstruct b/bsp/k210/SConstruct new file mode 100644 index 0000000000..dc55b29194 --- /dev/null +++ b/bsp/k210/SConstruct @@ -0,0 +1,35 @@ +import os +import sys +import rtconfig + +from rtconfig import RTT_ROOT + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) + +stack_size = 4096 + +stack_lds = open('link_stacksize.lds', 'w') +if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__') +stack_lds.write('__STACKSIZE__ = %d;' % stack_size) +stack_lds.close() + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/k210/applications/SConscript b/bsp/k210/applications/SConscript new file mode 100644 index 0000000000..c583d3016e --- /dev/null +++ b/bsp/k210/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/k210/applications/main.c b/bsp/k210/applications/main.c new file mode 100644 index 0000000000..b18163ef8d --- /dev/null +++ b/bsp/k210/applications/main.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/09/30 Bernard The first version + */ + +#include +#include + +int main(void) +{ + rt_kprintf("Hello, world\n"); + + return 0; +} diff --git a/bsp/k210/applications/mnt.c b/bsp/k210/applications/mnt.c new file mode 100644 index 0000000000..d528a7424d --- /dev/null +++ b/bsp/k210/applications/mnt.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include + +int mnt_init(void) +{ + return 0; +} diff --git a/bsp/k210/driver/Kconfig b/bsp/k210/driver/Kconfig new file mode 100644 index 0000000000..902d7c2444 --- /dev/null +++ b/bsp/k210/driver/Kconfig @@ -0,0 +1,25 @@ +config BSP_USING_UART_HS + bool "Enable High Speed UART" + default y + +config BSP_USING_UART1 + bool "Enable UART1 (GPIO0/1)" + default n + +config BSP_USING_UART2 + bool "Enable UART2 (GPIO0/1)" + default n + +config BSP_USING_UART3 + bool "Enable UART3 (GPIO0/1)" + default n + +config BSP_USING_I2C1 + bool "Enable I2C1 (GPIO0/1)" + select RT_USING_I2C + default n + +config BSP_USING_SPI1 + bool "Enable SPI1 (GPIO0/1)" + select RT_USING_SPI + default n diff --git a/bsp/k210/driver/SConscript b/bsp/k210/driver/SConscript new file mode 100644 index 0000000000..3ea01aa83f --- /dev/null +++ b/bsp/k210/driver/SConscript @@ -0,0 +1,38 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +board.c +drv_uart.c +''') +CPPPATH = [cwd] + +if GetDepend('RT_USING_PIN'): + src += ['drv_gpio.c'] + +if GetDepend('RT_USING_HWTIMER'): + src += ['drv_hw_timer.c'] + +if GetDepend('RT_USING_CPUTIME'): + src += ['drv_cputime.c'] + +if GetDepend('RT_USING_I2C'): + src += ['drv_i2c.c'] + +if GetDepend('RT_USING_SPI'): + src += ['drv_spi.c'] + +if GetDepend('RT_USING_PWM'): + src += ['drv_pwm.c'] + +if GetDepend('RT_USING_RTC'): + src += ['drv_rtc.c'] + +if GetDepend('RT_USING_WDT'): + src += ['drv_wdt.c'] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/k210/driver/board.c b/bsp/k210/driver/board.c new file mode 100644 index 0000000000..aac2adbc49 --- /dev/null +++ b/bsp/k210/driver/board.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include +#include + +#include "board.h" +#include "tick.h" + +#include "drv_uart.h" + +#include "encoding.h" +#include "fpioa.h" +#include "dmac.h" + +#include "uarths.h" +void rt_hw_console_output(const char *str) +{ + uarths_puts(str); + return ; +} + +void init_bss(void) +{ + unsigned int *dst; + + dst = &__bss_start; + while (dst < &__bss_end) + { + *dst++ = 0; + } +} + +void cpu_entry(int cpuid) +{ + extern void entry(void); + + /* disable global interrupt */ + rt_hw_interrupt_disable(); + if (cpuid == 0) + { + init_bss(); + entry(); + } + else + { + while (1) ; + } +} + +#include +#include + +int freq(void) +{ + rt_uint64_t value = 0; + + value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL0); + rt_kprintf("PLL0: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL1); + rt_kprintf("PLL1: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL2); + rt_kprintf("PLL2: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU); + rt_kprintf("CPU : %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0); + rt_kprintf("APB0: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1); + rt_kprintf("APB1: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB2); + rt_kprintf("APB2: %d\n", value); + value = sysctl_clock_get_freq(SYSCTL_CLOCK_HCLK); + rt_kprintf("HCLK: %d\n", value); + + value = clint_get_time(); + rt_kprintf("mtime: %d\n", value); + + return 0; +} +MSH_CMD_EXPORT(freq, show freq info); + +void rt_hw_board_init(void) +{ + /* Init FPIOA */ + fpioa_init(); + /* Dmac init */ + dmac_init(); + + /* initalize interrupt */ + rt_hw_interrupt_init(); + /* initialize hardware interrupt */ + rt_hw_uart_init(); + rt_hw_tick_init(); + +#ifdef RT_USING_CONSOLE + /* set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif /* RT_USING_CONSOLE */ + +#ifdef RT_USING_HEAP + rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END); + /* initialize memory system */ + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} diff --git a/bsp/k210/driver/board.h b/bsp/k210/driver/board.h new file mode 100644 index 0000000000..0d270abd2b --- /dev/null +++ b/bsp/k210/driver/board.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#ifndef BOARD_H__ +#define BOARD_H__ + +extern unsigned int __bss_start; +extern unsigned int __bss_end; + +#define RT_HW_HEAP_BEGIN (void*)&__bss_end +#define RT_HW_HEAP_END (void*)(0x80000000 + 6 * 1024 * 1024) + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/k210/driver/drv_uart.c b/bsp/k210/driver/drv_uart.c new file mode 100644 index 0000000000..74ba05e203 --- /dev/null +++ b/bsp/k210/driver/drv_uart.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#include + +// #include "uart.h" +#include "uarths.h" +#include "plic.h" + +struct device_uart +{ + rt_uint32_t hw_base; + rt_uint32_t irqno; +}; + +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg); +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg); +static int drv_uart_putc(struct rt_serial_device *serial, char c); +static int drv_uart_getc(struct rt_serial_device *serial); + +static void uart_irq_handler(int irqno, void *param); + +const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + drv_uart_putc, + drv_uart_getc, + RT_NULL +}; + +/* + * UART Initiation + */ +int rt_hw_uart_init(void) +{ + struct rt_serial_device *serial; + struct device_uart *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef BSP_USING_UART_HS + { + static struct rt_serial_device serial_hs; + static struct device_uart uart_hs; + + serial = &serial_hs; + uart = &uart_hs; + + serial->ops = &_uart_ops; + serial->config = config; + serial->config.baud_rate = 115200; + + uart->hw_base = UARTHS_BASE_ADDR; + uart->irqno = IRQN_UARTHS_INTERRUPT; + + /* initialize UART HS */ + uarths_init(); + + rt_hw_serial_register(serial, + "uarths", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + } +#endif + +#ifdef BSP_USING_UART1 + { + static struct rt_serial_device serial1; + static struct device_uart uart1; + + serial = &serial1; + uart = &uart1; + + serial->ops = &_uart_ops; + serial->config = config; + serial->config.baud_rate = 115200; + + uart->hw_base = UART1_BASE_ADDR; + uart->irqno = IRQN_UART1_INTERRUPT; + + rt_hw_serial_register(serial, + "uarths", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + } +#endif + +#ifdef BSP_USING_UART2 +#endif + +#ifdef BSP_USING_UART3 +#endif + + return 0; +} + +/* + * UART interface + */ +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + rt_uint32_t baud_div; + struct device_uart *uart; + + RT_ASSERT(serial != RT_NULL); + serial->config = *cfg; + + uart = serial->parent.user_data; + RT_ASSERT(uart != RT_NULL); + + /* Init UART Hardware */ + + /* Enable UART clock */ + + /* Set both receiver and transmitter in UART mode (not SIR) */ + + /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ + + /* set baudrate */ + + return (RT_EOK); +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct device_uart *uart; + + uart = serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* Disable the UART Interrupt */ + rt_hw_interrupt_mask(uart->irqno); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* install interrupt */ + rt_hw_interrupt_install(uart->irqno, uart_irq_handler, + serial, serial->parent.parent.name); + rt_hw_interrupt_umask(uart->irqno); + break; + } + + return (RT_EOK); +} + +static int drv_uart_putc(struct rt_serial_device *serial, char c) +{ + struct device_uart *uart; + + uart = serial->parent.user_data; + if (uart->hw_base == UARTHS_BASE_ADDR) + { + uarths_putchar(c); + } + else + { + /* other uart */ + } + + return (1); +} + +static int drv_uart_getc(struct rt_serial_device *serial) +{ + int ret = -1; + struct device_uart *uart = serial->parent.user_data; + + if (uart->hw_base == UARTHS_BASE_ADDR) + { + ret = uarths_getc(); + if (ret != EOF) return ret; + } + + /* Receive Data Available */ + + return (-1); +} + +/* UART ISR */ +static void uart_irq_handler(int irqno, void *param) +{ + rt_ubase_t isr; + struct rt_serial_device *serial = (struct rt_serial_device *)param; + struct device_uart *uart = serial->parent.user_data; + + /* read interrupt status and clear it */ + if (uart->hw_base == UARTHS_BASE_ADDR) + { + if (uarths->ip.rxwm) + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } +} diff --git a/bsp/k210/driver/drv_uart.h b/bsp/k210/driver/drv_uart.h new file mode 100644 index 0000000000..deac702fe1 --- /dev/null +++ b/bsp/k210/driver/drv_uart.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/01 Bernard The first version + */ + +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ + +int rt_hw_uart_init(void); + +#endif /* __DRV_UART_H__ */ diff --git a/bsp/k210/images/flash.png b/bsp/k210/images/flash.png new file mode 100644 index 0000000000..2a3c6eaf61 Binary files /dev/null and b/bsp/k210/images/flash.png differ diff --git a/bsp/k210/images/k210.png b/bsp/k210/images/k210.png new file mode 100644 index 0000000000..2d59f3aa58 Binary files /dev/null and b/bsp/k210/images/k210.png differ diff --git a/bsp/k210/link.lds b/bsp/k210/link.lds new file mode 100644 index 0000000000..851861f19f --- /dev/null +++ b/bsp/k210/link.lds @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +INCLUDE "link_stacksize.lds" + +/* + * The OUTPUT_ARCH command specifies the machine architecture where the + * argument is one of the names used in the Kendryte library. + */ +OUTPUT_ARCH( "riscv" ) + +MEMORY +{ + /* 6M SRAM */ + SRAM : ORIGIN = 0x80000000, LENGTH = 0x600000 +} + +ENTRY(_start) +SECTIONS +{ + . = 0x80000000 ; + + /* __STACKSIZE__ = 4096; */ + + .start : + { + *(.start); + } > SRAM + + . = ALIGN(4); + + .text : + { + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > SRAM + + .eh_frame_hdr : + { + *(.eh_frame_hdr) + *(.eh_frame_entry) + } > SRAM + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > SRAM + + . = ALIGN(4); + + .data : + { + *(.data) + *(.data.*) + + *(.data1) + *(.data1.*) + + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + + *(.sdata) + *(.sdata.*) + } > SRAM + + /* stack for dual core */ + .stack : + { + . = ALIGN(64); + __stack_start__ = .; + + . += __STACKSIZE__; + __stack_cpu0 = .; + + . += __STACKSIZE__; + __stack_cpu1 = .; + } > SRAM + + .sbss : + { + __bss_start = .; + *(.sbss) + *(.sbss.*) + *(.dynsbss) + *(.scommon) + } > SRAM + + .bss : + { + *(.bss) + *(.bss.*) + *(.dynbss) + *(COMMON) + __bss_end = .; + } > SRAM + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/k210/link_stacksize.lds b/bsp/k210/link_stacksize.lds new file mode 100644 index 0000000000..1dd893422c --- /dev/null +++ b/bsp/k210/link_stacksize.lds @@ -0,0 +1 @@ +__STACKSIZE__ = 4096; \ No newline at end of file diff --git a/bsp/k210/rtconfig.h b/bsp/k210/rtconfig.h new file mode 100644 index 0000000000..629a34f31c --- /dev/null +++ b/bsp/k210/rtconfig.h @@ -0,0 +1,178 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 8 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDEL_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_DEBUG +#define RT_DEBUG_INIT_CONFIG +#define RT_DEBUG_INIT 1 + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uarths" +#define RT_VER_NUM 0x40000 +#define ARCH_CPU_64BIT +#define ARCH_RISCV +#define ARCH_RISCV64 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* 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_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_USING_MSH_ONLY +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define DFS_FD_MAX 16 +#define RT_USING_DFS_DEVFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_USING_PIN + +/* Using WiFi */ + + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_POSIX + +/* Network */ + +/* Socket abstraction layer */ + + +/* light weight TCP/IP stack */ + + +/* Modbus master and slave stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + +#define PKG_USING_KENDRYTE_SDK +#define PKG_USING_KENDRYTE_SDK_V052 + +/* miscellaneous packages */ + + +/* sample package */ + +/* samples: kernel and components samples */ + + +/* example package: hello */ + + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + +#define BOARD_K210_EVB +#define BSP_USING_UART_HS +#define __STACKSIZE__ 4096 + +#endif diff --git a/bsp/k210/rtconfig.py b/bsp/k210/rtconfig.py new file mode 100644 index 0000000000..c2df896f4c --- /dev/null +++ b/bsp/k210/rtconfig.py @@ -0,0 +1,58 @@ +import os + +# toolchains options +ARCH ='risc-v' +CPU ='k210' +CROSS_TOOL ='gcc' + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = r'rt-thread' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'/opt/riscv64-unknown-elf-gcc-2018.07.0-x86_64-linux-ubuntu14/bin' +else: + print('Please make sure your toolchains is GNU GCC!') + exit(0) + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'release' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'riscv-none-embed-' + # PREFIX = 'riscv64-unknown-elf-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcmodel=medany' + CFLAGS = DEVICE + ' -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields ' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -ggdb' + AFLAGS += ' -ggdb' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c new file mode 100644 index 0000000000..6d8866c3f0 --- /dev/null +++ b/libcpu/risc-v/k210/interrupt.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/01 Bernard The first version + */ + +#include + +#include "tick.h" + +#include +#include +#include + +#define CPU_NUM 2 +#define MAX_HANDLERS IRQN_MAX + +static struct rt_irq_desc irq_desc[CPU_NUM][MAX_HANDLERS]; + +static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) +{ + rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector); + return RT_NULL; +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + int idx; + int cpuid; + + cpuid = current_coreid(); + + /* Disable all interrupts for the current core. */ + for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++) + plic->target_enables.target[cpuid].enable[idx] = 0; + + /* Set priorities to zero. */ + for (idx = 0; idx < PLIC_NUM_SOURCES; idx++) + plic->source_priorities.priority[idx] = 0; + + /* Set the threshold to zero. */ + plic->targets.target[cpuid].priority_threshold = 0; + + /* init exceptions table */ + for (idx = 0; idx < MAX_HANDLERS; idx++) + { + rt_hw_interrupt_mask(idx); + irq_desc[cpuid][idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[cpuid][idx].param = RT_NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[cpuid][idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx][cpuid].counter = 0; +#endif + } + + /* Enable machine external interrupts. */ + set_csr(mie, MIP_MEIP); +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + plic_irq_disable(vector); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + plic_set_priority(vector, 1); + plic_irq_enable(vector); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + int cpuid; + rt_isr_handler_t old_handler = RT_NULL; + + cpuid = current_coreid(); + + if(vector < MAX_HANDLERS) + { + old_handler = irq_desc[cpuid][vector].handler; + if (handler != RT_NULL) + { + irq_desc[cpuid][vector].handler = (rt_isr_handler_t)handler; + irq_desc[cpuid][vector].param = param; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[cpuid][vector].name, RT_NAME_MAX - 1, "%s", name); + irq_desc[cpuid][vector].counter = 0; +#endif + } + } + + return old_handler; +} + +uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) +{ + /* + * After the highest-priority pending interrupt is claimed by a target + * and the corresponding IP bit is cleared, other lower-priority + * pending interrupts might then become visible to the target, and so + * the PLIC EIP bit might not be cleared after a claim. The interrupt + * handler can check the local meip/heip/seip/ueip bits before exiting + * the handler, to allow more efficient service of other interrupts + * without first restoring the interrupted context and taking another + * interrupt trap. + */ + if (read_csr(mip) & MIP_MEIP) + { + /* Get current core id */ + uint64_t core_id = current_coreid(); + /* Get primitive interrupt enable flag */ + uint64_t ie_flag = read_csr(mie); + /* Get current IRQ num */ + uint32_t int_num = plic->targets.target[core_id].claim_complete; + /* Get primitive IRQ threshold */ + uint32_t int_threshold = plic->targets.target[core_id].priority_threshold; + /* Set new IRQ threshold = current IRQ threshold */ + plic->targets.target[core_id].priority_threshold = plic->source_priorities.priority[int_num]; + + /* Disable software interrupt and timer interrupt */ + clear_csr(mie, MIP_MTIP | MIP_MSIP); + + if (irq_desc[core_id][int_num].handler) + { + irq_desc[core_id][int_num].handler(int_num, irq_desc[core_id][int_num].param); + } + + /* Perform IRQ complete */ + plic->targets.target[core_id].claim_complete = int_num; + /* Set MPIE and MPP flag used to MRET instructions restore MIE flag */ + set_csr(mstatus, MSTATUS_MPIE | MSTATUS_MPP); + /* Restore primitive interrupt enable flag */ + write_csr(mie, ie_flag); + /* Restore primitive IRQ threshold */ + plic->targets.target[core_id].priority_threshold = int_threshold; + } + else + { + rt_kprintf("unhandled trap!\n"); + } + + return epc; +} + +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) +{ + int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK; + + if (mcause & (1UL << 63)) + { + switch (cause) + { + case IRQ_M_SOFT: + break; + case IRQ_M_EXT: + handle_irq_m_ext(mcause, epc); + break; + case IRQ_M_TIMER: + tick_isr(); + break; + } + } + else + { + rt_thread_t tid; + extern long list_thread(); + + rt_hw_interrupt_disable(); + + tid = rt_thread_self(); + rt_kprintf("\n"); + rt_kprintf("unhandled trap, epc => 0x%08x, INT[%d]\n", epc, rt_interrupt_get_nest()); + rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, tid->name); +#ifdef RT_USING_FINSH + list_thread(); +#endif + while(1); + } + + return epc; +} diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S new file mode 100644 index 0000000000..5783322237 --- /dev/null +++ b/libcpu/risc-v/k210/interrupt_gcc.S @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/02 Bernard The first version + */ + +#include "cpuport.h" + + .section .text.entry + .align 2 + .global trap_entry +trap_entry: + + /* save thread context to thread stack */ + addi sp, sp, -32 * REGBYTES + + STORE x1, 1 * REGBYTES(sp) + li t0, 0x80 + STORE t0, 2 * REGBYTES(sp) + + STORE x4, 4 * REGBYTES(sp) + STORE x5, 5 * REGBYTES(sp) + STORE x6, 6 * REGBYTES(sp) + STORE x7, 7 * REGBYTES(sp) + STORE x8, 8 * REGBYTES(sp) + STORE x9, 9 * REGBYTES(sp) + STORE x10, 10 * REGBYTES(sp) + STORE x11, 11 * REGBYTES(sp) + STORE x12, 12 * REGBYTES(sp) + STORE x13, 13 * REGBYTES(sp) + STORE x14, 14 * REGBYTES(sp) + STORE x15, 15 * REGBYTES(sp) + STORE x16, 16 * REGBYTES(sp) + STORE x17, 17 * REGBYTES(sp) + STORE x18, 18 * REGBYTES(sp) + STORE x19, 19 * REGBYTES(sp) + STORE x20, 20 * REGBYTES(sp) + STORE x21, 21 * REGBYTES(sp) + STORE x22, 22 * REGBYTES(sp) + STORE x23, 23 * REGBYTES(sp) + STORE x24, 24 * REGBYTES(sp) + STORE x25, 25 * REGBYTES(sp) + STORE x26, 26 * REGBYTES(sp) + STORE x27, 27 * REGBYTES(sp) + STORE x28, 28 * REGBYTES(sp) + STORE x29, 29 * REGBYTES(sp) + STORE x30, 30 * REGBYTES(sp) + STORE x31, 31 * REGBYTES(sp) + + /* switch to interrupt stack */ + move s0, sp + + /* get cpu id */ + csrr t0, mhartid + + /* switch interrupt stack of current cpu */ + la sp, __stack_start__ + addi t1, t0, 1 + li t2, __STACKSIZE__ + mul t1, t1, t2 + add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */ + + /* handle interrupt */ + call rt_interrupt_enter + csrr a0, mcause + csrr a1, mepc + mv a2, sp + call handle_trap + call rt_interrupt_leave + + /* switch to from_thread stack */ + move sp, s0 + + /* need to switch new thread */ + la s0, rt_thread_switch_interrupt_flag + lw s2, 0(s0) + beqz s2, spurious_interrupt + sw zero, 0(s0) + + csrr a0, mepc + STORE a0, 0 * REGBYTES(sp) + + la s0, rt_interrupt_from_thread + LOAD s1, 0(s0) + STORE sp, 0(s1) + + la s0, rt_interrupt_to_thread + LOAD s1, 0(s0) + LOAD sp, 0(s1) + + LOAD a0, 0 * REGBYTES(sp) + csrw mepc, a0 + +spurious_interrupt: + LOAD x1, 1 * REGBYTES(sp) + + /* Remain in M-mode after mret */ + li t0, 0x00001800 + csrs mstatus, t0 + LOAD t0, 2 * REGBYTES(sp) + csrs mstatus, t0 + + LOAD x4, 4 * REGBYTES(sp) + LOAD x5, 5 * REGBYTES(sp) + LOAD x6, 6 * REGBYTES(sp) + LOAD x7, 7 * REGBYTES(sp) + LOAD x8, 8 * REGBYTES(sp) + LOAD x9, 9 * REGBYTES(sp) + LOAD x10, 10 * REGBYTES(sp) + LOAD x11, 11 * REGBYTES(sp) + LOAD x12, 12 * REGBYTES(sp) + LOAD x13, 13 * REGBYTES(sp) + LOAD x14, 14 * REGBYTES(sp) + LOAD x15, 15 * REGBYTES(sp) + LOAD x16, 16 * REGBYTES(sp) + LOAD x17, 17 * REGBYTES(sp) + LOAD x18, 18 * REGBYTES(sp) + LOAD x19, 19 * REGBYTES(sp) + LOAD x20, 20 * REGBYTES(sp) + LOAD x21, 21 * REGBYTES(sp) + LOAD x22, 22 * REGBYTES(sp) + LOAD x23, 23 * REGBYTES(sp) + LOAD x24, 24 * REGBYTES(sp) + LOAD x25, 25 * REGBYTES(sp) + LOAD x26, 26 * REGBYTES(sp) + LOAD x27, 27 * REGBYTES(sp) + LOAD x28, 28 * REGBYTES(sp) + LOAD x29, 29 * REGBYTES(sp) + LOAD x30, 30 * REGBYTES(sp) + LOAD x31, 31 * REGBYTES(sp) + + addi sp, sp, 32 * REGBYTES + mret diff --git a/libcpu/risc-v/k210/startup_gcc.S b/libcpu/risc-v/k210/startup_gcc.S new file mode 100644 index 0000000000..bc73f51e03 --- /dev/null +++ b/libcpu/risc-v/k210/startup_gcc.S @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/01 Bernard The first version + */ + +#define MSTATUS_FS 0x00006000U /* initial state of FPU */ +#include + + .global _start + .section ".start", "ax" +_start: + j 1f + .word 0xdeadbeef +1: + csrw mideleg, 0 + csrw medeleg, 0 + csrw mie, 0 + csrw mip, 0 + la t0, trap_entry + csrw mtvec, t0 + + li x1, 0 + li x2, 0 + li x3, 0 + li x4, 0 + li x5, 0 + li x6, 0 + li x7, 0 + li x8, 0 + li x9, 0 + li x10,0 + li x11,0 + li x12,0 + li x13,0 + li x14,0 + li x15,0 + li x16,0 + li x17,0 + li x18,0 + li x19,0 + li x20,0 + li x21,0 + li x22,0 + li x23,0 + li x24,0 + li x25,0 + li x26,0 + li x27,0 + li x28,0 + li x29,0 + li x30,0 + li x31,0 + + /* set to initial state of FPU and disable interrupt */ + li t0, MSTATUS_FS + csrs mstatus, t0 + + fssr x0 + fmv.d.x f0, x0 + fmv.d.x f1, x0 + fmv.d.x f2, x0 + fmv.d.x f3, x0 + fmv.d.x f4, x0 + fmv.d.x f5, x0 + fmv.d.x f6, x0 + fmv.d.x f7, x0 + fmv.d.x f8, x0 + fmv.d.x f9, x0 + fmv.d.x f10,x0 + fmv.d.x f11,x0 + fmv.d.x f12,x0 + fmv.d.x f13,x0 + fmv.d.x f14,x0 + fmv.d.x f15,x0 + fmv.d.x f16,x0 + fmv.d.x f17,x0 + fmv.d.x f18,x0 + fmv.d.x f19,x0 + fmv.d.x f20,x0 + fmv.d.x f21,x0 + fmv.d.x f22,x0 + fmv.d.x f23,x0 + fmv.d.x f24,x0 + fmv.d.x f25,x0 + fmv.d.x f26,x0 + fmv.d.x f27,x0 + fmv.d.x f28,x0 + fmv.d.x f29,x0 + fmv.d.x f30,x0 + fmv.d.x f31,x0 + +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* get cpu id */ + csrr a0, mhartid + + la sp, __stack_start__ + addi t1, a0, 1 + li t2, __STACKSIZE__ + mul t1, t1, t2 + add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */ + + /* other cpu core, jump to cpu entry directly */ + bnez a0, _cpu_entry + +#if 0 + /* clear bss section */ + la a0, __bss_start + la a1, __bss_end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, REGBYTES + bltu a0, a1, 1b +2: +#endif + +_cpu_entry: + csrr a0, mhartid + j cpu_entry diff --git a/libcpu/risc-v/k210/tick.c b/libcpu/risc-v/k210/tick.c new file mode 100644 index 0000000000..144f7f1fff --- /dev/null +++ b/libcpu/risc-v/k210/tick.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/28 Bernard The unify RISC-V porting code. + */ + +#include +#include + +#include +#include +#include + +static volatile unsigned long tick_cycles = 0; +int tick_isr(void) +{ + uint64_t core_id = current_coreid(); + + clint->mtimecmp[core_id] += tick_cycles; + rt_tick_increase(); + + return 0; +} + +/* Sets and enable the timer interrupt */ +int rt_hw_tick_init(void) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + unsigned long interval = 1000/RT_TICK_PER_SECOND; + + /* Clear the Machine-Timer bit in MIE */ + clear_csr(mie, MIP_MTIP); + + /* calculate the tick cycles */ + tick_cycles = interval * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1; + /* Set mtimecmp by core id */ + clint->mtimecmp[core_id] = clint->mtime + tick_cycles; + + /* Enable the Machine-Timer bit in MIE */ + set_csr(mie, MIP_MTIP); + + return 0; +} diff --git a/libcpu/risc-v/k210/tick.h b/libcpu/risc-v/k210/tick.h new file mode 100644 index 0000000000..0821004263 --- /dev/null +++ b/libcpu/risc-v/k210/tick.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/28 Bernard The unify RISC-V porting code. + */ + +#ifndef TICK_H__ +#define TICK_H__ + +int tick_isr(void); +int rt_hw_tick_init(void); + +#endif -- cgit v1.3.1 From 597d71cc032bf30098c2a5f890eec48ce5ff418d Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sun, 23 Dec 2018 14:11:25 +0800 Subject: [bsp][k210] Add get_free_heap_size function. * Add get_free_heap_size function; * Increase shell stack for KPU module. --- bsp/k210/.config | 36 +++++++++++++++++++++++++++++++++++- bsp/k210/README.md | 4 ++++ bsp/k210/driver/SConscript | 1 + bsp/k210/driver/heap.c | 11 +++++++++++ bsp/k210/rtconfig.h | 2 +- bsp/k210/rtconfig.py | 2 +- libcpu/risc-v/k210/interrupt.c | 14 +++++++++++++- libcpu/risc-v/k210/startup_gcc.S | 5 +++++ 8 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 bsp/k210/driver/heap.c (limited to 'libcpu') diff --git a/bsp/k210/.config b/bsp/k210/.config index c696886459..a9737f1c80 100644 --- a/bsp/k210/.config +++ b/bsp/k210/.config @@ -93,7 +93,7 @@ CONFIG_FINSH_USING_SYMTAB=y CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set CONFIG_FINSH_THREAD_PRIORITY=20 -CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=16384 CONFIG_FINSH_CMD_SIZE=80 # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_USING_MSH=y @@ -325,6 +325,40 @@ CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2" # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO_V001 is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO_LATEST_VERSION is not set +# CONFIG_KENDRYTE_DEMO_NONE is not set +# CONFIG_KENDRYTE_DEMO_AES_128_TEST is not set +# CONFIG_KENDRYTE_DEMO_AES_192_TEST is not set +# CONFIG_KENDRYTE_DEMO_AES_256_TEST is not set +# CONFIG_KENDRYTE_DEMO_AI_DEMO_SIM is not set +# CONFIG_KENDRYTE_DEMO_DVP_OV is not set +# CONFIG_KENDRYTE_DEMO_FACE_DETECT is not set +# CONFIG_KENDRYTE_DEMO_FFT_TEST is not set +# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX is not set +# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX_DMA_TEST is not set +# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX_TEST is not set +# CONFIG_KENDRYTE_DEMO_GPIOHS_LED is not set +# CONFIG_KENDRYTE_DEMO_GPIO_LED is not set +# CONFIG_KENDRYTE_DEMO_HELLO_WORLD is not set +# CONFIG_KENDRYTE_DEMO_I2C_SLAVE is not set +# CONFIG_KENDRYTE_DEMO_KPU is not set +# CONFIG_KENDRYTE_DEMO_LCD is not set +# CONFIG_KENDRYTE_DEMO_MIC_PLAY is not set +# CONFIG_KENDRYTE_DEMO_PLAY_PCM is not set +# CONFIG_KENDRYTE_DEMO_PWM is not set +# CONFIG_KENDRYTE_DEMO_RTC is not set +# CONFIG_KENDRYTE_DEMO_RTC_SD3068 is not set +# CONFIG_KENDRYTE_DEMO_SD_CARD is not set +# CONFIG_KENDRYTE_DEMO_SERVO is not set +# CONFIG_KENDRYTE_DEMO_SHA256_TEST is not set +# CONFIG_KENDRYTE_DEMO_TIMER is not set +# CONFIG_KENDRYTE_DEMO_UART is not set +# CONFIG_KENDRYTE_DEMO_UART_DMA is not set +# CONFIG_KENDRYTE_DEMO_UART_DMA_IRQ is not set +# CONFIG_KENDRYTE_DEMO_UART_INTERRUPT is not set +# CONFIG_KENDRYTE_DEMO_WATCHDOG is not set # # samples: kernel and components samples diff --git a/bsp/k210/README.md b/bsp/k210/README.md index 6de922d7a2..66bdf2287d 100644 --- a/bsp/k210/README.md +++ b/bsp/k210/README.md @@ -64,6 +64,10 @@ Kendryte中文含义为勘智,而勘智取自勘物探智。这颗芯片主要 ![terminal](images/k210.png) +如果是K210-test_v0.2开发板,可以用如下命令来打开串口: + + python -m serial.tools.miniterm --rts 0 --dtr 0 COM9 115200 + ## 4. 驱动支持情况及计划 | 驱动 | 支持情况 | 备注 | diff --git a/bsp/k210/driver/SConscript b/bsp/k210/driver/SConscript index 3ea01aa83f..7d5d6e54ce 100644 --- a/bsp/k210/driver/SConscript +++ b/bsp/k210/driver/SConscript @@ -5,6 +5,7 @@ from building import * cwd = GetCurrentDir() src = Split(''' board.c +heap.c drv_uart.c ''') CPPPATH = [cwd] diff --git a/bsp/k210/driver/heap.c b/bsp/k210/driver/heap.c new file mode 100644 index 0000000000..f1d6d2c27a --- /dev/null +++ b/bsp/k210/driver/heap.c @@ -0,0 +1,11 @@ +#include +#include + +size_t get_free_heap_size(void) +{ + rt_uint32_t total, used, max; + + rt_memory_info(&total, &used, &max); + + return total - used; +} diff --git a/bsp/k210/rtconfig.h b/bsp/k210/rtconfig.h index bb101c8c8d..b5fe0dfd48 100644 --- a/bsp/k210/rtconfig.h +++ b/bsp/k210/rtconfig.h @@ -64,7 +64,7 @@ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 16384 #define FINSH_CMD_SIZE 80 #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT diff --git a/bsp/k210/rtconfig.py b/bsp/k210/rtconfig.py index b159d6fb9e..418c1d7456 100644 --- a/bsp/k210/rtconfig.py +++ b/bsp/k210/rtconfig.py @@ -50,7 +50,7 @@ if PLATFORM == 'gcc': CFLAGS += ' -O0 -ggdb' AFLAGS += ' -ggdb' else: - CFLAGS += ' -O2' + CFLAGS += ' -O2 -Os' CXXFLAGS = CFLAGS diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c index 6d8866c3f0..f9c3eb5a67 100644 --- a/libcpu/risc-v/k210/interrupt.c +++ b/libcpu/risc-v/k210/interrupt.c @@ -114,6 +114,13 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, return old_handler; } +RT_WEAK +void plic_irq_handle(plic_irq_t irq) +{ + rt_kprintf("UN-handled interrupt %d occurred!!!\n", irq); + return ; +} + uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) { /* @@ -142,7 +149,12 @@ uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) /* Disable software interrupt and timer interrupt */ clear_csr(mie, MIP_MTIP | MIP_MSIP); - if (irq_desc[core_id][int_num].handler) + if (irq_desc[core_id][int_num].handler == (rt_isr_handler_t)rt_hw_interrupt_handle) + { + /* default handler, route to kendryte bsp plic driver */ + plic_irq_handle(int_num); + } + else if (irq_desc[core_id][int_num].handler) { irq_desc[core_id][int_num].handler(int_num, irq_desc[core_id][int_num].param); } diff --git a/libcpu/risc-v/k210/startup_gcc.S b/libcpu/risc-v/k210/startup_gcc.S index bc73f51e03..2e69c5021e 100644 --- a/libcpu/risc-v/k210/startup_gcc.S +++ b/libcpu/risc-v/k210/startup_gcc.S @@ -16,6 +16,11 @@ _start: j 1f .word 0xdeadbeef + .align 3 + .global g_wake_up + g_wake_up: + .dword 1 + .dword 0 1: csrw mideleg, 0 csrw medeleg, 0 -- cgit v1.3.1 From fb693418eed74535e01e6b1aca29a2e76536fbbd Mon Sep 17 00:00:00 2001 From: zhuhongbing Date: Wed, 26 Dec 2018 12:50:52 +0800 Subject: add project support for at91sam9260, add support for at91sam9g45 --- bsp/at91sam9260/.config | 311 + bsp/at91sam9260/Kconfig | 46 + bsp/at91sam9260/applications/application.c | 6 +- bsp/at91sam9260/drivers/board.c | 6 +- bsp/at91sam9260/drivers/led.c | 37 +- bsp/at91sam9260/platform/interrupt.c | 58 +- bsp/at91sam9260/rtconfig.h | 268 +- bsp/at91sam9260/rtconfig.py | 6 + bsp/at91sam9260/template.ewp | 1914 ++++++ bsp/at91sam9260/template.eww | 10 + bsp/at91sam9260/template.uvopt | 174 + bsp/at91sam9260/template.uvproj | 407 ++ bsp/at91sam9g45/.config | 311 + bsp/at91sam9g45/SConscript | 14 + bsp/at91sam9g45/SConstruct | 39 + bsp/at91sam9g45/applications/SConscript | 11 + bsp/at91sam9g45/applications/application.c | 173 + bsp/at91sam9g45/drivers/SConscript | 31 + bsp/at91sam9g45/drivers/at91_i2c_gpio.c | 130 + bsp/at91sam9g45/drivers/at91_mci.c | 924 +++ bsp/at91sam9g45/drivers/at91_mci.h | 124 + bsp/at91sam9g45/drivers/board.c | 248 + bsp/at91sam9g45/drivers/board.h | 32 + bsp/at91sam9g45/drivers/led.c | 54 + bsp/at91sam9g45/drivers/led.h | 32 + bsp/at91sam9g45/drivers/macb.c | 911 +++ bsp/at91sam9g45/drivers/macb.h | 346 + bsp/at91sam9g45/drivers/mii.h | 191 + bsp/at91sam9g45/drivers/usart.c | 398 ++ bsp/at91sam9g45/link_scripts/at91sam9g45_ram.icf | 55 + bsp/at91sam9g45/link_scripts/at91sam9g45_ram.ld | 98 + bsp/at91sam9g45/link_scripts/at91sam9g45_ram.scat | 40 + bsp/at91sam9g45/platform/SConscript | 26 + bsp/at91sam9g45/platform/at91sam9g45.h | 7213 +++++++++++++++++++++ bsp/at91sam9g45/platform/gpio.h | 208 + bsp/at91sam9g45/platform/interrupt.c | 453 ++ bsp/at91sam9g45/platform/interrupt.h | 31 + bsp/at91sam9g45/platform/io.h | 39 + bsp/at91sam9g45/platform/irq.h | 52 + bsp/at91sam9g45/platform/reset.c | 68 + bsp/at91sam9g45/platform/rt_low_level_init.c | 63 + bsp/at91sam9g45/platform/rt_low_level_init.h | 35 + bsp/at91sam9g45/platform/system_clock.c | 270 + bsp/at91sam9g45/rtconfig.h | 159 + bsp/at91sam9g45/rtconfig.py | 138 + bsp/at91sam9g45/template.ewp | 1914 ++++++ bsp/at91sam9g45/template.eww | 10 + bsp/at91sam9g45/template.uvopt | 174 + bsp/at91sam9g45/template.uvproj | 407 ++ libcpu/arm/arm926/start_rvds.S | 9 +- 50 files changed, 18449 insertions(+), 225 deletions(-) create mode 100644 bsp/at91sam9260/.config create mode 100644 bsp/at91sam9260/Kconfig create mode 100644 bsp/at91sam9260/template.ewp create mode 100644 bsp/at91sam9260/template.eww create mode 100644 bsp/at91sam9260/template.uvopt create mode 100644 bsp/at91sam9260/template.uvproj create mode 100644 bsp/at91sam9g45/.config create mode 100644 bsp/at91sam9g45/SConscript create mode 100644 bsp/at91sam9g45/SConstruct create mode 100644 bsp/at91sam9g45/applications/SConscript create mode 100644 bsp/at91sam9g45/applications/application.c create mode 100644 bsp/at91sam9g45/drivers/SConscript create mode 100644 bsp/at91sam9g45/drivers/at91_i2c_gpio.c create mode 100644 bsp/at91sam9g45/drivers/at91_mci.c create mode 100644 bsp/at91sam9g45/drivers/at91_mci.h create mode 100644 bsp/at91sam9g45/drivers/board.c create mode 100644 bsp/at91sam9g45/drivers/board.h create mode 100644 bsp/at91sam9g45/drivers/led.c create mode 100644 bsp/at91sam9g45/drivers/led.h create mode 100644 bsp/at91sam9g45/drivers/macb.c create mode 100644 bsp/at91sam9g45/drivers/macb.h create mode 100644 bsp/at91sam9g45/drivers/mii.h create mode 100644 bsp/at91sam9g45/drivers/usart.c create mode 100644 bsp/at91sam9g45/link_scripts/at91sam9g45_ram.icf create mode 100644 bsp/at91sam9g45/link_scripts/at91sam9g45_ram.ld create mode 100644 bsp/at91sam9g45/link_scripts/at91sam9g45_ram.scat create mode 100644 bsp/at91sam9g45/platform/SConscript create mode 100644 bsp/at91sam9g45/platform/at91sam9g45.h create mode 100644 bsp/at91sam9g45/platform/gpio.h create mode 100644 bsp/at91sam9g45/platform/interrupt.c create mode 100644 bsp/at91sam9g45/platform/interrupt.h create mode 100644 bsp/at91sam9g45/platform/io.h create mode 100644 bsp/at91sam9g45/platform/irq.h create mode 100644 bsp/at91sam9g45/platform/reset.c create mode 100644 bsp/at91sam9g45/platform/rt_low_level_init.c create mode 100644 bsp/at91sam9g45/platform/rt_low_level_init.h create mode 100644 bsp/at91sam9g45/platform/system_clock.c create mode 100644 bsp/at91sam9g45/rtconfig.h create mode 100644 bsp/at91sam9g45/rtconfig.py create mode 100644 bsp/at91sam9g45/template.ewp create mode 100644 bsp/at91sam9g45/template.eww create mode 100644 bsp/at91sam9g45/template.uvopt create mode 100644 bsp/at91sam9g45/template.uvproj (limited to 'libcpu') diff --git a/bsp/at91sam9260/.config b/bsp/at91sam9260/.config new file mode 100644 index 0000000000..a19ac15d3d --- /dev/null +++ b/bsp/at91sam9260/.config @@ -0,0 +1,311 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +CONFIG_RT_ALIGN_SIZE=4 +# 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=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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_DEVICE_OPS is not set +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="dbgu" + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# 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_ECHO_DISABLE_DEFAULT is not set +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 +CONFIG_FINSH_ARG_MAX=10 + +# +# 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=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# 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_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_PWM is not set +# 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 is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_AUDIO 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 is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT 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 +# + +# +# 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_JSMN is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_STM32F4_HAL is not set +# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set + +# +# sample package +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_RT_USING_DBGU=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_RT_USING_UART1 is not set +# CONFIG_RT_USING_UART2 is not set +# CONFIG_RT_USING_UART3 is not set +CONFIG_RT_USING_LED=y diff --git a/bsp/at91sam9260/Kconfig b/bsp/at91sam9260/Kconfig new file mode 100644 index 0000000000..f07968f982 --- /dev/null +++ b/bsp/at91sam9260/Kconfig @@ -0,0 +1,46 @@ +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" + +config RT_USING_DBGU + bool "Using RT_USING_DBGU" + default y + +config RT_USING_UART0 + bool "Using RT_USING_UART0" + default n + +config RT_USING_UART1 + bool "Using RT_USING_UART1" + default n + +config RT_USING_UART2 + bool "Using RT_USING_UART2" + default n + +config RT_USING_UART3 + bool "Using RT_USING_UART3" + default n + +config RT_USING_LED + bool "Using RT_USING_LED" + default y + help + led blink demo + diff --git a/bsp/at91sam9260/applications/application.c b/bsp/at91sam9260/applications/application.c index 5800ba53d2..48c526957a 100644 --- a/bsp/at91sam9260/applications/application.c +++ b/bsp/at91sam9260/applications/application.c @@ -96,7 +96,10 @@ int main(void) #endif } #endif - + +#ifdef RT_USING_LED + rt_led_app_init(); +#endif } #ifdef RT_USING_LED @@ -121,7 +124,6 @@ void rt_led_thread_entry(void* parameter) led_on(3); else led_off(3); - } } #endif diff --git a/bsp/at91sam9260/drivers/board.c b/bsp/at91sam9260/drivers/board.c index d058c30935..a7ec6008da 100644 --- a/bsp/at91sam9260/drivers/board.c +++ b/bsp/at91sam9260/drivers/board.c @@ -43,7 +43,7 @@ extern unsigned char __bss_end__; #define HEAP_BEGIN (__section_end(".noinit")) #endif -#define HEAP_END (0x24000000) +#define HEAP_END (((rt_uint32_t)HEAP_BEGIN & (0xF0 << 24)) + (32 << 20)) extern void rt_hw_interrupt_init(void); extern void rt_hw_clock_init(void); @@ -57,8 +57,8 @@ static struct mem_desc at91_mem_desc[] = { { 0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB }, /* None cached for 4G memory */ { 0x20000000, 0x24000000-1, 0x20000000, RW_CB }, /* 64M cached SDRAM memory */ { 0x00000000, 0x100000, 0x20000000, RW_CB }, /* isr vector table */ - { 0x90000000, 0x90400000 - 1, 0x00200000, RW_NCNB }, /* 4K SRAM0 + 4k SRAM1 */ - { 0xA0000000, 0xA4000000-1, 0x20000000, RW_NCNB } /* 64M none-cached SDRAM memory */ + { 0x90000000, 0x90400000-1, 0x00200000, RW_NCNB }, /* 4K SRAM0@2M + 4k SRAM1@3M + 16k UHP@5M */ + { 0xA0000000, 0xA4000000-1, 0x20000000, RW_NCNB } /* 64M none-cached SDRAM memory */ }; diff --git a/bsp/at91sam9260/drivers/led.c b/bsp/at91sam9260/drivers/led.c index 6c8f202108..3791b2a568 100644 --- a/bsp/at91sam9260/drivers/led.c +++ b/bsp/at91sam9260/drivers/led.c @@ -26,12 +26,27 @@ #include #include "led.h" +#if 1 +// GB9260 board +#define PIO_LED AT91_PIOB +#define LED1 (1 << 25) // LED_SYS +#define LED2 (0) +#define LED3 (1 << 23) // LED_USR +#define LED_ALL (LED1 | LED2 | LED3) +#else +#define PIO_LED AT91_PIOC +#define LED1 (1 << 8) +#define LED2 (1 << 11) +#define LED3 (1 << 6) +#define LED_ALL (LED1 | LED2 | LED3) +#endif + void led_init(void) { - at91_sys_write(AT91_PIOC, (1<<8)|(1<<11)|(1<<6)); - at91_sys_write(AT91_PIOC+0x10, (1<<8)|(1<<11)|(1<<6)); - at91_sys_write(AT91_PIOC+0x64, (1<<8)|(1<<11)|(1<<6)); - at91_sys_write(AT91_PIOC+0x30, (1<<8)|(1<<11)|(1<<6)); + at91_sys_write(PIO_LED+0x00, LED_ALL); + at91_sys_write(PIO_LED+0x10, LED_ALL); + at91_sys_write(PIO_LED+0x64, LED_ALL); + at91_sys_write(PIO_LED+0x30, LED_ALL); } void led_on(int num) @@ -39,18 +54,17 @@ void led_on(int num) switch(num) { case 1: - at91_sys_write(AT91_PIOC+0x34, 1<<8); + at91_sys_write(PIO_LED+0x34, LED1); break; case 2: - at91_sys_write(AT91_PIOC+0x34, 1<<11); + at91_sys_write(PIO_LED+0x34, LED2); break; case 3: - at91_sys_write(AT91_PIOC+0x34, 1<<6); + at91_sys_write(PIO_LED+0x34, LED3); break; default: break; } - } void led_off(int num) @@ -58,16 +72,15 @@ void led_off(int num) switch(num) { case 1: - at91_sys_write(AT91_PIOC+0x30, 1<<8); + at91_sys_write(PIO_LED+0x30, LED1); break; case 2: - at91_sys_write(AT91_PIOC+0x30, 1<<11); + at91_sys_write(PIO_LED+0x30, LED2); break; case 3: - at91_sys_write(AT91_PIOC+0x30, 1<<6); + at91_sys_write(PIO_LED+0x30, LED3); break; default: break; } - //at91_sys_write(AT91_PIOC+0x30, 1<<8); } diff --git a/bsp/at91sam9260/platform/interrupt.c b/bsp/at91sam9260/platform/interrupt.c index 7a83fca494..0708460578 100644 --- a/bsp/at91sam9260/platform/interrupt.c +++ b/bsp/at91sam9260/platform/interrupt.c @@ -30,7 +30,7 @@ extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ -struct rt_irq_desc irq_desc[MAX_HANDLERS]; +struct rt_irq_desc irq_desc[MAX_HANDLERS]; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; @@ -101,17 +101,17 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) rt_uint32_t isr, pio, irq_n; void *parameter; - if (vector == AT91SAM9260_ID_PIOA) + if (vector == AT91SAM9260_ID_PIOA) { pio = AT91_PIOA; irq_n = AIC_IRQS; } - else if (vector == AT91SAM9260_ID_PIOB) + else if (vector == AT91SAM9260_ID_PIOB) { pio = AT91_PIOB; irq_n = AIC_IRQS + 32; } - else if (vector == AT91SAM9260_ID_PIOC) + else if (vector == AT91SAM9260_ID_PIOC) { pio = AT91_PIOC; irq_n = AIC_IRQS + 32*2; @@ -119,9 +119,9 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) else return RT_NULL; isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); - while (isr) + while (isr) { - if (isr & 1) + if (isr & 1) { parameter = irq_desc[irq_n].param; irq_desc[irq_n].handler(irq_n, parameter); @@ -175,7 +175,7 @@ static void at91_gpio_irq_init() { int i, idx; char *name[] = {"PIOA", "PIOB", "PIOC"}; - + at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); @@ -183,11 +183,13 @@ static void at91_gpio_irq_init() idx = AT91SAM9260_ID_PIOA; for (i = 0; i < 3; i++) { - rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, name[i]); irq_desc[idx].handler = (rt_isr_handler_t)at91_gpio_irq_handle; irq_desc[idx].param = RT_NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, name[i]); irq_desc[idx].counter = 0; - idx++; +#endif + idx++; } rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); @@ -203,7 +205,7 @@ void rt_hw_interrupt_init(void) { register rt_uint32_t idx; rt_uint32_t *priority = at91sam9260_default_irq_priority; - + at91_extern_irq = (1UL << AT91SAM9260_ID_IRQ0) | (1UL << AT91SAM9260_ID_IRQ1) | (1UL << AT91SAM9260_ID_IRQ2); @@ -213,10 +215,12 @@ void rt_hw_interrupt_init(void) /* init exceptions table */ for(idx=0; idx < MAX_HANDLERS; idx++) { - rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; irq_desc[idx].param = RT_NULL; - irq_desc[idx].counter = 0; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].counter = 0; +#endif } at91_gpio_irq_init(); @@ -234,15 +238,15 @@ static void at91_gpio_irq_mask(int irq) bank = (irq - AIC_IRQS)>>5; - if (bank == 0) + if (bank == 0) { pio = AT91_PIOA; } - else if (bank == 1) + else if (bank == 1) { pio = AT91_PIOB; } - else if (bank == 2) + else if (bank == 2) { pio = AT91_PIOC; } @@ -258,7 +262,7 @@ static void at91_gpio_irq_mask(int irq) */ void rt_hw_interrupt_mask(int irq) { - if (irq >= AIC_IRQS) + if (irq >= AIC_IRQS) { at91_gpio_irq_mask(irq); } @@ -275,15 +279,15 @@ static void at91_gpio_irq_umask(int irq) bank = (irq - AIC_IRQS)>>5; - if (bank == 0) + if (bank == 0) { pio = AT91_PIOA; } - else if (bank == 1) + else if (bank == 1) { pio = AT91_PIOB; } - else if (bank == 2) + else if (bank == 2) { pio = AT91_PIOC; } @@ -299,7 +303,7 @@ static void at91_gpio_irq_umask(int irq) */ void rt_hw_interrupt_umask(int irq) { - if (irq >= AIC_IRQS) + if (irq >= AIC_IRQS) { at91_gpio_irq_umask(irq); } @@ -328,10 +332,12 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, old_handler = irq_desc[vector].handler; if (handler != RT_NULL) { - rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); irq_desc[vector].handler = (rt_isr_handler_t)handler; irq_desc[vector].param = param; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); irq_desc[vector].counter = 0; +#endif } } @@ -353,15 +359,15 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQ_TYPE_LEVEL_LOW: - // only supported on external interrupts - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) + // only supported on external interrupts + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) srctype = AT91_AIC_SRCTYPE_LOW; else return -1; break; case IRQ_TYPE_EDGE_FALLING: - // only supported on external interrupts - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) + // only supported on external interrupts + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) srctype = AT91_AIC_SRCTYPE_FALLING; else return -1; @@ -409,7 +415,7 @@ void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id) void list_irq(void) { int irq; - + rt_kprintf("number\tcount\tname\n"); for (irq = 0; irq < MAX_HANDLERS; irq++) { diff --git a/bsp/at91sam9260/rtconfig.h b/bsp/at91sam9260/rtconfig.h index b9ec26f390..816054c3e1 100755 --- a/bsp/at91sam9260/rtconfig.h +++ b/bsp/at91sam9260/rtconfig.h @@ -1,254 +1,160 @@ -/* RT-Thread config file */ -#ifndef __RTTHREAD_CFG_H__ -#define __RTTHREAD_CFG_H__ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ -/* RT_NAME_MAX*/ -#define RT_NAME_MAX 32 +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ -/* RT_ALIGN_SIZE*/ -#define RT_ALIGN_SIZE 4 - -/* PRIORITY_MAX */ -#define RT_THREAD_PRIORITY_MAX 256 - -/* Tick per Second */ -#define RT_TICK_PER_SECOND 100 - -/* SECTION: RT_DEBUG */ -/* Thread Debug */ -#define RT_DEBUG -//#define SCHEDULER_DEBUG -/* #define RT_THREAD_DEBUG */ +/* RT-Thread Kernel */ +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 #define RT_USING_OVERFLOW_CHECK - -#define RT_USING_INTERRUPT_INFO - -/* Using Hook */ #define RT_USING_HOOK +#define RT_IDEL_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 +#define RT_DEBUG -/* Using Software Timer */ -#define RT_USING_TIMER_SOFT -#define RT_TIMER_THREAD_PRIO 8 -#define RT_TIMER_THREAD_STACK_SIZE 512 -#define RT_TIMER_TICK_PER_SECOND 10 +/* Inter-Thread communication */ -/* SECTION: IPC */ -/* Using Semaphore */ #define RT_USING_SEMAPHORE - -/* Using Mutex */ #define RT_USING_MUTEX - -/* Using Event */ #define RT_USING_EVENT - -/* Using MailBox */ #define RT_USING_MAILBOX - -/* Using Message Queue */ #define RT_USING_MESSAGEQUEUE -/* SECTION: Memory Management */ -/* Using Memory Pool Management*/ -#define RT_USING_MEMPOOL +/* Memory Management */ -/* Using Dynamic Heap Management */ +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM #define RT_USING_HEAP -/* Using Small MM */ -/* #define RT_USING_SMALL_MEM */ +/* Kernel Device Object */ -/* Using SLAB Allocator */ -#define RT_USING_SLAB +#define RT_USING_DEVICE +#define RT_USING_INTERRUPT_INFO +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "dbgu" -/* SECTION: the runtime libc library */ -/* the runtime libc library */ -#define RT_USING_LIBC -#define RT_USING_PTHREADS +/* RT-Thread Components */ -/* Using Module System */ -#define RT_USING_MODULE +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 -/* SECTION: Device System */ -/* Using Device System */ -#define RT_USING_DEVICE +/* C++ features */ #define RT_USING_DEVICE_IPC #define RT_USING_SERIAL #define RT_SERIAL_USING_DMA -/* SECTION: Console options */ -#define RT_USING_CONSOLE -/* the buffer size of console */ -#define RT_CONSOLEBUF_SIZE 128 -#define RT_CONSOLE_DEVICE_NAME "dbgu" +/* Command shell */ -/* SECTION: finsh, a C-Express shell */ -/* Using FinSH as Shell*/ #define RT_USING_FINSH -/* Using symbol table */ +#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_PRIORITY 20 #define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 #define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 -/* SECTION: C++ support */ -/* Using C++ support */ -/* #define RT_USING_CPLUSPLUS */ +/* Device virtual file system */ -/* SECTION: Device filesystem support */ -/* using DFS support */ #define RT_USING_DFS -#define RT_USING_DFS_ELMFAT -/* use long file name feature */ -#define RT_DFS_ELM_USE_LFN 2 -#define RT_DFS_ELM_REENTRANT -/* define OEM code page */ -#define RT_DFS_ELM_CODE_PAGE 936 -/* Using OEM code page file */ -// #define RT_DFS_ELM_CODE_PAGE_FILE -/* the max number of file length */ -#define RT_DFS_ELM_MAX_LFN 128 -/* #define RT_USING_DFS_YAFFS2 */ +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 16 #define RT_USING_DFS_DEVFS -#define RT_USING_DFS_NFS -#define RT_NFS_HOST_EXPORT "192.168.1.5:/" +/* Device Drivers */ -#define DFS_USING_WORKDIR +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_USING_PIN -/* the max number of mounted filesystem */ -#define DFS_FILESYSTEMS_MAX 4 -/* the max number of opened files */ -#define DFS_FD_MAX 16 -/* the max number of cached sector */ -#define DFS_CACHE_MAX_NUM 4 +/* Using USB */ -/* Enable freemodbus protocol stack*/ -/* #define RT_USING_MODBUS */ -//#define RT_USING_LED +/* POSIX layer and C standard library */ -#define RT_USING_SDIO +#define RT_USING_LIBC -#define RT_USING_I2C -#define RT_USING_I2C_BITOPS +/* Network */ -#define RT_USING_DBGU -/* #define RT_USING_UART0 */ -/* #define RT_USING_UART1 */ -/* #define RT_USING_UART2 */ -/* #define RT_USING_UART3 */ +/* Socket abstraction layer */ -/* SECTION: lwip, a lightweight TCP/IP protocol stack */ -/* Using lightweight TCP/IP protocol stack */ -#define RT_USING_LWIP -#define RT_LWIP_DNS -/* Trace LwIP protocol */ -// #define RT_LWIP_DEBUG +/* light weight TCP/IP stack */ -/* Enable ICMP protocol */ -#define RT_LWIP_ICMP -/* Enable IGMP protocol */ -#define RT_LWIP_IGMP +/* Modbus master and slave stack */ -/* Enable UDP protocol */ -#define RT_LWIP_UDP -/* Enable TCP protocol */ -#define RT_LWIP_TCP +/* AT commands */ -/* the number of simulatenously active TCP connections*/ -#define RT_LWIP_TCP_PCB_NUM 5 -/* TCP sender buffer space */ -#define RT_LWIP_TCP_SND_BUF 1024*10 +/* VBUS(Virtual Software BUS) */ -/* TCP receive window. */ -#define RT_LWIP_TCP_WND 1024*8 -/* Enable SNMP protocol */ -/* #define RT_LWIP_SNMP */ +/* Utilities */ -/* Using DHCP */ -/* #define RT_LWIP_DHCP */ -/* ip address of target */ -#define RT_LWIP_IPADDR "192.168.1.30" +/* RT-Thread online packages */ -/* gateway address of target */ -#define RT_LWIP_GWADDR "192.168.1.1" +/* IoT - internet of things */ -/* mask address of target */ -#define RT_LWIP_MSKADDR "255.255.255.0" -/* the number of blocks for pbuf */ -#define RT_LWIP_PBUF_NUM 16 +/* Wi-Fi */ -/* the number of simultaneously queued TCP */ -#define RT_LWIP_TCP_SEG_NUM 40 +/* Marvell WiFi */ -/* thread priority of tcpip thread */ -#define RT_LWIP_TCPTHREAD_PRIORITY 128 -/* mail box size of tcpip thread to wait for */ -#define RT_LWIP_TCPTHREAD_MBOX_SIZE 32 +/* Wiced WiFi */ -/* thread stack size of tcpip thread */ -#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 -/* thread priority of ethnetif thread */ -#define RT_LWIP_ETHTHREAD_PRIORITY 144 +/* IoT Cloud */ -/* mail box size of ethnetif thread to wait for */ -#define RT_LWIP_ETHTHREAD_MBOX_SIZE 32 -/* thread stack size of ethnetif thread */ -#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 +/* security packages */ -/* SECTION: RTGUI support */ -/* using RTGUI support */ -/* #define RT_USING_RTGUI */ +/* language packages */ -/* name length of RTGUI object */ -//#define RTGUI_NAME_MAX 16 -/* support 16 weight font */ -//#define RTGUI_USING_FONT16 -/* support 16 weight font */ -//#define RTGUI_USING_FONT12 -/* support Chinese font */ -//#define RTGUI_USING_FONTHZ -/* use DFS as file interface */ -//#define RTGUI_USING_DFS_FILERW -/* use font file as Chinese font */ -/* #define RTGUI_USING_HZ_FILE */ -/* use Chinese bitmap font */ -//#define RTGUI_USING_HZ_BMP -/* use small size in RTGUI */ -/* #define RTGUI_USING_SMALL_SIZE */ -/* use mouse cursor */ -/* #define RTGUI_USING_MOUSE_CURSOR */ -/* SECTION: FTK support */ -/* using FTK support */ -/* #define RT_USING_FTK */ +/* multimedia packages */ -/* - * Note on FTK: - * - * FTK depends : - * #define RT_USING_NEWLIB - * #define DFS_USING_WORKDIR - * - * And the maximal length must great than 64 - * #define RT_DFS_ELM_MAX_LFN 128 - */ -#define RT_USING_COMPONENTS_INIT -#define RT_USING_USER_MAIN +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* sample package */ + +/* samples: kernel and components samples */ + + +/* example package: hello */ + +#define RT_USING_DBGU +#define RT_USING_LED #endif diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py index 3aefb30fad..da3be0fd59 100755 --- a/bsp/at91sam9260/rtconfig.py +++ b/bsp/at91sam9260/rtconfig.py @@ -11,6 +11,12 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' EXEC_PATH = r'D:\arm-2013.11\bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.2' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') diff --git a/bsp/at91sam9260/template.ewp b/bsp/at91sam9260/template.ewp new file mode 100644 index 0000000000..c9cc04c3db --- /dev/null +++ b/bsp/at91sam9260/template.ewp @@ -0,0 +1,1914 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 24 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + + diff --git a/bsp/at91sam9260/template.eww b/bsp/at91sam9260/template.eww new file mode 100644 index 0000000000..bd036bb4c9 --- /dev/null +++ b/bsp/at91sam9260/template.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\template.ewp + + + + + diff --git a/bsp/at91sam9260/template.uvopt b/bsp/at91sam9260/template.uvopt new file mode 100644 index 0000000000..2dca5102b8 --- /dev/null +++ b/bsp/at91sam9260/template.uvopt @@ -0,0 +1,174 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + rtthread + 0x4 + ARM-ADS + + 18432000 + + 1 + 1 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 16 + + + 0 + Datasheet + DATASHTS\ATMEL\AT91SAM9260_DS.PDF + + + 1 + Summary + DATASHTS\ATMEL\AT91SAM9260_DC.PDF + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 5 + + + + + + + + + + .\jlink\at91sam9260.ini + Segger\JLTAgdi.dll + + + + 0 + JLTAgdi + -O558 -J1 -Y1000 -Z1 -FO0 -FD200000 -FC800 -FN0 + + + 0 + UL2ARM + -UV2077N9E -O47 -S0 -C0 -N00("ARM926EJ-S Core") -D00(0792603F) -L00(4) -FO7 -FD300000 -FC1000 -FN1 -FF0AT91SAM9_DF_P1056_CS1 -FS020000000 -FL083BE00) + + + + + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + +
diff --git a/bsp/at91sam9260/template.uvproj b/bsp/at91sam9260/template.uvproj new file mode 100644 index 0000000000..c644bc5440 --- /dev/null +++ b/bsp/at91sam9260/template.uvproj @@ -0,0 +1,407 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread + 0x4 + ARM-ADS + + + AT91SAM9260 + Atmel + IRAM(0x200000-0x200FFF) IRAM2(0x300000-0x300FFF) IROM(0x100000-0x107FFF) CLOCK(18432000) CPUTYPE(ARM926EJ-S) + + "STARTUP\Atmel\SAM9260.s" ("Atmel AT91SAM9260 Startup Code") + UL2ARM(-UV2077N9E -O47 -S0 -C0 -N00("ARM926EJ-S Core") -D00(0792603F) -L00(4) -FO7 -FD300000 -FC1000 -FN1 -FF0AT91SAM9_DF_P1056_CS1 -FS020000000 -FL083BE00) + 4210 + AT91SAM9260.H + + + + + + + + + + + 0 + 0 + + + + Atmel\SAM9260\ + Atmel\SAM9260\ + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARM.DLL + -cAT91SAM9260 + DARMATS9.DLL + -p91SAM9260 + SARM.DLL + + TARMATS9.DLL + -p91SAM9260 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + + 0 + 5 + + + + + + + + + + + + + .\jlink\at91sam9260.ini + Segger\JLTAgdi.dll + + + + + 1 + 0 + 0 + 0 + 1 + 4096 + + 1 + BIN\UL2ARM.DLL + "" () + .\jlink\at91sam9260.ini + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + ARM926EJ-S + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x200000 + 0x1000 + + + 1 + 0x100000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x20000000 + 0x800000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x100000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x20800000 + 0x1800000 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x200000 + 0x1000 + + + 0 + 0x300000 + 0x1000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + + + RT_USING_INTERRUPT_INFO + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + .\platform + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x20000000 + 0x20800000 + + .\link_scripts\at91sam9260_ram.scat + + + + + + + + + + + +
diff --git a/bsp/at91sam9g45/.config b/bsp/at91sam9g45/.config new file mode 100644 index 0000000000..5f3ae78673 --- /dev/null +++ b/bsp/at91sam9g45/.config @@ -0,0 +1,311 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +CONFIG_RT_ALIGN_SIZE=4 +# 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_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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_DEVICE_OPS is not set +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="dbgu" + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +CONFIG_RT_USING_CPLUSPLUS=y + +# +# 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_ECHO_DISABLE_DEFAULT is not set +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 +CONFIG_FINSH_ARG_MAX=10 + +# +# 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=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# 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_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_PWM is not set +# 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 is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_AUDIO 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_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT 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 +# + +# +# 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_JSMN is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_STM32F4_HAL is not set +# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set + +# +# sample package +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_RT_USING_DBGU=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_RT_USING_UART1 is not set +# CONFIG_RT_USING_UART2 is not set +# CONFIG_RT_USING_UART3 is not set +CONFIG_RT_USING_LED=y diff --git a/bsp/at91sam9g45/SConscript b/bsp/at91sam9g45/SConscript new file mode 100644 index 0000000000..fe0ae941ae --- /dev/null +++ b/bsp/at91sam9g45/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +Import('RTT_ROOT') + +cwd = str(Dir('#')) +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/at91sam9g45/SConstruct b/bsp/at91sam9g45/SConstruct new file mode 100644 index 0000000000..41139a3377 --- /dev/null +++ b/bsp/at91sam9g45/SConstruct @@ -0,0 +1,39 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread-at91sam9g45.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +if GetDepend('RT_USING_WEBSERVER'): + objs = objs + SConscript(RTT_ROOT + '/components/net/webserver/SConscript', variant_dir='build/net/webserver', duplicate=0) + +if GetDepend('RT_USING_RTGUI'): + objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) + +# libc testsuite +objs = objs + SConscript(RTT_ROOT + '/examples/libc/SConscript', variant_dir='build/examples/libc', duplicate=0) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/at91sam9g45/applications/SConscript b/bsp/at91sam9g45/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/at91sam9g45/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/at91sam9g45/applications/application.c b/bsp/at91sam9g45/applications/application.c new file mode 100644 index 0000000000..ec878faa85 --- /dev/null +++ b/bsp/at91sam9g45/applications/application.c @@ -0,0 +1,173 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + */ + +/** + * @addtogroup at91sam9260 + */ +/*@{*/ + +#include +#include + +#ifdef RT_USING_DFS +/* dfs Filesystem APIs */ +#include +#endif + +#ifdef RT_USING_SDIO +#include +#include "at91_mci.h" +#endif + +#ifdef RT_USING_LED +#include "led.h" +#endif + +static int rt_led_app_init(void); + +RT_WEAK int main(void) +{ +#ifdef RT_USING_SDIO + int timeout = 0; +#endif + +/* Filesystem Initialization */ +#ifdef RT_USING_DFS + { +#if defined(RT_USING_DFS_ROMFS) + if (dfs_mount(RT_NULL, "/rom", "rom", 0, &romfs_root) == 0) + { + rt_kprintf("ROM File System initialized!\n"); + } + else + rt_kprintf("ROM File System initialzation failed!\n"); +#endif + +#if defined(RT_USING_DFS_UFFS) + { + /* mount flash device as flash directory */ + if(dfs_mount("nand0", "/nand0", "uffs", 0, 0) == 0) + rt_kprintf("UFFS File System initialized!\n"); + else + rt_kprintf("UFFS File System initialzation failed!\n"); + } +#endif + +#ifdef RT_USING_SDIO + timeout = 0; + while ((rt_device_find("sd0") == RT_NULL) && (timeout++ < RT_TICK_PER_SECOND*2)) + { + rt_thread_delay(1); + } + + if (timeout < RT_TICK_PER_SECOND*2) + { + /* 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!%d\n", rt_get_errno()); + } + else + { + rt_kprintf("No SD card found.\n"); + } +#endif + } +#endif + + rt_led_app_init(); +} + +#ifdef RT_USING_LED +void rt_led_thread_entry(void* parameter) +{ + rt_uint8_t cnt = 0; + led_init(); + while(1) + { + /* light on leds for one second */ + rt_thread_delay(40); + cnt++; + if (cnt&0x01) + led_on(1); + else + led_off(1); + if (cnt&0x02) + led_on(2); + else + led_off(2); + if (cnt&0x04) + led_on(3); + else + led_off(3); + + } +} +#endif + +static int rt_led_app_init(void) +{ +#ifdef RT_USING_LED + rt_thread_t led_thread; + +#if (RT_THREAD_PRIORITY_MAX == 32) + led_thread = rt_thread_create("led", + rt_led_thread_entry, RT_NULL, + 512, 20, 20); +#else + led_thread = rt_thread_create("led", + rt_led_thread_entry, RT_NULL, + 512, 200, 20); +#endif + + if(led_thread != RT_NULL) + rt_thread_startup(led_thread); +#endif + + return 0; +} + +/* NFSv3 Initialization */ +#if defined(RT_USING_DFS) && defined(RT_USING_LWIP) && defined(RT_USING_DFS_NFS) +#include +void nfs_start(void) +{ + nfs_init(); + + if (dfs_mount(RT_NULL, "/nfs", "nfs", 0, RT_NFS_HOST_EXPORT) == 0) + { + rt_kprintf("NFSv3 File System initialized!\n"); + } + else + rt_kprintf("NFSv3 File System initialzation failed!\n"); +} + +#include "finsh.h" +FINSH_FUNCTION_EXPORT(nfs_start, start net filesystem); +#endif + +/*@}*/ diff --git a/bsp/at91sam9g45/drivers/SConscript b/bsp/at91sam9g45/drivers/SConscript new file mode 100644 index 0000000000..d0470f9049 --- /dev/null +++ b/bsp/at91sam9g45/drivers/SConscript @@ -0,0 +1,31 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'drivers') + +# add the general drvers. +src = Split(""" +board.c +usart.c +""") + +# add Ethernet drvers. +if GetDepend('RT_USING_LED'): + src += ['led.c'] + +if GetDepend('RT_USING_SDIO'): + src += ['at91_mci.c'] + +if GetDepend('RT_USING_LWIP'): + src += ['macb.c'] + +if GetDepend('RT_USING_I2C') and GetDepend('RT_USING_I2C_BITOPS'): + src += ['at91_i2c_gpio.c'] + + +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/at91sam9g45/drivers/at91_i2c_gpio.c b/bsp/at91sam9g45/drivers/at91_i2c_gpio.c new file mode 100644 index 0000000000..91ca646c7a --- /dev/null +++ b/bsp/at91sam9g45/drivers/at91_i2c_gpio.c @@ -0,0 +1,130 @@ +/* + * File : at91_i2c_gpio.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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 + * 2012-04-25 weety first version + */ + +#include +#include +#include + + +static void at91_i2c_gpio_init() +{ + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA; //enable PIOA clock + AT91C_BASE_PIOA->PIO_PUER = (1 << 23); + AT91C_BASE_PIOA->PIO_PER = (1 << 23); + AT91C_BASE_PIOA->PIO_MDER = (1 << 23); + AT91C_BASE_PIOA->PIO_PUER = (1 << 24); + AT91C_BASE_PIOA->PIO_PER = (1 << 24); + AT91C_BASE_PIOA->PIO_MDER = (1 << 24); + + AT91C_BASE_PIOA->PIO_OER = (1 << 23); + AT91C_BASE_PIOA->PIO_OER = (1 << 24); + + AT91C_BASE_PIOA->PIO_SODR = (1 << 23); + AT91C_BASE_PIOA->PIO_SODR = (1 << 24); +} + +static void at91_set_sda(void *data, rt_int32_t state) +{ + if (state) + { + AT91C_BASE_PIOA->PIO_SODR = (1 << 23); + } + else + { + AT91C_BASE_PIOA->PIO_CODR = (1 << 23); + } +} + +static void at91_set_scl(void *data, rt_int32_t state) +{ + if (state) + { + AT91C_BASE_PIOA->PIO_SODR = (1 << 24); + } + else + { + AT91C_BASE_PIOA->PIO_CODR = (1 << 24); + } +} + +static rt_int32_t at91_get_sda(void *data) +{ + return AT91C_BASE_PIOA->PIO_PDSR & (1 << 23); +} + +static rt_int32_t at91_get_scl(void *data) +{ + return AT91C_BASE_PIOA->PIO_PDSR & (1 << 24); +} + +static void at91_udelay (rt_uint32_t us) +{ + rt_int32_t i; + for (; us > 0; us--) + { + i = 50000; + while(i > 0) + { + i--; + } + } +} + +static const struct rt_i2c_bit_ops bit_ops = { + RT_NULL, + at91_set_sda, + at91_set_scl, + at91_get_sda, + at91_get_scl, + + at91_udelay, + + 5, + 100 +}; + +int at91_i2c_init(void) +{ + struct rt_i2c_bus_device *bus; + + bus = rt_malloc(sizeof(struct rt_i2c_bus_device)); + if (bus == RT_NULL) + { + rt_kprintf("rt_malloc failed\n"); + return -RT_ENOMEM; + } + + rt_memset((void *)bus, 0, sizeof(struct rt_i2c_bus_device)); + + bus->priv = (void *)&bit_ops; + + at91_i2c_gpio_init(); + + rt_i2c_bit_add_bus(bus, "i2c0"); + + return 0; +} + +INIT_DEVICE_EXPORT(at91_i2c_init); + diff --git a/bsp/at91sam9g45/drivers/at91_mci.c b/bsp/at91sam9g45/drivers/at91_mci.c new file mode 100644 index 0000000000..0ad5590df6 --- /dev/null +++ b/bsp/at91sam9g45/drivers/at91_mci.c @@ -0,0 +1,924 @@ +/* + * File : at91_mci.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-07-25 weety first version + */ + +#include +#include +#include +#include +#include "at91_mci.h" + +#define USE_SLOT_B +//#define RT_MCI_DBG + +#ifdef RT_MCI_DBG +#define mci_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__) +#else +#define mci_dbg(fmt, ...) +#endif + +#define MMU_NOCACHE_ADDR(a) ((rt_uint32_t)a | (1UL<<31)) + +extern void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size); +extern void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size); + + +#define AT91C_MCI_ERRORS (AT91C_MCI_RINDE | AT91C_MCI_RDIRE | AT91C_MCI_RCRCE \ + | AT91C_MCI_RENDE | AT91C_MCI_RTOE | AT91C_MCI_DCRCE \ + | AT91C_MCI_DTOE | AT91C_MCI_OVRE | AT91C_MCI_UNRE) + +#define at91_mci_read(reg) readl(AT91C_BASE_MCI + (reg)) +#define at91_mci_write(reg, val) writel((val), AT91C_BASE_MCI + (reg)) + + +#define REQ_ST_INIT (1U << 0) +#define REQ_ST_CMD (1U << 1) +#define REQ_ST_STOP (1U << 2) + +struct at91_mci { + struct rt_mmcsd_host *host; + struct rt_mmcsd_req *req; + struct rt_mmcsd_cmd *cmd; + struct rt_timer timer; + //struct rt_semaphore sem_ack; + rt_uint32_t *buf; + rt_uint32_t current_status; +}; + +/* + * Reset the controller and restore most of the state + */ +static void at91_reset_host() +{ + rt_uint32_t mr; + rt_uint32_t sdcr; + rt_uint32_t dtor; + rt_uint32_t imr; + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + + imr = at91_mci_read(AT91C_MCI_IMR); + + at91_mci_write(AT91C_MCI_IDR, 0xffffffff); + + /* save current state */ + mr = at91_mci_read(AT91C_MCI_MR) & 0x7fff; + sdcr = at91_mci_read(AT91C_MCI_SDCR); + dtor = at91_mci_read(AT91C_MCI_DTOR); + + /* reset the controller */ + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIDIS | AT91C_MCI_SWRST); + + /* restore state */ + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIEN); + at91_mci_write(AT91C_MCI_MR, mr); + at91_mci_write(AT91C_MCI_SDCR, sdcr); + at91_mci_write(AT91C_MCI_DTOR, dtor); + at91_mci_write(AT91C_MCI_IER, imr); + + /* make sure sdio interrupts will fire */ + at91_mci_read(AT91C_MCI_SR); + rt_hw_interrupt_enable(level); + +} + + +/* + * Enable the controller + */ +static void at91_mci_enable() +{ + rt_uint32_t mr; + + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIEN); + at91_mci_write(AT91C_MCI_IDR, 0xffffffff); + at91_mci_write(AT91C_MCI_DTOR, AT91C_MCI_DTOMUL_1M | AT91C_MCI_DTOCYC); + mr = AT91C_MCI_PDCMODE | 0x34a; + + mr |= AT91C_MCI_RDPROOF | AT91C_MCI_WRPROOF; + + at91_mci_write(AT91C_MCI_MR, mr); + + /* use Slot A or B (only one at same time) */ + at91_mci_write(AT91C_MCI_SDCR, 1); /* use slot b */ +} + +/* + * Disable the controller + */ +static void at91_mci_disable() +{ + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIDIS | AT91C_MCI_SWRST); +} + +static void at91_timeout_timer(void *data) +{ + struct at91_mci *mci; + + mci = (struct at91_mci *)data; + + if (mci->req) + { + rt_kprintf("Timeout waiting end of packet\n"); + + if (mci->current_status == REQ_ST_CMD) + { + if (mci->req->cmd && mci->req->data) + { + mci->req->data->err = -RT_ETIMEOUT; + } + else + { + if (mci->req->cmd) + mci->req->cmd->err = -RT_ETIMEOUT; + } + } + else if (mci->current_status == REQ_ST_STOP) + { + mci->req->stop->err = -RT_ETIMEOUT; + } + + at91_reset_host(); + mmcsd_req_complete(mci->host); + } +} + +/* + * Prepare a dma read + */ +static void at91_mci_init_dma_read(struct at91_mci *mci) +{ + rt_uint8_t i; + struct rt_mmcsd_cmd *cmd; + struct rt_mmcsd_data *data; + rt_uint32_t length; + + mci_dbg("pre dma read\n"); + + cmd = mci->cmd; + if (!cmd) + { + mci_dbg("no command\n"); + return; + } + + data = cmd->data; + if (!data) + { + mci_dbg("no data\n"); + return; + } + + for (i = 0; i < 1; i++) + { + /* Check to see if this needs filling */ + if (i == 0) + { + if (at91_mci_read(AT91C_PDC_RCR) != 0) + { + mci_dbg("Transfer active in current\n"); + continue; + } + } + else { + if (at91_mci_read(AT91C_PDC_RNCR) != 0) + { + mci_dbg("Transfer active in next\n"); + continue; + } + } + + length = data->blksize * data->blks; + mci_dbg("dma address = %08X, length = %d\n", data->buf, length); + + if (i == 0) + { + at91_mci_write(AT91C_PDC_RPR, (rt_uint32_t)(data->buf)); + at91_mci_write(AT91C_PDC_RCR, (data->blksize & 0x3) ? length : length / 4); + } + else + { + at91_mci_write(AT91C_PDC_RNPR, (rt_uint32_t)(data->buf)); + at91_mci_write(AT91C_PDC_RNCR, (data->blksize & 0x3) ? length : length / 4); + } + } + + mci_dbg("pre dma read done\n"); +} + +/* + * Send a command + */ +static void at91_mci_send_command(struct at91_mci *mci, struct rt_mmcsd_cmd *cmd) +{ + rt_uint32_t cmdr, mr; + rt_uint32_t block_length; + struct rt_mmcsd_data *data = cmd->data; + struct rt_mmcsd_host *host = mci->host; + + rt_uint32_t blocks; + rt_uint32_t ier = 0; + rt_uint32_t length; + + mci->cmd = cmd; + + /* Needed for leaving busy state before CMD1 */ + if ((at91_mci_read(AT91C_MCI_SR) & AT91C_MCI_RTOE) && (cmd->cmd_code == 1)) + { + mci_dbg("Clearing timeout\n"); + at91_mci_write(AT91C_MCI_ARGR, 0); + at91_mci_write(AT91C_MCI_CMDR, AT91C_MCI_OPDCMD); + while (!(at91_mci_read(AT91C_MCI_SR) & AT91C_MCI_CMDRDY)) + { + /* spin */ + mci_dbg("Clearing: SR = %08X\n", at91_mci_read(AT91C_MCI_SR)); + } + } + + cmdr = cmd->cmd_code; + + if (resp_type(cmd) == RESP_NONE) + cmdr |= AT91C_MCI_RSPTYP_NONE; + else + { + /* if a response is expected then allow maximum response latancy */ + cmdr |= AT91C_MCI_MAXLAT; + /* set 136 bit response for R2, 48 bit response otherwise */ + if (resp_type(cmd) == RESP_R2) + cmdr |= AT91C_MCI_RSPTYP_136; + else + cmdr |= AT91C_MCI_RSPTYP_48; + } + + if (data) + { + + block_length = data->blksize; + blocks = data->blks; + + /* always set data start - also set direction flag for read */ + if (data->flags & DATA_DIR_READ) + cmdr |= (AT91C_MCI_TRDIR | AT91C_MCI_TRCMD_START); + else if (data->flags & DATA_DIR_WRITE) + cmdr |= AT91C_MCI_TRCMD_START; + + if (data->flags & DATA_STREAM) + cmdr |= AT91C_MCI_TRTYP_STREAM; + if (data->blks > 1) + cmdr |= AT91C_MCI_TRTYP_MULTIPLE; + } + else + { + block_length = 0; + blocks = 0; + } + + /*if (cmd->cmd_code == GO_IDLE_STATE) + { + cmdr |= AT91C_MCI_SPCMD_INIT; + }*/ + + if (cmd->cmd_code == STOP_TRANSMISSION) + cmdr |= AT91C_MCI_TRCMD_STOP; + + if (host->io_cfg.bus_mode == MMCSD_BUSMODE_OPENDRAIN) + cmdr |= AT91C_MCI_OPDCMD; + + /* + * Set the arguments and send the command + */ + mci_dbg("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n", + cmd->cmd_code, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91C_MCI_MR)); + + if (!data) + { + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); + at91_mci_write(AT91C_PDC_RPR, 0); + at91_mci_write(AT91C_PDC_RCR, 0); + at91_mci_write(AT91C_PDC_RNPR, 0); + at91_mci_write(AT91C_PDC_RNCR, 0); + at91_mci_write(AT91C_PDC_TPR, 0); + at91_mci_write(AT91C_PDC_TCR, 0); + at91_mci_write(AT91C_PDC_TNPR, 0); + at91_mci_write(AT91C_PDC_TNCR, 0); + ier = AT91C_MCI_CMDRDY; + } + else + { + /* zero block length and PDC mode */ + mr = at91_mci_read(AT91C_MCI_MR) & 0x5fff; + mr |= (data->blksize & 0x3) ? AT91C_MCI_PDCFBYTE : 0; + mr |= (block_length << 16); + mr |= AT91C_MCI_PDCMODE; + at91_mci_write(AT91C_MCI_MR, mr); + + at91_mci_write(AT91C_MCI_BLKR, + AT91C_MCI_BLKR_BCNT(blocks) | + AT91C_MCI_BLKR_BLKLEN(block_length)); + + /* + * Disable the PDC controller + */ + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); + + if (cmdr & AT91C_MCI_TRCMD_START) + { + if (cmdr & AT91C_MCI_TRDIR) + { + /* + * Handle a read + */ + + mmu_invalidate_dcache((rt_uint32_t)data->buf, data->blksize*data->blks); + at91_mci_init_dma_read(mci); + ier = AT91C_MCI_ENDRX /* | AT91C_MCI_RXBUFF */; + } + else + { + /* + * Handle a write + */ + length = block_length * blocks; + /* + * at91mci MCI1 rev2xx Data Write Operation and + * number of bytes erratum + */ + if (length < 12) + { + length = 12; + mci->buf = rt_malloc(length); + if (!mci->buf) + { + rt_kprintf("rt alloc tx buffer failed\n"); + cmd->err = -RT_ENOMEM; + mmcsd_req_complete(mci->host); + return; + } + rt_memset(mci->buf, 0, 12); + rt_memcpy(mci->buf, data->buf, length); + mmu_clean_dcache((rt_uint32_t)mci->buf, length); + at91_mci_write(AT91C_PDC_TPR, (rt_uint32_t)(mci->buf)); + at91_mci_write(AT91C_PDC_TCR, (data->blksize & 0x3) ? + length : length / 4); + } + else + { + mmu_clean_dcache((rt_uint32_t)data->buf, data->blksize*data->blks); + at91_mci_write(AT91C_PDC_TPR, (rt_uint32_t)(data->buf)); + at91_mci_write(AT91C_PDC_TCR, (data->blksize & 0x3) ? + length : length / 4); + } + mci_dbg("Transmitting %d bytes\n", length); + ier = AT91C_MCI_CMDRDY; + } + } + } + + /* + * Send the command and then enable the PDC - not the other way round as + * the data sheet says + */ + + at91_mci_write(AT91C_MCI_ARGR, cmd->arg); + at91_mci_write(AT91C_MCI_CMDR, cmdr); + + if (cmdr & AT91C_MCI_TRCMD_START) + { + if (cmdr & AT91C_MCI_TRDIR) + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_RXTEN); + } + + /* Enable selected interrupts */ + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_ERRORS | ier); +} + +/* + * Process the next step in the request + */ +static void at91_mci_process_next(struct at91_mci *mci) +{ + if (mci->current_status == REQ_ST_INIT) + { + mci->current_status = REQ_ST_CMD; + at91_mci_send_command(mci, mci->req->cmd); + } + else if ((mci->current_status == REQ_ST_CMD) && mci->req->stop) + { + mci->current_status = REQ_ST_STOP; + at91_mci_send_command(mci, mci->req->stop); + } + else + { + rt_timer_stop(&mci->timer); + /* the mci controller hangs after some transfers, + * and the workaround is to reset it after each transfer. + */ + at91_reset_host(); + mmcsd_req_complete(mci->host); + } +} + +/* + * Handle an MMC request + */ +static void at91_mci_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) +{ + rt_uint32_t timeout = RT_TICK_PER_SECOND; + struct at91_mci *mci = host->private_data; + mci->req = req; + mci->current_status = REQ_ST_INIT; + + rt_timer_control(&mci->timer, RT_TIMER_CTRL_SET_TIME, (void*)&timeout); + rt_timer_start(&mci->timer); + + at91_mci_process_next(mci); +} + +/* + * Handle transmitted data + */ +static void at91_mci_handle_transmitted(struct at91_mci *mci) +{ + struct rt_mmcsd_cmd *cmd; + struct rt_mmcsd_data *data; + + mci_dbg("Handling the transmit\n"); + + /* Disable the transfer */ + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); + + /* Now wait for cmd ready */ + at91_mci_write(AT91C_MCI_IDR, AT91C_MCI_TXBUFE); + + cmd = mci->cmd; + if (!cmd) return; + + data = cmd->data; + if (!data) return; + + if (data->blks > 1) + { + mci_dbg("multiple write : wait for BLKE...\n"); + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_BLKE); + } else + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_NOTBUSY); +} + + +/* + * Handle after a dma read + */ +static void at91_mci_post_dma_read(struct at91_mci *mci) +{ + struct rt_mmcsd_cmd *cmd; + struct rt_mmcsd_data *data; + + mci_dbg("post dma read\n"); + + cmd = mci->cmd; + if (!cmd) + { + mci_dbg("no command\n"); + return; + } + + data = cmd->data; + if (!data) + { + mci_dbg("no data\n"); + return; + } + + at91_mci_write(AT91C_MCI_IDR, AT91C_MCI_ENDRX); + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_RXBUFF); + + mci_dbg("post dma read done\n"); +} + +/*Handle after command sent ready*/ +static int at91_mci_handle_cmdrdy(struct at91_mci *mci) +{ + if (!mci->cmd) + return 1; + else if (!mci->cmd->data) + { + if (mci->current_status == REQ_ST_STOP) + { + /*After multi block write, we must wait for NOTBUSY*/ + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_NOTBUSY); + } + else return 1; + } + else if (mci->cmd->data->flags & DATA_DIR_WRITE) + { + /*After sendding multi-block-write command, start DMA transfer*/ + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_TXBUFE | AT91C_MCI_BLKE); + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_TXTEN); + } + + /* command not completed, have to wait */ + return 0; +} + +/* + * Handle a command that has been completed + */ +static void at91_mci_completed_command(struct at91_mci *mci, rt_uint32_t status) +{ + struct rt_mmcsd_cmd *cmd = mci->cmd; + struct rt_mmcsd_data *data = cmd->data; + + at91_mci_write(AT91C_MCI_IDR, 0xffffffff & ~(AT91C_MCI_SDIOIRQA | AT91C_MCI_SDIOIRQB)); + + cmd->resp[0] = at91_mci_read(AT91C_MCI_RSPR(0)); + cmd->resp[1] = at91_mci_read(AT91C_MCI_RSPR(1)); + cmd->resp[2] = at91_mci_read(AT91C_MCI_RSPR(2)); + cmd->resp[3] = at91_mci_read(AT91C_MCI_RSPR(3)); + + if (mci->buf) + { + //rt_memcpy(data->buf, mci->buf, data->blksize*data->blks); + rt_free(mci->buf); + mci->buf = RT_NULL; + } + + mci_dbg("Status = %08X/%08x [%08X %08X %08X %08X]\n", + status, at91_mci_read(AT91C_MCI_SR), + cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + + if (status & AT91C_MCI_ERRORS) + { + if ((status & AT91C_MCI_RCRCE) && (resp_type(cmd) & (RESP_R3|RESP_R4))) + { + cmd->err = 0; + } + else + { + if (status & (AT91C_MCI_DTOE | AT91C_MCI_DCRCE)) + { + if (data) + { + if (status & AT91C_MCI_DTOE) + data->err = -RT_ETIMEOUT; + else if (status & AT91C_MCI_DCRCE) + data->err = -RT_ERROR; + } + } + else + { + if (status & AT91C_MCI_RTOE) + cmd->err = -RT_ETIMEOUT; + else if (status & AT91C_MCI_RCRCE) + cmd->err = -RT_ERROR; + else + cmd->err = -RT_ERROR; + } + + rt_kprintf("error detected and set to %d/%d (cmd = %d)\n", + cmd->err, data ? data->err : 0, + cmd->cmd_code); + } + } + else + cmd->err = 0; + + at91_mci_process_next(mci); +} + +/* + * Handle an interrupt + */ +static void at91_mci_irq(int irq, void *param) +{ + struct at91_mci *mci = (struct at91_mci *)param; + rt_int32_t completed = 0; + rt_uint32_t int_status, int_mask; + + int_status = at91_mci_read(AT91C_MCI_SR); + int_mask = at91_mci_read(AT91C_MCI_IMR); + + mci_dbg("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask, + int_status & int_mask); + + int_status = int_status & int_mask; + + if (int_status & AT91C_MCI_ERRORS) + { + completed = 1; + + if (int_status & AT91C_MCI_UNRE) + mci_dbg("MMC: Underrun error\n"); + if (int_status & AT91C_MCI_OVRE) + mci_dbg("MMC: Overrun error\n"); + if (int_status & AT91C_MCI_DTOE) + mci_dbg("MMC: Data timeout\n"); + if (int_status & AT91C_MCI_DCRCE) + mci_dbg("MMC: CRC error in data\n"); + if (int_status & AT91C_MCI_RTOE) + mci_dbg("MMC: Response timeout\n"); + if (int_status & AT91C_MCI_RENDE) + mci_dbg("MMC: Response end bit error\n"); + if (int_status & AT91C_MCI_RCRCE) + mci_dbg("MMC: Response CRC error\n"); + if (int_status & AT91C_MCI_RDIRE) + mci_dbg("MMC: Response direction error\n"); + if (int_status & AT91C_MCI_RINDE) + mci_dbg("MMC: Response index error\n"); + } + else + { + /* Only continue processing if no errors */ + + if (int_status & AT91C_MCI_TXBUFE) + { + mci_dbg("TX buffer empty\n"); + at91_mci_handle_transmitted(mci); + } + + if (int_status & AT91C_MCI_ENDRX) + { + mci_dbg("ENDRX\n"); + at91_mci_post_dma_read(mci); + } + + if (int_status & AT91C_MCI_RXBUFF) + { + mci_dbg("RX buffer full\n"); + at91_mci_write(AT91C_PDC_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); + at91_mci_write(AT91C_MCI_IDR, AT91C_MCI_RXBUFF | AT91C_MCI_ENDRX); + completed = 1; + } + + if (int_status & AT91C_MCI_ENDTX) + mci_dbg("Transmit has ended\n"); + + if (int_status & AT91C_MCI_NOTBUSY) + { + mci_dbg("Card is ready\n"); + //at91_mci_update_bytes_xfered(host); + completed = 1; + } + + if (int_status & AT91C_MCI_DTIP) + mci_dbg("Data transfer in progress\n"); + + if (int_status & AT91C_MCI_BLKE) + { + mci_dbg("Block transfer has ended\n"); + if (mci->req->data && mci->req->data->blks > 1) + { + /* multi block write : complete multi write + * command and send stop */ + completed = 1; + } + else + { + at91_mci_write(AT91C_MCI_IER, AT91C_MCI_NOTBUSY); + } + } + + /*if (int_status & AT91C_MCI_SDIOIRQA) + rt_mmcsd_signal_sdio_irq(host->mmc);*/ + + if (int_status & AT91C_MCI_SDIOIRQB) + sdio_irq_wakeup(mci->host); + + if (int_status & AT91C_MCI_TXRDY) + mci_dbg("Ready to transmit\n"); + + if (int_status & AT91C_MCI_RXRDY) + mci_dbg("Ready to receive\n"); + + if (int_status & AT91C_MCI_CMDRDY) + { + mci_dbg("Command ready\n"); + completed = at91_mci_handle_cmdrdy(mci); + } + } + + if (completed) + { + mci_dbg("Completed command\n"); + at91_mci_write(AT91C_MCI_IDR, 0xffffffff & ~(AT91C_MCI_SDIOIRQA | AT91C_MCI_SDIOIRQB)); + at91_mci_completed_command(mci, int_status); + } + else + at91_mci_write(AT91C_MCI_IDR, int_status & ~(AT91C_MCI_SDIOIRQA | AT91C_MCI_SDIOIRQB)); + +} + + +/* + * Set the IOCFG + */ +static void at91_mci_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) +{ + rt_uint32_t clkdiv; + //struct at91_mci *mci = host->private_data; + rt_uint32_t at91_master_clock = clk_get_rate(clk_get("mck")); + + if (io_cfg->clock == 0) + { + /* Disable the MCI controller */ + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIDIS); + clkdiv = 0; + } + else + { + /* Enable the MCI controller */ + at91_mci_write(AT91C_MCI_CR, AT91C_MCI_MCIEN); + + if ((at91_master_clock % (io_cfg->clock * 2)) == 0) + clkdiv = ((at91_master_clock / io_cfg->clock) / 2) - 1; + else + clkdiv = (at91_master_clock / io_cfg->clock) / 2; + + mci_dbg("clkdiv = %d. mcck = %ld\n", clkdiv, + at91_master_clock / (2 * (clkdiv + 1))); + } + if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4) + { + mci_dbg("MMC: Setting controller bus width to 4\n"); + at91_mci_write(AT91C_MCI_SDCR, at91_mci_read(AT91C_MCI_SDCR) | AT91C_MCI_SDCBUS); + } + else + { + mci_dbg("MMC: Setting controller bus width to 1\n"); + at91_mci_write(AT91C_MCI_SDCR, at91_mci_read(AT91C_MCI_SDCR) & ~AT91C_MCI_SDCBUS); + } + + /* Set the clock divider */ + at91_mci_write(AT91C_MCI_MR, (at91_mci_read(AT91C_MCI_MR) & ~AT91C_MCI_CLKDIV) | clkdiv); + + /* maybe switch power to the card */ + switch (io_cfg->power_mode) + { + case MMCSD_POWER_OFF: + break; + case MMCSD_POWER_UP: + break; + case MMCSD_POWER_ON: + /*at91_mci_write(AT91C_MCI_ARGR, 0); + at91_mci_write(AT91C_MCI_CMDR, 0|AT91C_MCI_SPCMD_INIT|AT91C_MCI_OPDCMD); + mci_dbg("MCI_SR=0x%08x\n", at91_mci_read(AT91C_MCI_SR)); + while (!(at91_mci_read(AT91C_MCI_SR) & AT91C_MCI_CMDRDY)) + { + + } + mci_dbg("at91 mci power on\n");*/ + break; + default: + rt_kprintf("unknown power_mode %d\n", io_cfg->power_mode); + break; + } + +} + + +static void at91_mci_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t enable) +{ + at91_mci_write(enable ? AT91C_MCI_IER : AT91C_MCI_IDR, AT91C_MCI_SDIOIRQB); +} + + +static const struct rt_mmcsd_host_ops ops = { + at91_mci_request, + at91_mci_set_iocfg, + RT_NULL, + at91_mci_enable_sdio_irq, +}; + +void at91_mci_detect(int irq, void *param) +{ + rt_kprintf("mmcsd gpio detected\n"); +} + +static void mci_gpio_init() +{ +#ifdef USE_SLOT_B + AT91C_BASE_PIOA->PIO_PUER = (1 << 0)|(1 << 1)|(1 << 3)|(1 << 4)|(1 << 5); + AT91C_BASE_PIOA->PIO_PUDR = (1 << 8); + AT91C_BASE_PIOA->PIO_BSR = (1 << 0)|(1 << 1)|(1 << 3)|(1 << 4)|(1 << 5); + AT91C_BASE_PIOA->PIO_ASR = (1 << 8); + AT91C_BASE_PIOA->PIO_PDR = (1 << 0)|(1 << 1)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 8); + + AT91C_BASE_PIOA->PIO_IDR = (1 << 6)|(1 << 7); + AT91C_BASE_PIOA->PIO_PUER = (1 << 6)|(1 << 7); + AT91C_BASE_PIOA->PIO_ODR = (1 << 6)|(1 << 7); + AT91C_BASE_PIOA->PIO_PER = (1 << 6)|(1 << 7); +#else + AT91C_BASE_PIOA->PIO_PUER = (1 << 6)|(1 << 7)|(1 << 9)|(1 << 10)|(1 << 11); + AT91C_BASE_PIOA->PIO_ASR = (1 << 6)|(1 << 7)|(1 << 9)|(1 << 10)|(1 << 11)|(1 << 8); + AT91C_BASE_PIOA->PIO_PDR = (1 << 6)|(1 << 7)|(1 << 9)|(1 << 10)|(1 << 11)|(1 << 8); +#endif +} + +int at91_mci_init(void) +{ + struct rt_mmcsd_host *host; + struct at91_mci *mci; + + host = mmcsd_alloc_host(); + if (!host) + { + return -RT_ERROR; + } + + mci = rt_malloc(sizeof(struct at91_mci)); + if (!mci) + { + rt_kprintf("alloc mci failed\n"); + goto err; + } + + rt_memset(mci, 0, sizeof(struct at91_mci)); + + host->ops = &ops; + host->freq_min = 375000; + host->freq_max = 25000000; + host->valid_ocr = VDD_32_33 | VDD_33_34; + host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | \ + MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ; + host->max_seg_size = 65535; + host->max_dma_segs = 2; + host->max_blk_size = 512; + host->max_blk_count = 4096; + + mci->host = host; + + mci_gpio_init(); + AT91C_BASE_PMC->AT91C_PMC_PCER = 1 << AT91C_ID_MCI; //enable MCI clock + + at91_mci_disable(); + at91_mci_enable(); + + /* instal interrupt */ + rt_hw_interrupt_install(AT91SAM9260_ID_MCI, at91_mci_irq, + (void *)mci, "MMC"); + rt_hw_interrupt_umask(AT91SAM9260_ID_MCI); + rt_hw_interrupt_install(gpio_to_irq(AT91C_PIN_PA7), + at91_mci_detect, RT_NULL, "MMC_DETECT"); + rt_hw_interrupt_umask(gpio_to_irq(AT91C_PIN_PA7)); + + rt_timer_init(&mci->timer, "mci_timer", + at91_timeout_timer, + mci, + RT_TICK_PER_SECOND, + RT_TIMER_FLAG_PERIODIC); + + //rt_timer_start(&mci->timer); + + //rt_sem_init(&mci->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO); + + host->private_data = mci; + + mmcsd_change(host); + + return 0; + +err: + mmcsd_free_host(host); + + return -RT_ENOMEM; +} + +INIT_DEVICE_EXPORT(at91_mci_init); + +#include "finsh.h" +FINSH_FUNCTION_EXPORT(at91_mci_init, at91sam9260 sd init); + +void mci_dump(void) +{ + rt_uint32_t i; + + rt_kprintf("PIOA_PSR=0x%08x\n", readl(AT91C_PIOA+PIO_PSR)); + rt_kprintf("PIOA_ABSR=0x%08x\n", readl(AT91C_PIOA+PIO_ABSR)); + rt_kprintf("PIOA_PUSR=0x%08x\n", readl(AT91C_PIOA+PIO_PUSR)); + + for (i = 0; i <= 0x4c; i += 4) { + rt_kprintf("0x%08x:0x%08x\n", AT91SAM9260_BASE_MCI+i, at91_mci_read(i)); + } +} + +FINSH_FUNCTION_EXPORT(mci_dump, dump register for mci); diff --git a/bsp/at91sam9g45/drivers/at91_mci.h b/bsp/at91sam9g45/drivers/at91_mci.h new file mode 100644 index 0000000000..b3bfd289b1 --- /dev/null +++ b/bsp/at91sam9g45/drivers/at91_mci.h @@ -0,0 +1,124 @@ +/* + * File : at91_mci.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-06-09 weety first version + */ + +#ifndef __AT91C_MCI_H__ +#define __AT91C_MCI_H__ + +#define AT91C_MCI_CR 0x00 /* Control Register */ +#define AT91C_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */ +#define AT91C_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */ +#define AT91C_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */ +#define AT91C_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */ +#define AT91C_MCI_SWRST (1 << 7) /* Software Reset */ + +#define AT91C_MCI_MR 0x04 /* Mode Register */ +#define AT91C_MCI_CLKDIV (0xff << 0) /* Clock Divider */ +#define AT91C_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ +#define AT91C_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */ +#define AT91C_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */ +#define AT91C_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */ +#define AT91C_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ +#define AT91C_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ +#define AT91C_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ + +#define AT91C_MCI_DTOR 0x08 /* Data Timeout Register */ +#define AT91C_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */ +#define AT91C_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */ +#define AT91C_MCI_DTOMUL_1 (0 << 4) +#define AT91C_MCI_DTOMUL_16 (1 << 4) +#define AT91C_MCI_DTOMUL_128 (2 << 4) +#define AT91C_MCI_DTOMUL_256 (3 << 4) +#define AT91C_MCI_DTOMUL_1K (4 << 4) +#define AT91C_MCI_DTOMUL_4K (5 << 4) +#define AT91C_MCI_DTOMUL_64K (6 << 4) +#define AT91C_MCI_DTOMUL_1M (7 << 4) + +#define AT91C_MCI_SDCR 0x0c /* SD Card Register */ +#define AT91C_MCI_SDCSEL (3 << 0) /* SD Card Selector */ +#define AT91C_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */ + +#define AT91C_MCI_ARGR 0x10 /* Argument Register */ + +#define AT91C_MCI_CMDR 0x14 /* Command Register */ +#define AT91C_MCI_CMDNB (0x3f << 0) /* Command Number */ +#define AT91C_MCI_RSPTYP (3 << 6) /* Response Type */ +#define AT91C_MCI_RSPTYP_NONE (0 << 6) +#define AT91C_MCI_RSPTYP_48 (1 << 6) +#define AT91C_MCI_RSPTYP_136 (2 << 6) +#define AT91C_MCI_SPCMD (7 << 8) /* Special Command */ +#define AT91C_MCI_SPCMD_NONE (0 << 8) +#define AT91C_MCI_SPCMD_INIT (1 << 8) +#define AT91C_MCI_SPCMD_SYNC (2 << 8) +#define AT91C_MCI_SPCMD_ICMD (4 << 8) +#define AT91C_MCI_SPCMD_IRESP (5 << 8) +#define AT91C_MCI_OPDCMD (1 << 11) /* Open Drain Command */ +#define AT91C_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */ +#define AT91C_MCI_TRCMD (3 << 16) /* Transfer Command */ +#define AT91C_MCI_TRCMD_NONE (0 << 16) +#define AT91C_MCI_TRCMD_START (1 << 16) +#define AT91C_MCI_TRCMD_STOP (2 << 16) +#define AT91C_MCI_TRDIR (1 << 18) /* Transfer Direction */ +#define AT91C_MCI_TRTYP (3 << 19) /* Transfer Type */ +#define AT91C_MCI_TRTYP_BLOCK (0 << 19) +#define AT91C_MCI_TRTYP_MULTIPLE (1 << 19) +#define AT91C_MCI_TRTYP_STREAM (2 << 19) + +#define AT91C_MCI_BLKR 0x18 /* Block Register */ +#define AT91C_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ +#define AT91C_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */ + +#define AT91C_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ +#define AT91C_MCR_RDR 0x30 /* Receive Data Register */ +#define AT91C_MCR_TDR 0x34 /* Transmit Data Register */ + +#define AT91C_MCI_SR 0x40 /* Status Register */ +#define AT91C_MCI_CMDRDY (1U << 0) /* Command Ready */ +#define AT91C_MCI_RXRDY (1U << 1) /* Receiver Ready */ +#define AT91C_MCI_TXRDY (1U << 2) /* Transmit Ready */ +#define AT91C_MCI_BLKE (1U << 3) /* Data Block Ended */ +#define AT91C_MCI_DTIP (1U << 4) /* Data Transfer in Progress */ +#define AT91C_MCI_NOTBUSY (1U << 5) /* Data Not Busy */ +#define AT91C_MCI_ENDRX (1U << 6) /* End of RX Buffer */ +#define AT91C_MCI_ENDTX (1U << 7) /* End fo TX Buffer */ +#define AT91C_MCI_SDIOIRQA (1U << 8) /* SDIO Interrupt for Slot A */ +#define AT91C_MCI_SDIOIRQB (1U << 9) /* SDIO Interrupt for Slot B */ +#define AT91C_MCI_RXBUFF (1U << 14) /* RX Buffer Full */ +#define AT91C_MCI_TXBUFE (1U << 15) /* TX Buffer Empty */ +#define AT91C_MCI_RINDE (1U << 16) /* Response Index Error */ +#define AT91C_MCI_RDIRE (1U << 17) /* Response Direction Error */ +#define AT91C_MCI_RCRCE (1U << 18) /* Response CRC Error */ +#define AT91C_MCI_RENDE (1U << 19) /* Response End Bit Error */ +#define AT91C_MCI_RTOE (1U << 20) /* Reponse Time-out Error */ +#define AT91C_MCI_DCRCE (1U << 21) /* Data CRC Error */ +#define AT91C_MCI_DTOE (1U << 22) /* Data Time-out Error */ +#define AT91C_MCI_OVRE (1U << 30) /* Overrun */ +#define AT91C_MCI_UNRE (1U << 31) /* Underrun */ + +#define AT91C_MCI_IER 0x44 /* Interrupt Enable Register */ +#define AT91C_MCI_IDR 0x48 /* Interrupt Disable Register */ +#define AT91C_MCI_IMR 0x4c /* Interrupt Mask Register */ + +extern int at91_mci_init(void); + +#endif diff --git a/bsp/at91sam9g45/drivers/board.c b/bsp/at91sam9g45/drivers/board.c new file mode 100644 index 0000000000..c14055f310 --- /dev/null +++ b/bsp/at91sam9g45/drivers/board.c @@ -0,0 +1,248 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009 RT-Thread Develop 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-01-13 weety first version + */ + +#include +#include + +#include "board.h" +#include + +/** + * @addtogroup at91sam9g45 + */ +/*@{*/ +#if defined(__CC_ARM) +extern int Image$$ER_ZI$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$ER_ZI$$ZI$$Limit) +#elif (defined (__GNUC__)) +extern unsigned char __bss_end__; +#define HEAP_BEGIN (&__bss_end__) +#elif (defined (__ICCARM__)) +#pragma section=".noinit" +#define HEAP_BEGIN (__section_end(".noinit")) +#endif + +#define HEAP_END (((rt_uint32_t)HEAP_BEGIN & 0xF0000000) + 0x04000000) + +extern void rt_hw_interrupt_init(void); +extern void rt_hw_clock_init(void); + +extern void rt_hw_get_clock(void); +extern void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn); +extern void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv); +extern void rt_dbgu_isr(void); + +#define SAM9G45_BLOCK_SIZE 0x10000000 // 256M +#define MMU_SECTION_SIZE 0x100000 // 1M +#define PERIPHERALS_ADDR // 1M + +#define SECTION_END(sa) ((sa) + MMU_SECTION_SIZE - 1) // sa: start address +#define BLOCK_END(ba) ((ba) + SAM9G45_BLOCK_SIZE - 1) // ba: block address + +static struct mem_desc at91_mem_desc[] = { /* FIXME, hornby, to confirm MMU and memory */ + { 0x00000000, 0xFFFFFFFF , 0x00000000, RW_NCNB }, /* None cached for 4G memory */ + //{ 0x00000000, SECTION_END(0x00000000), 0x00000000, RW_CNB }, /* TLB for ITCM, ITCM map to address zero, 32KB */ + //{ 0x00200000, SECTION_END(0x00200000), 0x00200000, RW_CNB }, /* TLB for DTCM, 32KB */ + //{ 0x00300000, SECTION_END(0x00300000), 0x00300000, RW_CNB }, /* TLB for internal RAM, 64KB, we use it as global variable area */ + //{ 0x00600000, SECTION_END(0x00600000), 0x00600000, RW_NCNB }, /* TLB for UDPHS(DMA) */ + //{ 0x00700000, SECTION_END(0x00700000), 0x00700000, RW_NCNB }, /* TLB for UHP OHCI */ + //{ 0x00800000, SECTION_END(0x00800000), 0x00800000, RW_NCNB }, /* TLB for UHP EHCI */ + //{ 0x30000000, 0x30000000+0x00100000-1, 0x30000000, RW_CB }, /* 1M external SRAM for program code and stack */ + //{ 0x40000000, BLOCK_END(0x40000000), 0x40000000, RW_NCNB }, /* 256M for nand-flash controller */ + //{ 0x60000000, BLOCK_END(0x60000000), 0x60000000, RW_NCNB }, /* 256M for FPGA */ + //{ 0x70000000, 0x70000000+0x08000000-1, 0x70000000, RW_NCNB }, /* 128M for main DDR-SDRAM for print data */ + { 0x00000000, SECTION_END(0x00000000), 0x70000000, RW_CB }, /* isr */ + { 0x70000000, 0x70000000+0x08000000-1, 0x70000000, RW_CB }, /* 128M for main DDR-SDRAM for print data */ + //{ 0xFFF00000, SECTION_END(0xFFF00000), 0xFFF00000, RW_NCNB }, /* Internal Peripherals, 1MB */ +}; + + +#define PIT_CPIV(x) ((x) & AT91C_PITC_CPIV) +#define PIT_PICNT(x) (((x) & AT91C_PITC_PICNT) >> 20) + +static rt_uint32_t pit_cycle; /* write-once */ +static rt_uint32_t pit_cnt; /* access only w/system irq blocked */ + +/** + * This function will handle rtos timer + */ +void rt_timer_handler(int vector, void *param) +{ +#ifdef RT_USING_DBGU + if (readl(AT91C_DBGU_CSR) & AT91C_US_RXRDY) + { + rt_dbgu_isr(); + } +#endif + if (readl(AT91C_PITC_PISR) & AT91C_PITC_PITS) + { + unsigned nr_ticks; + + /* Get number of ticks performed before irq, and ack it */ + nr_ticks = PIT_PICNT(readl(AT91C_PITC_PIVR)); + while (nr_ticks--) + rt_tick_increase(); + } +} + +static void at91sam9g45_pit_reset(void) +{ + /* Disable timer and irqs */ + AT91C_BASE_PITC->PITC_PIMR = 0; + + /* Clear any pending interrupts, wait for PIT to stop counting */ + while (PIT_CPIV(readl(AT91C_PITC_PIVR)) != 0) + ; + + /* Start PIT but don't enable IRQ */ + //AT91C_BASE_PITC->PITC_PIMR = (pit_cycle - 1) | AT91C_PITC_PITEN; + pit_cnt += pit_cycle * PIT_PICNT(readl(AT91C_PITC_PIVR)); + AT91C_BASE_PITC->PITC_PIMR = + (pit_cycle - 1) | AT91C_PITC_PITEN | AT91C_PITC_PITIEN; + rt_kprintf("PIT_MR=0x%08x\n", readl(AT91C_PITC_PIMR)); +} + +/* + * Set up both clocksource and clockevent support. + */ +static void at91sam9g45_pit_init(void) +{ + rt_uint32_t pit_rate; + //rt_uint32_t bits; + + /* + * Use our actual MCK to figure out how many MCK/16 ticks per + * 1/HZ period (instead of a compile-time constant LATCH). + */ + pit_rate = clk_get_rate(clk_get("mck")) / 16; + rt_kprintf("pit_rate=%dHZ\n", pit_rate); + pit_cycle = (pit_rate + RT_TICK_PER_SECOND/2) / RT_TICK_PER_SECOND; + + /* Initialize and enable the timer */ + at91sam9g45_pit_reset(); +} + +/** + * This function will init pit for system ticks + */ +void rt_hw_timer_init() +{ + at91sam9g45_pit_init(); + + /* install interrupt handler */ + rt_hw_interrupt_install(AT91C_ID_SYS, rt_timer_handler, + RT_NULL, "system"); + rt_hw_interrupt_umask(AT91C_ID_SYS); +} + +void at91_tc1_init() +{ + AT91C_BASE_PMC->PMC_PCER = 1<DBGU_CSR & AT91C_US_TXRDY)) + ; + AT91C_BASE_DBGU->DBGU_THR = c; +} + +/** + * This function is used to display a string on console, normally, it's + * invoked by rt_kprintf + * + * @param str the displayed string + */ +void rt_hw_console_output(const char* str) +{ + while (*str) + { + if (*str=='\n') + { + at91_usart_putc('\r'); + } + + at91_usart_putc(*str++); + } +} + +static void rt_hw_console_init(void) +{ + int div; + int mode = 0; + + AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTTX | AT91C_US_RSTRX | + AT91C_US_RXDIS | AT91C_US_TXDIS; + mode |= AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | + AT91C_US_CHMODE_NORMAL; + mode |= AT91C_US_CHRL_8_BITS; + mode |= AT91C_US_NBSTOP_1_BIT; + mode |= AT91C_US_PAR_NONE; + AT91C_BASE_DBGU->DBGU_MR = mode; + div = (clk_get_rate(clk_get("mck")) / 16 + BPS/2) / BPS; + AT91C_BASE_DBGU->DBGU_BRGR = div; + AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN; +} + + +/** + * This function will init at91sam9g45 board + */ +void rt_hw_board_init() +{ + /* initialize the system clock */ + rt_hw_clock_init(); + + /* initialize console */ + rt_hw_console_init(); + + /* initialize mmu */ + rt_hw_mmu_init(at91_mem_desc, sizeof(at91_mem_desc)/sizeof(at91_mem_desc[0])); + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + + /* initialize early device */ +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + /* initialize timer0 */ + rt_hw_timer_init(); + +/* initialize board */ +#ifdef RT_USING_HEAP + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif +} + +/*@}*/ diff --git a/bsp/at91sam9g45/drivers/board.h b/bsp/at91sam9g45/drivers/board.h new file mode 100644 index 0000000000..a6ec4e0ef7 --- /dev/null +++ b/bsp/at91sam9g45/drivers/board.h @@ -0,0 +1,32 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-01-13 weety add board.h to this bsp + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/at91sam9g45/drivers/led.c b/bsp/at91sam9g45/drivers/led.c new file mode 100644 index 0000000000..fb8b417033 --- /dev/null +++ b/bsp/at91sam9g45/drivers/led.c @@ -0,0 +1,54 @@ +/* + * File : led.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-01-13 weety first version + */ + +#include +#include +#include "led.h" + +// BYHX A-Plus Board +#define LED0 (1UL << 30) +#define LED1 (1UL << 31) +#define LED2 (1UL << 29) +#define LED3 (1UL << 28) +#define LED_ALL (LED0 | LED1 | LED2 | LED3) + +void led_init(void) +{ + AT91C_BASE_PIOC->PIO_PER = LED_ALL; + AT91C_BASE_PIOC->PIO_OER = LED_ALL; + AT91C_BASE_PIOC->PIO_PPUER = LED_ALL; + AT91C_BASE_PIOC->PIO_SODR = LED_ALL; +} + +const static rt_uint32_t m_leds[] = { LED0, LED1, LED2, LED3 }; + +void led_on(int num) +{ + if (num < 4) AT91C_BASE_PIOC->PIO_CODR = m_leds[num]; +} + +void led_off(int num) +{ + if (num < 4) AT91C_BASE_PIOC->PIO_SODR = m_leds[num]; +} diff --git a/bsp/at91sam9g45/drivers/led.h b/bsp/at91sam9g45/drivers/led.h new file mode 100644 index 0000000000..f2967bc92d --- /dev/null +++ b/bsp/at91sam9g45/drivers/led.h @@ -0,0 +1,32 @@ +/* + * File : led.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + */ + +#ifndef __LED_H__ +#define __LED_H__ + +void led_init(void); +void led_on(int num); +void led_off(int num); + +#endif diff --git a/bsp/at91sam9g45/drivers/macb.c b/bsp/at91sam9g45/drivers/macb.c new file mode 100644 index 0000000000..b5cffaa1d2 --- /dev/null +++ b/bsp/at91sam9g45/drivers/macb.c @@ -0,0 +1,911 @@ +/* + * File : macb.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-03-18 weety first version + */ + +#include +#include +#include "lwipopts.h" +#include +#include "macb.h" + +#define MMU_NOCACHE_ADDR(a) ((rt_uint32_t)a | (1UL<<31)) + +extern void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size); +extern void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size); + +/* Cache macros - Packet buffers would be from pbuf pool which is cached */ +#define EMAC_VIRT_NOCACHE(addr) (addr) +#define EMAC_CACHE_INVALIDATE(addr, size) \ + mmu_invalidate_dcache((rt_uint32_t)addr, size) +#define EMAC_CACHE_WRITEBACK(addr, size) \ + mmu_clean_dcache((rt_uint32_t)addr, size) +#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \ + mmu_clean_invalidated_dcache((rt_uint32_t)addr, size) + +/* EMAC has BD's in cached memory - so need cache functions */ +#define BD_CACHE_INVALIDATE(addr, size) +#define BD_CACHE_WRITEBACK(addr, size) +#define BD_CACHE_WRITEBACK_INVALIDATE(addr, size) + +/* EMAC internal utility function */ +rt_inline unsigned long emac_virt_to_phys(unsigned long addr) +{ + return addr; +} + + +#define AT91SAM9260_SRAM0_VIRT_BASE (0x90000000) + +#define MACB_TX_SRAM + +#if defined(MACB_TX_SRAM) +#define MACB_TX_RING_SIZE 2 +#define MACB_TX_BUFFER_SIZE (1536 * MACB_TX_RING_SIZE) +#define TX_RING_BYTES (sizeof(struct macb_dma_desc) * MACB_TX_RING_SIZE) +#else +#define MACB_TX_RING_SIZE 16 +#define MACB_TX_BUFFER_SIZE (1536 * MACB_TX_RING_SIZE) +#endif + +#define MACB_RX_BUFFER_SIZE (4096*4) +#define MACB_RX_RING_SIZE (MACB_RX_BUFFER_SIZE / 128) + +#define DEF_TX_RING_PENDING (MACB_TX_RING_SIZE) + +#define TX_RING_GAP(macb) \ + (MACB_TX_RING_SIZE - (macb)->tx_pending) + +#define TX_BUFFS_AVAIL(macb) \ + (((macb)->tx_tail <= (macb)->tx_head) ? \ + (macb)->tx_tail + (macb)->tx_pending - (macb)->tx_head : \ + (macb)->tx_tail - (macb)->tx_head - TX_RING_GAP(macb)) + +#define NEXT_TX(n) (((n) + 1) & (MACB_TX_RING_SIZE - 1)) + +#define NEXT_RX(n) (((n) + 1) & (MACB_RX_RING_SIZE - 1)) + +/* minimum number of free TX descriptors before waking up TX process */ +#define MACB_TX_WAKEUP_THRESH (MACB_TX_RING_SIZE / 4) + +#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ + | MACB_BIT(ISR_ROVR)) + +#define MACB_TX_TIMEOUT 1000 +#define MACB_AUTONEG_TIMEOUT 5000000 +#define MACB_LINK_TIMEOUT 500000 + +#define CONFIG_RMII + +struct macb_dma_desc { + rt_uint32_t addr; + rt_uint32_t ctrl; +}; + +#define RXADDR_USED 0x00000001 +#define RXADDR_WRAP 0x00000002 + +#define RXBUF_FRMLEN_MASK 0x00000fff +#define RXBUF_FRAME_START 0x00004000 +#define RXBUF_FRAME_END 0x00008000 +#define RXBUF_TYPEID_MATCH 0x00400000 +#define RXBUF_ADDR4_MATCH 0x00800000 +#define RXBUF_ADDR3_MATCH 0x01000000 +#define RXBUF_ADDR2_MATCH 0x02000000 +#define RXBUF_ADDR1_MATCH 0x04000000 +#define RXBUF_BROADCAST 0x80000000 + +#define TXBUF_FRMLEN_MASK 0x000007ff +#define TXBUF_FRAME_END 0x00008000 +#define TXBUF_NOCRC 0x00010000 +#define TXBUF_EXHAUSTED 0x08000000 +#define TXBUF_UNDERRUN 0x10000000 +#define TXBUF_MAXRETRY 0x20000000 +#define TXBUF_WRAP 0x40000000 +#define TXBUF_USED 0x80000000 + +/* Duplex, half or full. */ +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 + +#define MAX_ADDR_LEN 6 +struct rt_macb_eth +{ + /* inherit from ethernet device */ + struct eth_device parent; + + unsigned int regs; + + unsigned int rx_tail; + unsigned int tx_head; + unsigned int tx_tail; + unsigned int rx_pending; + unsigned int tx_pending; + + void *rx_buffer; + void *tx_buffer; + struct macb_dma_desc *rx_ring; + struct macb_dma_desc *tx_ring; + + unsigned long rx_buffer_dma; + unsigned long tx_buffer_dma; + unsigned long rx_ring_dma; + unsigned long tx_ring_dma; + + unsigned int tx_stop; + + /* interface address info. */ + rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ + unsigned short phy_addr; + + struct rt_semaphore mdio_bus_lock; + struct rt_semaphore tx_lock; + struct rt_semaphore rx_lock; + struct rt_semaphore tx_ack; + rt_uint32_t speed; + rt_uint32_t duplex; + rt_uint32_t link; + struct rt_timer timer; +}; +static struct rt_macb_eth macb_device; + +static void macb_tx(struct rt_macb_eth *macb); + +static void udelay(rt_uint32_t us) +{ + rt_uint32_t len; + for (;us > 0; us --) + for (len = 0; len < 10; len++ ); +} + +static void rt_macb_isr(int irq, void *param) +{ + struct rt_macb_eth *macb = (struct rt_macb_eth *)param; + rt_device_t dev = &(macb->parent.parent); + rt_uint32_t status, rsr, tsr; + + status = macb_readl(macb, ISR); + + while (status) { + + if (status & MACB_RX_INT_FLAGS) + { + rsr = macb_readl(macb, RSR); + macb_writel(macb, RSR, rsr); + /* a frame has been received */ + eth_device_ready(&(macb_device.parent)); + + } + + if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) | + MACB_BIT(ISR_RLE))) + { + macb_tx(macb); + } + + /* + * Link change detection isn't possible with RMII, so we'll + * add that if/when we get our hands on a full-blown MII PHY. + */ + + if (status & MACB_BIT(HRESP)) + { + /* + * TODO: Reset the hardware, and maybe move the printk + * to a lower-priority context as well (work queue?) + */ + rt_kprintf("%s: DMA bus error: HRESP not OK\n", + dev->parent.name); + } + + status = macb_readl(macb, ISR); + } + + +} + +static int macb_mdio_write(struct rt_macb_eth *macb, rt_uint8_t reg, rt_uint16_t value) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + rt_sem_take(&macb->mdio_bus_lock, RT_WAITING_FOREVER); + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 1) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2) + | MACB_BF(DATA, value)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + rt_sem_release(&macb->mdio_bus_lock); +} + +static int macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + rt_sem_take(&macb->mdio_bus_lock, RT_WAITING_FOREVER); + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 2) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + frame = macb_readl(macb, MAN); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + rt_sem_release(&macb->mdio_bus_lock); + + return MACB_BFEXT(DATA, frame); +} + +static void macb_phy_reset(rt_device_t dev) +{ + int i; + rt_uint16_t status, adv; + struct rt_macb_eth *macb = dev->user_data;; + + adv = ADVERTISE_CSMA | ADVERTISE_ALL; + macb_mdio_write(macb, MII_ADVERTISE, adv); + rt_kprintf("%s: Starting autonegotiation...\n", dev->parent.name); + macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE + | BMCR_ANRESTART)); + + for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) + { + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_ANEGCOMPLETE) + break; + udelay(100); + } + + if (status & BMSR_ANEGCOMPLETE) + rt_kprintf("%s: Autonegotiation complete\n", dev->parent.name); + else + rt_kprintf("%s: Autonegotiation timed out (status=0x%04x)\n", + dev->parent.name, status); +} + + +static int macb_phy_init(rt_device_t dev) +{ + struct rt_macb_eth *macb = dev->user_data; + rt_uint32_t ncfgr; + rt_uint16_t phy_id, status, adv, lpa; + int media, speed, duplex; + int i; + + /* Check if the PHY is up to snuff... */ + phy_id = macb_mdio_read(macb, MII_PHYSID1); + if (phy_id == 0xffff) + { + rt_kprintf("%s: No PHY present\n", dev->parent.name); + return 0; + } + + status = macb_mdio_read(macb, MII_BMSR); + if (!(status & BMSR_LSTATUS)) + { + /* Try to re-negotiate if we don't have link already. */ + macb_phy_reset(dev); + + for (i = 0; i < MACB_LINK_TIMEOUT / 100; i++) + { + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_LSTATUS) + break; + udelay(100); + } + } + + if (!(status & BMSR_LSTATUS)) + { + rt_kprintf("%s: link down (status: 0x%04x)\n", + dev->parent.name, status); + return 0; + } + else + { + adv = macb_mdio_read(macb, MII_ADVERTISE); + lpa = macb_mdio_read(macb, MII_LPA); + media = mii_nway_result(lpa & adv); + speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) + ? 1 : 0); + duplex = (media & ADVERTISE_FULL) ? 1 : 0; + rt_kprintf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", + dev->parent.name, + speed ? "100" : "10", + duplex ? "full" : "half", + lpa); + + ncfgr = macb_readl(macb, NCFGR); + ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); + if (speed) + ncfgr |= MACB_BIT(SPD); + if (duplex) + ncfgr |= MACB_BIT(FD); + macb_writel(macb, NCFGR, ncfgr); + return 1; + } +} + +void macb_update_link(void *param) +{ + struct rt_macb_eth *macb = (struct rt_macb_eth *)param; + rt_device_t dev = &macb->parent.parent; + int status, status_change = 0; + rt_uint32_t link; + rt_uint32_t media; + rt_uint16_t adv, lpa; + + /* Do a fake read */ + status = macb_mdio_read(macb, MII_BMSR); + if (status < 0) + return; + + /* Read link and autonegotiation status */ + status = macb_mdio_read(macb, MII_BMSR); + if (status < 0) + return; + + if ((status & BMSR_LSTATUS) == 0) + link = 0; + else + link = 1; + + if (link != macb->link) + { + macb->link = link; + status_change = 1; + } + + if (status_change) + { + if (macb->link) + { + adv = macb_mdio_read(macb, MII_ADVERTISE); + lpa = macb_mdio_read(macb, MII_LPA); + media = mii_nway_result(lpa & adv); + macb->speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) + ? 100 : 10); + macb->duplex = (media & ADVERTISE_FULL) ? 1 : 0; + rt_kprintf("%s: link up (%dMbps/%s-duplex)\n", + dev->parent.name, macb->speed, + DUPLEX_FULL == macb->duplex ? "Full":"Half"); + eth_device_linkchange(&macb->parent, RT_TRUE); + } + else + { + rt_kprintf("%s: link down\n", dev->parent.name); + eth_device_linkchange(&macb->parent, RT_FALSE); + } + + } + +} + +/* RT-Thread Device Interface */ +/* initialize the interface */ + +static rt_err_t rt_macb_init(rt_device_t dev) +{ + struct rt_macb_eth *macb = dev->user_data; + unsigned long paddr; + rt_uint32_t hwaddr_bottom; + rt_uint16_t hwaddr_top; + int i; + + /* + * macb_halt should have been called at some point before now, + * so we'll assume the controller is idle. + */ + + /* initialize DMA descriptors */ + paddr = macb->rx_buffer_dma; + for (i = 0; i < MACB_RX_RING_SIZE; i++) + { + if (i == (MACB_RX_RING_SIZE - 1)) + paddr |= RXADDR_WRAP; + macb->rx_ring[i].addr = paddr; + macb->rx_ring[i].ctrl = 0; + paddr += 128; + } + paddr = macb->tx_buffer_dma; + for (i = 0; i < MACB_TX_RING_SIZE; i++) + { + macb->tx_ring[i].addr = paddr; + if (i == (MACB_TX_RING_SIZE - 1)) + macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; + else + macb->tx_ring[i].ctrl = TXBUF_USED; + paddr += 1536; + } + macb->rx_tail = macb->tx_head = macb->tx_tail = 0; + + BD_CACHE_WRITEBACK_INVALIDATE(macb->rx_ring, MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + BD_CACHE_WRITEBACK_INVALIDATE(macb->tx_ring, MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc)); + macb_writel(macb, RBQP, macb->rx_ring_dma); + macb_writel(macb, TBQP, macb->tx_ring_dma); + + /* set hardware address */ + hwaddr_bottom = (*((rt_uint32_t *)macb->dev_addr)); + macb_writel(macb, SA1B, hwaddr_bottom); + hwaddr_top = (*((rt_uint16_t *)(macb->dev_addr + 4))); + macb_writel(macb, SA1T, hwaddr_top); + + + /* choose RMII or MII mode. This depends on the board */ +#ifdef CONFIG_RMII + macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); +#else + macb_writel(macb, USRIO, MACB_BIT(CLKEN)); +#endif /* CONFIG_RMII */ + + if (!macb_phy_init(dev)) + return -RT_ERROR; + + /* Enable TX and RX */ + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(MPE)); + + /* Enable interrupts */ + macb_writel(macb, IER, (MACB_BIT(RCOMP) + | MACB_BIT(RXUBR) + | MACB_BIT(ISR_TUND) + | MACB_BIT(ISR_RLE) + | MACB_BIT(TXERR) + | MACB_BIT(TCOMP) + | MACB_BIT(ISR_ROVR) + | MACB_BIT(HRESP))); + + /* instal interrupt */ + rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, + (void *)macb, "emac"); + rt_hw_interrupt_umask(AT91SAM9260_ID_EMAC); + + rt_timer_init(&macb->timer, "link_timer", + macb_update_link, + (void *)macb, + RT_TICK_PER_SECOND, + RT_TIMER_FLAG_PERIODIC); + + rt_timer_start(&macb->timer); + + return RT_EOK; +} + +static rt_err_t rt_macb_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_macb_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t rt_macb_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t rt_macb_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t rt_macb_control(rt_device_t dev, int cmd, void *args) +{ + switch(cmd) + { + case NIOCTL_GADDR: + /* get mac address */ + if(args) rt_memcpy(args, macb_device.dev_addr, 6); + else return -RT_ERROR; + break; + + default : + break; + } + + return RT_EOK; +} + +static void macb_tx(struct rt_macb_eth *macb) +{ + unsigned int tail; + unsigned int head; + rt_uint32_t status; + + status = macb_readl(macb, TSR); + macb_writel(macb, TSR, status); + + /*rt_kprintf("macb_tx status = %02lx\n", + (unsigned long)status);*/ + + if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) + { + int i; + rt_kprintf("%s: TX %s, resetting buffers\n", + macb->parent.parent.parent.name, status & MACB_BIT(UND) ? + "underrun" : "retry limit exceeded"); + + /* Transfer ongoing, disable transmitter, to avoid confusion */ + if (status & MACB_BIT(TGO)) + macb_writel(macb, NCR, macb_readl(macb, NCR) & ~MACB_BIT(TE)); + + head = macb->tx_head; + + /*Mark all the buffer as used to avoid sending a lost buffer*/ + for (i = 0; i < MACB_TX_RING_SIZE; i++) + macb->tx_ring[i].ctrl = MACB_BIT(TX_USED); + + /* free transmit buffer in upper layer*/ + + macb->tx_head = macb->tx_tail = 0; + + /* Enable the transmitter again */ + if (status & MACB_BIT(TGO)) + macb_writel(macb, NCR, macb_readl(macb, NCR) | MACB_BIT(TE)); + } + + if (!(status & MACB_BIT(COMP))) + /* + * This may happen when a buffer becomes complete + * between reading the ISR and scanning the + * descriptors. Nothing to worry about. + */ + return; + + head = macb->tx_head; + for (tail = macb->tx_tail; tail != head; tail = NEXT_TX(tail)) + { + rt_uint32_t bufstat; + + bufstat = macb->tx_ring[tail].ctrl; + + if (!(bufstat & MACB_BIT(TX_USED))) + break; + } + + macb->tx_tail = tail; + if ((macb->tx_stop == 1) && + TX_BUFFS_AVAIL(macb) > MACB_TX_WAKEUP_THRESH) + rt_sem_release(&macb->tx_ack); +} + + +/* ethernet device interface */ +/* transmit packet. */ +rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p) +{ + unsigned long ctrl; + struct pbuf* q; + rt_uint8_t* bufptr; + rt_uint32_t mapping; + struct rt_macb_eth *macb = dev->user_data; + unsigned int tx_head = macb->tx_head; + + rt_sem_take(&macb->tx_lock, RT_WAITING_FOREVER); + if (TX_BUFFS_AVAIL(macb) < 1) + { + rt_sem_release(&macb->tx_lock); + rt_kprintf("Tx Ring full!\n"); + rt_kprintf("tx_head = %u, tx_tail = %u\n", + macb->tx_head, macb->tx_tail); + return -RT_ERROR; + } + + macb->tx_stop = 0; + + ctrl = p->tot_len & TXBUF_FRMLEN_MASK; + ctrl |= TXBUF_FRAME_END; + if (tx_head == (MACB_TX_RING_SIZE - 1)) + { + ctrl |= TXBUF_WRAP; + } +#if defined(MACB_TX_SRAM) + bufptr = macb->tx_buffer + tx_head * 1536; +#else + mapping = (unsigned long)macb->tx_buffer + tx_head * 1536; + bufptr = (rt_uint8_t *)mapping; +#endif + + for (q = p; q != NULL; q = q->next) + { + memcpy(bufptr, q->payload, q->len); + bufptr += q->len; + } +#if !defined(MACB_TX_SRAM) + EMAC_CACHE_WRITEBACK(mapping, p->tot_len); +#endif + macb->tx_ring[tx_head].ctrl = ctrl; + BD_CACHE_WRITEBACK_INVALIDATE(&macb->tx_ring[tx_head], sizeof(struct macb_dma_desc)); + tx_head = NEXT_TX(tx_head); + macb->tx_head = tx_head; + macb_writel(macb, NCR, macb_readl(macb, NCR) | MACB_BIT(TSTART)); + macb_writel(macb, NCR, macb_readl(macb, NCR) | MACB_BIT(TSTART)); + + if (TX_BUFFS_AVAIL(macb) < 1) + { + macb->tx_stop = 1; + rt_sem_take(&macb->tx_ack, RT_WAITING_FOREVER); + } + rt_sem_release(&macb->tx_lock); + + return RT_EOK; +} + +static void reclaim_rx_buffers(struct rt_macb_eth *macb, + unsigned int new_tail) +{ + unsigned int i; + + i = macb->rx_tail; + while (i > new_tail) + { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + if (i > MACB_RX_RING_SIZE) + i = 0; + } + + while (i < new_tail) + { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + } + + macb->rx_tail = new_tail; +} + +/* reception packet. */ +struct pbuf *rt_macb_rx(rt_device_t dev) +{ + struct rt_macb_eth *macb = dev->user_data; + struct pbuf* p = RT_NULL; + rt_uint32_t len; + unsigned int rx_tail = macb->rx_tail; + void *buffer; + int wrapped = 0; + rt_uint32_t status; + + rt_sem_take(&macb->rx_lock, RT_WAITING_FOREVER); + for (;;) + { + if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) + break; + + status = macb->rx_ring[rx_tail].ctrl; + if (status & RXBUF_FRAME_START) + { + if (rx_tail != macb->rx_tail) + reclaim_rx_buffers(macb, rx_tail); + wrapped = 0; + } + + if (status & RXBUF_FRAME_END) + { + buffer = (void *)((unsigned int)macb->rx_buffer + 128 * macb->rx_tail); + len = status & RXBUF_FRMLEN_MASK; + p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); + if (!p) + { + rt_kprintf("alloc pbuf failed\n"); + break; + } + if (wrapped) + { + unsigned int headlen, taillen; + + headlen = 128 * (MACB_RX_RING_SIZE + - macb->rx_tail); + taillen = len - headlen; + EMAC_CACHE_INVALIDATE(buffer, headlen); + EMAC_CACHE_INVALIDATE(macb->rx_buffer, taillen); + memcpy((void *)p->payload, buffer, headlen); + memcpy((void *)((unsigned int)p->payload + headlen), + macb->rx_buffer, taillen); + } + else + { + EMAC_CACHE_INVALIDATE(buffer, len); + memcpy((void *)p->payload, buffer, p->len); + } + + if (++rx_tail >= MACB_RX_RING_SIZE) + rx_tail = 0; + reclaim_rx_buffers(macb, rx_tail); + break; + } + else + { + if (++rx_tail >= MACB_RX_RING_SIZE) + { + wrapped = 1; + rx_tail = 0; + } + } + } + + rt_sem_release(&macb->rx_lock); + + return p; +} + +void macb_gpio_init() +{ + /* Pins used for MII and RMII */ + AT91C_BASE_PIOA->PIO_PDR, (1 << 19)|(1 << 17)|(1 << 14)|(1 << 15)|(1 << 18)|(1 << 16)|(1 << 12)|(1 << 13)|(1 << 21)|(1 << 20); + AT91C_BASE_PIOA->PIO_ASR, (1 << 19)|(1 << 17)|(1 << 14)|(1 << 15)|(1 << 18)|(1 << 16)|(1 << 12)|(1 << 13)|(1 << 21)|(1 << 20); + +#ifndef GONFIG_RMII + AT91C_BASE_PIOA->PIO_PDR, (1 << 22)|(1 << 23)|(1 << 24)|(1 << 25)|(1 << 26)|(1 << 27)|(1 << 28)|(1 << 29); + AT91C_BASE_PIOA->PIO_ASR, (1 << 22)|(1 << 23)|(1 << 24)|(1 << 25)|(1 << 26)|(1 << 27)|(1 << 28)|(1 << 29); +#endif +} + +rt_err_t macb_initialize() +{ + struct rt_macb_eth *macb = &macb_device; + unsigned long macb_hz; + rt_uint32_t ncfgr; + +#if defined(MACB_TX_SRAM) + macb->tx_ring_dma = AT91SAM9260_SRAM0_BASE; + macb->tx_ring = (struct macb_dma_desc *)AT91SAM9260_SRAM0_VIRT_BASE; + macb->tx_buffer = (char *) macb->tx_ring + TX_RING_BYTES; + macb->tx_buffer_dma = macb->tx_ring_dma + TX_RING_BYTES; +#else + macb->tx_ring = rt_malloc(MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + if (macb->tx_ring == RT_NULL) + goto err1; + EMAC_CACHE_INVALIDATE(macb->tx_ring, MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc)); + macb->tx_ring_dma = emac_virt_to_phys((unsigned long)macb->tx_ring); + macb->tx_ring = (struct macb_dma_desc *)MMU_NOCACHE_ADDR((unsigned long)macb->tx_ring); + macb->tx_buffer = rt_malloc(MACB_TX_BUFFER_SIZE); + if (macb->tx_buffer == RT_NULL) + goto err2; + macb->tx_buffer_dma = emac_virt_to_phys((unsigned long)macb->tx_buffer); +#endif + + macb->rx_ring = rt_malloc(MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + if (macb->rx_ring == RT_NULL) + goto err3; + EMAC_CACHE_INVALIDATE(macb->rx_ring, MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + macb->rx_ring_dma = emac_virt_to_phys((unsigned long)macb->rx_ring); + macb->rx_ring = (struct macb_dma_desc *)MMU_NOCACHE_ADDR((unsigned long)macb->rx_ring); + macb->rx_buffer = rt_malloc(MACB_RX_BUFFER_SIZE); + if (macb->rx_buffer == RT_NULL) + goto err4; + macb->rx_buffer_dma = emac_virt_to_phys((unsigned long)macb->rx_buffer); + + macb->tx_pending = DEF_TX_RING_PENDING; + + macb->regs = AT91SAM9260_BASE_EMAC; + macb->phy_addr = 0x00; + + /* + * Do some basic initialization so that we at least can talk + * to the PHY + */ + macb_hz = clk_get_rate(clk_get("mck")); + if (macb_hz < 20000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV8); + else if (macb_hz < 40000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV16); + else if (macb_hz < 80000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV32); + else + ncfgr = MACB_BF(CLK, MACB_CLK_DIV64); + + macb_writel(macb, NCFGR, ncfgr); + + macb->link = 0; + + return RT_EOK; + +err4: + rt_free(macb->rx_ring); + macb->rx_ring = RT_NULL; +err3: +#if !defined(MACB_TX_SRAM) + rt_free(macb->tx_buffer); + macb->tx_buffer = RT_NULL; +err2: + rt_free(macb->tx_ring); + macb->tx_ring = RT_NULL; +err1: +#endif + return -RT_ENOMEM; +} + +int rt_hw_macb_init(void) +{ + rt_err_t ret; + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; //enable macb clock + macb_gpio_init(); + rt_memset(&macb_device, 0, sizeof(macb_device)); + ret = macb_initialize(); + if (ret != RT_EOK) + { + rt_kprintf("AT91 EMAC initialized failed\n"); + return -1; + } + rt_sem_init(&macb_device.tx_ack, "tx_ack", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(&macb_device.tx_lock, "tx_lock", 1, RT_IPC_FLAG_FIFO); + rt_sem_init(&macb_device.rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO); + + macb_device.dev_addr[0] = 0x00; + macb_device.dev_addr[1] = 0x60; + macb_device.dev_addr[2] = 0x6E; + macb_device.dev_addr[3] = 0x11; + macb_device.dev_addr[4] = 0x22; + macb_device.dev_addr[5] = 0x33; + + macb_device.parent.parent.init = rt_macb_init; + macb_device.parent.parent.open = rt_macb_open; + macb_device.parent.parent.close = rt_macb_close; + macb_device.parent.parent.read = rt_macb_read; + macb_device.parent.parent.write = rt_macb_write; + macb_device.parent.parent.control = rt_macb_control; + macb_device.parent.parent.user_data = &macb_device; + + macb_device.parent.eth_rx = rt_macb_rx; + macb_device.parent.eth_tx = rt_macb_tx; + + rt_sem_init(&macb_device.mdio_bus_lock, "mdio_bus_lock", 1, RT_IPC_FLAG_FIFO); + + eth_device_init(&(macb_device.parent), "e0"); + + return 0; +} + +INIT_DEVICE_EXPORT(rt_hw_macb_init); + diff --git a/bsp/at91sam9g45/drivers/macb.h b/bsp/at91sam9g45/drivers/macb.h new file mode 100644 index 0000000000..9df2883534 --- /dev/null +++ b/bsp/at91sam9g45/drivers/macb.h @@ -0,0 +1,346 @@ +/* + * File : macb.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-03-18 weety first version + */ +#ifndef _MACB_H +#define _MACB_H +#include + +/* MACB register offsets */ +#define MACB_NCR 0x0000 +#define MACB_NCFGR 0x0004 +#define MACB_NSR 0x0008 +#define MACB_TSR 0x0014 +#define MACB_RBQP 0x0018 +#define MACB_TBQP 0x001c +#define MACB_RSR 0x0020 +#define MACB_ISR 0x0024 +#define MACB_IER 0x0028 +#define MACB_IDR 0x002c +#define MACB_IMR 0x0030 +#define MACB_MAN 0x0034 +#define MACB_PTR 0x0038 +#define MACB_PFR 0x003c +#define MACB_FTO 0x0040 +#define MACB_SCF 0x0044 +#define MACB_MCF 0x0048 +#define MACB_FRO 0x004c +#define MACB_FCSE 0x0050 +#define MACB_ALE 0x0054 +#define MACB_DTF 0x0058 +#define MACB_LCOL 0x005c +#define MACB_EXCOL 0x0060 +#define MACB_TUND 0x0064 +#define MACB_CSE 0x0068 +#define MACB_RRE 0x006c +#define MACB_ROVR 0x0070 +#define MACB_RSE 0x0074 +#define MACB_ELE 0x0078 +#define MACB_RJA 0x007c +#define MACB_USF 0x0080 +#define MACB_STE 0x0084 +#define MACB_RLE 0x0088 +#define MACB_TPF 0x008c +#define MACB_HRB 0x0090 +#define MACB_HRT 0x0094 +#define MACB_SA1B 0x0098 +#define MACB_SA1T 0x009c +#define MACB_SA2B 0x00a0 +#define MACB_SA2T 0x00a4 +#define MACB_SA3B 0x00a8 +#define MACB_SA3T 0x00ac +#define MACB_SA4B 0x00b0 +#define MACB_SA4T 0x00b4 +#define MACB_TID 0x00b8 +#define MACB_TPQ 0x00bc +#define MACB_USRIO 0x00c0 +#define MACB_WOL 0x00c4 + +/* Bitfields in NCR */ +#define MACB_LB_OFFSET 0 +#define MACB_LB_SIZE 1 +#define MACB_LLB_OFFSET 1 +#define MACB_LLB_SIZE 1 +#define MACB_RE_OFFSET 2 +#define MACB_RE_SIZE 1 +#define MACB_TE_OFFSET 3 +#define MACB_TE_SIZE 1 +#define MACB_MPE_OFFSET 4 +#define MACB_MPE_SIZE 1 +#define MACB_CLRSTAT_OFFSET 5 +#define MACB_CLRSTAT_SIZE 1 +#define MACB_INCSTAT_OFFSET 6 +#define MACB_INCSTAT_SIZE 1 +#define MACB_WESTAT_OFFSET 7 +#define MACB_WESTAT_SIZE 1 +#define MACB_BP_OFFSET 8 +#define MACB_BP_SIZE 1 +#define MACB_TSTART_OFFSET 9 +#define MACB_TSTART_SIZE 1 +#define MACB_THALT_OFFSET 10 +#define MACB_THALT_SIZE 1 +#define MACB_NCR_TPF_OFFSET 11 +#define MACB_NCR_TPF_SIZE 1 +#define MACB_TZQ_OFFSET 12 +#define MACB_TZQ_SIZE 1 + +/* Bitfields in NCFGR */ +#define MACB_SPD_OFFSET 0 +#define MACB_SPD_SIZE 1 +#define MACB_FD_OFFSET 1 +#define MACB_FD_SIZE 1 +#define MACB_BIT_RATE_OFFSET 2 +#define MACB_BIT_RATE_SIZE 1 +#define MACB_JFRAME_OFFSET 3 +#define MACB_JFRAME_SIZE 1 +#define MACB_CAF_OFFSET 4 +#define MACB_CAF_SIZE 1 +#define MACB_NBC_OFFSET 5 +#define MACB_NBC_SIZE 1 +#define MACB_NCFGR_MTI_OFFSET 6 +#define MACB_NCFGR_MTI_SIZE 1 +#define MACB_UNI_OFFSET 7 +#define MACB_UNI_SIZE 1 +#define MACB_BIG_OFFSET 8 +#define MACB_BIG_SIZE 1 +#define MACB_EAE_OFFSET 9 +#define MACB_EAE_SIZE 1 +#define MACB_CLK_OFFSET 10 +#define MACB_CLK_SIZE 2 +#define MACB_RTY_OFFSET 12 +#define MACB_RTY_SIZE 1 +#define MACB_PAE_OFFSET 13 +#define MACB_PAE_SIZE 1 +#define MACB_RBOF_OFFSET 14 +#define MACB_RBOF_SIZE 2 +#define MACB_RLCE_OFFSET 16 +#define MACB_RLCE_SIZE 1 +#define MACB_DRFCS_OFFSET 17 +#define MACB_DRFCS_SIZE 1 +#define MACB_EFRHD_OFFSET 18 +#define MACB_EFRHD_SIZE 1 +#define MACB_IRXFCS_OFFSET 19 +#define MACB_IRXFCS_SIZE 1 + +/* Bitfields in NSR */ +#define MACB_NSR_LINK_OFFSET 0 +#define MACB_NSR_LINK_SIZE 1 +#define MACB_MDIO_OFFSET 1 +#define MACB_MDIO_SIZE 1 +#define MACB_IDLE_OFFSET 2 +#define MACB_IDLE_SIZE 1 + +/* Bitfields in TSR */ +#define MACB_UBR_OFFSET 0 +#define MACB_UBR_SIZE 1 +#define MACB_COL_OFFSET 1 +#define MACB_COL_SIZE 1 +#define MACB_TSR_RLE_OFFSET 2 +#define MACB_TSR_RLE_SIZE 1 +#define MACB_TGO_OFFSET 3 +#define MACB_TGO_SIZE 1 +#define MACB_BEX_OFFSET 4 +#define MACB_BEX_SIZE 1 +#define MACB_COMP_OFFSET 5 +#define MACB_COMP_SIZE 1 +#define MACB_UND_OFFSET 6 +#define MACB_UND_SIZE 1 + +/* Bitfields in RSR */ +#define MACB_BNA_OFFSET 0 +#define MACB_BNA_SIZE 1 +#define MACB_REC_OFFSET 1 +#define MACB_REC_SIZE 1 +#define MACB_OVR_OFFSET 2 +#define MACB_OVR_SIZE 1 + +/* Bitfields in ISR/IER/IDR/IMR */ +#define MACB_MFD_OFFSET 0 +#define MACB_MFD_SIZE 1 +#define MACB_RCOMP_OFFSET 1 +#define MACB_RCOMP_SIZE 1 +#define MACB_RXUBR_OFFSET 2 +#define MACB_RXUBR_SIZE 1 +#define MACB_TXUBR_OFFSET 3 +#define MACB_TXUBR_SIZE 1 +#define MACB_ISR_TUND_OFFSET 4 +#define MACB_ISR_TUND_SIZE 1 +#define MACB_ISR_RLE_OFFSET 5 +#define MACB_ISR_RLE_SIZE 1 +#define MACB_TXERR_OFFSET 6 +#define MACB_TXERR_SIZE 1 +#define MACB_TCOMP_OFFSET 7 +#define MACB_TCOMP_SIZE 1 +#define MACB_ISR_LINK_OFFSET 9 +#define MACB_ISR_LINK_SIZE 1 +#define MACB_ISR_ROVR_OFFSET 10 +#define MACB_ISR_ROVR_SIZE 1 +#define MACB_HRESP_OFFSET 11 +#define MACB_HRESP_SIZE 1 +#define MACB_PFR_OFFSET 12 +#define MACB_PFR_SIZE 1 +#define MACB_PTZ_OFFSET 13 +#define MACB_PTZ_SIZE 1 + +/* Bitfields in MAN */ +#define MACB_DATA_OFFSET 0 +#define MACB_DATA_SIZE 16 +#define MACB_CODE_OFFSET 16 +#define MACB_CODE_SIZE 2 +#define MACB_REGA_OFFSET 18 +#define MACB_REGA_SIZE 5 +#define MACB_PHYA_OFFSET 23 +#define MACB_PHYA_SIZE 5 +#define MACB_RW_OFFSET 28 +#define MACB_RW_SIZE 2 +#define MACB_SOF_OFFSET 30 +#define MACB_SOF_SIZE 2 + +/* Bitfields in USRIO (AVR32) */ +#define MACB_MII_OFFSET 0 +#define MACB_MII_SIZE 1 +#define MACB_EAM_OFFSET 1 +#define MACB_EAM_SIZE 1 +#define MACB_TX_PAUSE_OFFSET 2 +#define MACB_TX_PAUSE_SIZE 1 +#define MACB_TX_PAUSE_ZERO_OFFSET 3 +#define MACB_TX_PAUSE_ZERO_SIZE 1 + +/* Bitfields in USRIO (AT91) */ +#define MACB_RMII_OFFSET 0 +#define MACB_RMII_SIZE 1 +#define MACB_CLKEN_OFFSET 1 +#define MACB_CLKEN_SIZE 1 + +/* Bitfields in WOL */ +#define MACB_IP_OFFSET 0 +#define MACB_IP_SIZE 16 +#define MACB_MAG_OFFSET 16 +#define MACB_MAG_SIZE 1 +#define MACB_ARP_OFFSET 17 +#define MACB_ARP_SIZE 1 +#define MACB_SA1_OFFSET 18 +#define MACB_SA1_SIZE 1 +#define MACB_WOL_MTI_OFFSET 19 +#define MACB_WOL_MTI_SIZE 1 + +/* Constants for CLK */ +#define MACB_CLK_DIV8 0 +#define MACB_CLK_DIV16 1 +#define MACB_CLK_DIV32 2 +#define MACB_CLK_DIV64 3 + +/* Constants for MAN register */ +#define MACB_MAN_SOF 1 +#define MACB_MAN_WRITE 1 +#define MACB_MAN_READ 2 +#define MACB_MAN_CODE 2 + +/* Bit manipulation macros */ +#define MACB_BIT(name) \ + (1 << MACB_##name##_OFFSET) +#define MACB_BF(name,value) \ + (((value) & ((1 << MACB_##name##_SIZE) - 1)) \ + << MACB_##name##_OFFSET) +#define MACB_BFEXT(name,value)\ + (((value) >> MACB_##name##_OFFSET) \ + & ((1 << MACB_##name##_SIZE) - 1)) +#define MACB_BFINS(name,value,old) \ + (((old) & ~(((1 << MACB_##name##_SIZE) - 1) \ + << MACB_##name##_OFFSET)) \ + | MACB_BF(name,value)) + +/* Register access macros */ +#define macb_readl(port,reg) \ + readl((port)->regs + MACB_##reg) +#define macb_writel(port,reg,value) \ + writel((value), (port)->regs + MACB_##reg) + +struct dma_desc { + rt_uint32_t addr; + rt_uint32_t ctrl; +}; + +/* DMA descriptor bitfields */ +#define MACB_RX_USED_OFFSET 0 +#define MACB_RX_USED_SIZE 1 +#define MACB_RX_WRAP_OFFSET 1 +#define MACB_RX_WRAP_SIZE 1 +#define MACB_RX_WADDR_OFFSET 2 +#define MACB_RX_WADDR_SIZE 30 + +#define MACB_RX_FRMLEN_OFFSET 0 +#define MACB_RX_FRMLEN_SIZE 12 +#define MACB_RX_OFFSET_OFFSET 12 +#define MACB_RX_OFFSET_SIZE 2 +#define MACB_RX_SOF_OFFSET 14 +#define MACB_RX_SOF_SIZE 1 +#define MACB_RX_EOF_OFFSET 15 +#define MACB_RX_EOF_SIZE 1 +#define MACB_RX_CFI_OFFSET 16 +#define MACB_RX_CFI_SIZE 1 +#define MACB_RX_VLAN_PRI_OFFSET 17 +#define MACB_RX_VLAN_PRI_SIZE 3 +#define MACB_RX_PRI_TAG_OFFSET 20 +#define MACB_RX_PRI_TAG_SIZE 1 +#define MACB_RX_VLAN_TAG_OFFSET 21 +#define MACB_RX_VLAN_TAG_SIZE 1 +#define MACB_RX_TYPEID_MATCH_OFFSET 22 +#define MACB_RX_TYPEID_MATCH_SIZE 1 +#define MACB_RX_SA4_MATCH_OFFSET 23 +#define MACB_RX_SA4_MATCH_SIZE 1 +#define MACB_RX_SA3_MATCH_OFFSET 24 +#define MACB_RX_SA3_MATCH_SIZE 1 +#define MACB_RX_SA2_MATCH_OFFSET 25 +#define MACB_RX_SA2_MATCH_SIZE 1 +#define MACB_RX_SA1_MATCH_OFFSET 26 +#define MACB_RX_SA1_MATCH_SIZE 1 +#define MACB_RX_EXT_MATCH_OFFSET 28 +#define MACB_RX_EXT_MATCH_SIZE 1 +#define MACB_RX_UHASH_MATCH_OFFSET 29 +#define MACB_RX_UHASH_MATCH_SIZE 1 +#define MACB_RX_MHASH_MATCH_OFFSET 30 +#define MACB_RX_MHASH_MATCH_SIZE 1 +#define MACB_RX_BROADCAST_OFFSET 31 +#define MACB_RX_BROADCAST_SIZE 1 + +#define MACB_TX_FRMLEN_OFFSET 0 +#define MACB_TX_FRMLEN_SIZE 11 +#define MACB_TX_LAST_OFFSET 15 +#define MACB_TX_LAST_SIZE 1 +#define MACB_TX_NOCRC_OFFSET 16 +#define MACB_TX_NOCRC_SIZE 1 +#define MACB_TX_BUF_EXHAUSTED_OFFSET 27 +#define MACB_TX_BUF_EXHAUSTED_SIZE 1 +#define MACB_TX_UNDERRUN_OFFSET 28 +#define MACB_TX_UNDERRUN_SIZE 1 +#define MACB_TX_ERROR_OFFSET 29 +#define MACB_TX_ERROR_SIZE 1 +#define MACB_TX_WRAP_OFFSET 30 +#define MACB_TX_WRAP_SIZE 1 +#define MACB_TX_USED_OFFSET 31 +#define MACB_TX_USED_SIZE 1 + +extern int rt_hw_macb_init(); + +#endif /* _MACB_H */ + diff --git a/bsp/at91sam9g45/drivers/mii.h b/bsp/at91sam9g45/drivers/mii.h new file mode 100644 index 0000000000..2f6dd18e71 --- /dev/null +++ b/bsp/at91sam9g45/drivers/mii.h @@ -0,0 +1,191 @@ +/* + * File : mii.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-03-18 weety first version + */ + +#ifndef __MII_H__ +#define __MII_H__ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ +#define ADVERTISE_RESV 0x1000 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ +#define LPA_RESV 0x1000 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ +#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + +/* 1000BASE-T Control register */ +#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ + +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ +#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ +#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ + +/* Flow control flags */ +#define FLOW_CTRL_TX 0x01 +#define FLOW_CTRL_RX 0x02 + +/** + * mii_nway_result + * @negotiated: value of MII ANAR and'd with ANLPAR + * + * Given a set of MII abilities, check each bit and returns the + * currently supported media, in the priority order defined by + * IEEE 802.3u. We use LPA_xxx constants but note this is not the + * value of LPA solely, as described above. + * + * The one exception to IEEE 802.3u is that 100baseT4 is placed + * between 100T-full and 100T-half. If your phy does not support + * 100T4 this is fine. If your phy places 100T4 elsewhere in the + * priority order, you will need to roll your own function. + */ +rt_inline unsigned int mii_nway_result (unsigned int negotiated) +{ + unsigned int ret; + + if (negotiated & LPA_100FULL) + ret = LPA_100FULL; + else if (negotiated & LPA_100BASE4) + ret = LPA_100BASE4; + else if (negotiated & LPA_100HALF) + ret = LPA_100HALF; + else if (negotiated & LPA_10FULL) + ret = LPA_10FULL; + else + ret = LPA_10HALF; + + return ret; +} + + +#endif /* __MII_H__ */ + diff --git a/bsp/at91sam9g45/drivers/usart.c b/bsp/at91sam9g45/drivers/usart.c new file mode 100644 index 0000000000..d4ba657232 --- /dev/null +++ b/bsp/at91sam9g45/drivers/usart.c @@ -0,0 +1,398 @@ +/* + * File : usart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + * 2013-07-21 weety using serial component + */ + +#include +#include +#include +#include + + +struct at91_uart { + AT91S_USART *port; + int irq; +}; + + +/** + * This function will handle serial port interrupt + */ +void rt_at91_usart_handler(int vector, void *param) +{ + int status; + struct at91_uart *uart; + rt_device_t dev = (rt_device_t)param; + uart = (struct at91_uart *)dev->user_data; + status = uart->port->US_CSR; + if (!(status & uart->port->US_IMR)) /* check actived and enabled interrupt */ + { + return; + } + rt_interrupt_enter(); + rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_RX_IND); + rt_interrupt_leave(); +} + +/** + * UART device in RT-Thread + */ +static rt_err_t at91_usart_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + int div; + int mode = 0; + struct at91_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + uart = (struct at91_uart *)serial->parent.user_data; + + uart->port->US_CR = AT91C_US_RSTTX | AT91C_US_RSTRX | + AT91C_US_RXDIS | AT91C_US_TXDIS; + mode |= AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | + AT91C_US_CHMODE_NORMAL; + switch (cfg->data_bits) + { + case DATA_BITS_8: + mode |= AT91C_US_CHRL_8_BITS; + break; + case DATA_BITS_7: + mode |= AT91C_US_CHRL_7_BITS; + break; + case DATA_BITS_6: + mode |= AT91C_US_CHRL_6_BITS; + break; + case DATA_BITS_5: + mode |= AT91C_US_CHRL_5_BITS; + break; + default: + mode |= AT91C_US_CHRL_8_BITS; + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + mode |= AT91C_US_NBSTOP_2_BIT; + break; + case STOP_BITS_1: + default: + mode |= AT91C_US_NBSTOP_1_BIT; + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + mode |= AT91C_US_PAR_ODD; + break; + case PARITY_EVEN: + mode |= AT91C_US_PAR_EVEN; + break; + case PARITY_NONE: + default: + mode |= AT91C_US_PAR_NONE; + break; + } + + uart->port->US_MR = mode; + /* Assume OVER is cleared and fractional baudrate generator is disabled */ + div = (clk_get_rate(clk_get("mck")) / 16 + cfg->baud_rate/2) / cfg->baud_rate; + uart->port->US_BRGR = div; + uart->port->US_CR = AT91C_US_RXEN | AT91C_US_TXEN; + uart->port->US_IER = AT91C_US_RXRDY; + + return RT_EOK; +} + +static rt_err_t at91_usart_control(struct rt_serial_device *serial, + int cmd, void *arg) +{ + struct at91_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct at91_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + rt_hw_interrupt_mask(uart->irq); + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + rt_hw_interrupt_umask(uart->irq); + break; + } + + return RT_EOK; +} + +static int at91_usart_putc(struct rt_serial_device *serial, char c) +{ + //rt_uint32_t level; + struct at91_uart *uart = serial->parent.user_data; + + while (!(uart->port->US_CSR & AT91C_US_TXRDY)); + uart->port->US_THR = c; + + return 1; +} + +static int at91_usart_getc(struct rt_serial_device *serial) +{ + int result; + struct at91_uart *uart = serial->parent.user_data; + + if (uart->port->US_CSR & AT91C_US_RXRDY) + { + result = uart->port->US_RHR & 0xff; + } + else + { + result = -1; + } + + return result; +} + +static const struct rt_uart_ops at91_usart_ops = +{ + at91_usart_configure, + at91_usart_control, + at91_usart_putc, + at91_usart_getc, +}; + +#if defined(RT_USING_DBGU) +static struct rt_serial_device serial_dbgu; +struct at91_uart dbgu = { + (AT91PS_USART)AT91C_BASE_DBGU, + AT91C_ID_SYS +}; + +#endif + +#if defined(RT_USING_UART0) +static struct rt_serial_device serial0; +struct at91_uart uart0 = { + AT91C_BASE_US0, + AT91C_ID_US0 +}; +#endif + +#if defined(RT_USING_UART1) +static struct rt_serial_device serial1; +struct at91_uart uart1 = { + AT91C_BASE_US1, + AT91C_ID_US1 +}; +#endif + +#if defined(RT_USING_UART2) +static struct rt_serial_device serial2; +struct at91_uart uart2 = { + AT91C_BASE_US2, + AT91C_ID_US2 +}; +#endif + +#if defined(RT_USING_UART3) +static struct rt_serial_device serial3; +struct at91_uart uart3 = { + AT91C_BASE_US3, + AT91C_ID_US3 +}; +#endif + + +void at91_usart_gpio_init(void) +{ +#ifdef RT_USING_DBGU +#define DRXD 12 // DBGU rx as Peripheral A on PB12 +#define DTXD 13 // DBGU tx as Peripheral A on PB13 + AT91C_BASE_PIOB->PIO_IDR, (1<PIO_PPUDR, (1<PIO_ASR, (1<PIO_PDR, (1<PMC_PCER, 1 << AT91C_ID_SYS; +#endif + +#ifdef RT_USING_UART0 +#define RXD0 18 // UART0 rx as Peripheral A on PB18 +#define TXD0 19 // UART0 tx as Peripheral A on PB19 + AT91C_BASE_PMC->PMC_PCER, 1 << AT91C_ID_US0; + AT91C_BASE_PIOB->PIO_IDR, (1<PIO_PPUER, (1<PIO_PPUDR, (1<PIO_ASR, (1<PIO_PDR, (1<PMC_PCER, 1 << AT91C_ID_US1; + AT91C_BASE_PIOB->PIO_IDR, (1<PIO_PPUER, (1<PIO_PPUDR, (1<PIO_ASR, (1<PIO_PDR, (1<PMC_PCER, 1 << AT91C_ID_US2; + AT91C_BASE_PIOB->PIO_IDR, (1<PIO_PPUER, (1<PIO_PPUDR, (1<PIO_ASR, (1<PIO_PDR, (1<PMC_PCER, 1<PIO_IDR, (1<PIO_PPUER, (1<PIO_PPUDR, (1<PIO_ASR, (1<PIO_PDR, (1< R7 +#define AT91C_ISI_RGB_SWAP_ENABLE (0x1 << 14) // (ISI) D0 -> R7 +#define AT91C_ISI_COL_SPACE (0x1 << 15) // (ISI) Color space for the image data +#define AT91C_ISI_COL_SPACE_YCBCR (0x0 << 15) // (ISI) YCbCr +#define AT91C_ISI_COL_SPACE_RGB (0x1 << 15) // (ISI) RGB +#define AT91C_ISI_IM_HSIZE (0x7FF << 16) // (ISI) Horizontal size of the Image sensor [0..2047] +#define AT91C_ISI_YCC_SWAP (0x3 << 28) // (ISI) Ycc swap +#define AT91C_ISI_YCC_SWAP_YCC_DEFAULT (0x0 << 28) // (ISI) Cb(i) Y(i) Cr(i) Y(i+1) +#define AT91C_ISI_YCC_SWAP_YCC_MODE1 (0x1 << 28) // (ISI) Cr(i) Y(i) Cb(i) Y(i+1) +#define AT91C_ISI_YCC_SWAP_YCC_MODE2 (0x2 << 28) // (ISI) Y(i) Cb(i) Y(i+1) Cr(i) +#define AT91C_ISI_YCC_SWAP_YCC_MODE3 (0x3 << 28) // (ISI) Y(i) Cr(i) Y(i+1) Cb(i) +#define AT91C_ISI_RGB_CFG (0x3 << 30) // (ISI) RGB configuration +#define AT91C_ISI_RGB_CFG_RGB_DEFAULT (0x0 << 30) // (ISI) R/G(MSB) G(LSB)/B R/G(MSB) G(LSB)/B +#define AT91C_ISI_RGB_CFG_RGB_MODE1 (0x1 << 30) // (ISI) B/G(MSB) G(LSB)/R B/G(MSB) G(LSB)/R +#define AT91C_ISI_RGB_CFG_RGB_MODE2 (0x2 << 30) // (ISI) G(LSB)/R B/G(MSB) G(LSB)/R B/G(MSB) +#define AT91C_ISI_RGB_CFG_RGB_MODE3 (0x3 << 30) // (ISI) G(LSB)/B R/G(MSB) G(LSB)/B R/G(MSB) +// -------- ISI_PSIZE : (ISI Offset: 0x8) ISI Preview Register -------- +#define AT91C_ISI_PREV_VSIZE (0x3FF << 0) // (ISI) Vertical size for the preview path +#define AT91C_ISI_PREV_HSIZE (0x3FF << 16) // (ISI) Horizontal size for the preview path +// -------- ISI_PDECF : (ISI Offset: 0xc) ISI Preview Decimation Factor Register -------- +#define AT91C_ISI_DEC_FACTOR (0xFF << 0) // (ISI) Decimation factor +// -------- ISI_Y2RSET0 : (ISI Offset: 0x10) Color Space Conversion YCrCb to RGB Register -------- +#define AT91C_ISI_Y2R_C0 (0xFF << 0) // (ISI) Color Space Conversion Matrix Coefficient C0 +#define AT91C_ISI_Y2R_C1 (0xFF << 8) // (ISI) Color Space Conversion Matrix Coefficient C1 +#define AT91C_ISI_Y2R_C2 (0xFF << 16) // (ISI) Color Space Conversion Matrix Coefficient C2 +#define AT91C_ISI_Y2R_C3 (0xFF << 24) // (ISI) Color Space Conversion Matrix Coefficient C3 +// -------- ISI_Y2RSET1 : (ISI Offset: 0x14) ISI Color Space Conversion YCrCb to RGB set 1 Register -------- +#define AT91C_ISI_Y2R_C4 (0x1FF << 0) // (ISI) Color Space Conversion Matrix Coefficient C4 +#define AT91C_ISI_Y2R_YOFF (0x1 << 12) // (ISI) Color Space Conversion Luninance default offset +#define AT91C_ISI_Y2R_YOFF_0 (0x0 << 12) // (ISI) Offset is 0 +#define AT91C_ISI_Y2R_YOFF_128 (0x1 << 12) // (ISI) Offset is 128 +#define AT91C_ISI_Y2R_CROFF (0x1 << 13) // (ISI) Color Space Conversion Red Chrominance default offset +#define AT91C_ISI_Y2R_CROFF_0 (0x0 << 13) // (ISI) Offset is 0 +#define AT91C_ISI_Y2R_CROFF_16 (0x1 << 13) // (ISI) Offset is 16 +#define AT91C_ISI_Y2R_CBOFF (0x1 << 14) // (ISI) Color Space Conversion Blue Chrominance default offset +#define AT91C_ISI_Y2R_CBOFF_0 (0x0 << 14) // (ISI) Offset is 0 +#define AT91C_ISI_Y2R_CBOFF_16 (0x1 << 14) // (ISI) Offset is 16 +// -------- ISI_R2YSET0 : (ISI Offset: 0x18) Color Space Conversion RGB to YCrCb set 0 register -------- +#define AT91C_ISI_R2Y_C0 (0x7F << 0) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C0 +#define AT91C_ISI_R2Y_C1 (0x7F << 8) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C1 +#define AT91C_ISI_R2Y_C2 (0x7F << 16) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C2 +#define AT91C_ISI_R2Y_ROFF (0x1 << 24) // (ISI) Color Space Conversion Red component offset +#define AT91C_ISI_R2Y_ROFF_0 (0x0 << 24) // (ISI) Offset is 0 +#define AT91C_ISI_R2Y_ROFF_16 (0x1 << 24) // (ISI) Offset is 16 +// -------- ISI_R2YSET1 : (ISI Offset: 0x1c) Color Space Conversion RGB to YCrCb set 1 register -------- +#define AT91C_ISI_R2Y_C3 (0x7F << 0) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C3 +#define AT91C_ISI_R2Y_C4 (0x7F << 8) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C4 +#define AT91C_ISI_R2Y_C5 (0x7F << 16) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C5 +#define AT91C_ISI_R2Y_GOFF (0x1 << 24) // (ISI) Color Space Conversion Green component offset +#define AT91C_ISI_R2Y_GOFF_0 (0x0 << 24) // (ISI) Offset is 0 +#define AT91C_ISI_R2Y_GOFF_128 (0x1 << 24) // (ISI) Offset is 128 +// -------- ISI_R2YSET2 : (ISI Offset: 0x20) Color Space Conversion RGB to YCrCb set 2 register -------- +#define AT91C_ISI_R2Y_C6 (0x7F << 0) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C6 +#define AT91C_ISI_R2Y_C7 (0x7F << 8) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C7 +#define AT91C_ISI_R2Y_C8 (0x7F << 16) // (ISI) Color Space Conversion RGB to YCrCb Matrix coefficient C8 +#define AT91C_ISI_R2Y_BOFF (0x1 << 24) // (ISI) Color Space Conversion Blue component offset +#define AT91C_ISI_R2Y_BOFF_0 (0x0 << 24) // (ISI) Offset is 0 +#define AT91C_ISI_R2Y_BOFF_128 (0x1 << 24) // (ISI) Offset is 128 +// -------- ISI_CTRL : (ISI Offset: 0x24) ISI Control Register -------- +#define AT91C_ISI_EN (0x1 << 0) // (ISI) Image Sensor Interface Enable Request +#define AT91C_ISI_EN_0 (0x0) // (ISI) No effect +#define AT91C_ISI_EN_1 (0x1) // (ISI) Enable the module and the capture +#define AT91C_ISI_DIS (0x1 << 1) // (ISI) Image Sensor Interface Disable Request +#define AT91C_ISI_DIS_0 (0x0 << 1) // (ISI) No effect +#define AT91C_ISI_DIS_1 (0x1 << 1) // (ISI) Disable the module and the capture +#define AT91C_ISI_SRST (0x1 << 2) // (ISI) Software Reset Request +#define AT91C_ISI_SRST_0 (0x0 << 2) // (ISI) No effect +#define AT91C_ISI_SRST_1 (0x1 << 2) // (ISI) Reset the module +#define AT91C_ISI_CDC (0x1 << 8) // (ISI) Codec Request +#define AT91C_ISI_CDC_0 (0x0 << 8) // (ISI) No effect +#define AT91C_ISI_CDC_1 (0x1 << 8) // (ISI) Enable the Codec +// -------- ISI_SR : (ISI Offset: 0x28) ISI Status Register -------- +#define AT91C_ISI_VSYNC (0x1 << 10) // (ISI) Vertical Synchronization +#define AT91C_ISI_VSYNC_0 (0x0 << 10) // (ISI) No effect +#define AT91C_ISI_VSYNC_1 (0x1 << 10) // (ISI) Indicates that a Vertical Synchronization has been detected since last read +#define AT91C_ISI_PXFR_DONE (0x1 << 16) // (ISI) Preview DMA transfer terminated +#define AT91C_ISI_PXFR_DONE_0 (0x0 << 16) // (ISI) No effect +#define AT91C_ISI_PXFR_DONE_1 (0x1 << 16) // (ISI) Indicates that DATA transfer on preview channel has completed since last read +#define AT91C_ISI_CXFR_DONE (0x1 << 17) // (ISI) Codec DMA transfer terminated +#define AT91C_ISI_CXFR_DONE_0 (0x0 << 17) // (ISI) No effect +#define AT91C_ISI_CXFR_DONE_1 (0x1 << 17) // (ISI) Indicates that DATA transfer on preview channel has completed since last read +#define AT91C_ISI_SIP (0x1 << 19) // (ISI) Synchronization In Progress +#define AT91C_ISI_SIP_0 (0x0 << 19) // (ISI) No effect +#define AT91C_ISI_SIP_1 (0x1 << 19) // (ISI) Indicates that Synchronization is in progress +#define AT91C_ISI_P_OVR (0x1 << 24) // (ISI) Fifo Preview Overflow +#define AT91C_ISI_P_OVR_0 (0x0 << 24) // (ISI) No error +#define AT91C_ISI_P_OVR_1 (0x1 << 24) // (ISI) An overrun condition has occurred in input FIFO on the preview path +#define AT91C_ISI_C_OVR (0x1 << 25) // (ISI) Fifo Codec Overflow +#define AT91C_ISI_C_OVR_0 (0x0 << 25) // (ISI) No error +#define AT91C_ISI_C_OVR_1 (0x1 << 25) // (ISI) An overrun condition has occurred in input FIFO on the codec path +#define AT91C_ISI_CRC_ERR (0x1 << 26) // (ISI) CRC synchronisation error +#define AT91C_ISI_CRC_ERR_0 (0x0 << 26) // (ISI) No error +#define AT91C_ISI_CRC_ERR_1 (0x1 << 26) // (ISI) CRC_SYNC is enabled in the control register and an error has been detected and not corrected. The frame is discarded and the ISI waits for a new one. +#define AT91C_ISI_FR_OVR (0x1 << 27) // (ISI) Frame rate overun +#define AT91C_ISI_FR_OVR_0 (0x0 << 27) // (ISI) No error +#define AT91C_ISI_FR_OVR_1 (0x1 << 27) // (ISI) Frame overrun, the current frame is being skipped because a vsync signal has been detected while flushing FIFOs. +// -------- ISI_IER : (ISI Offset: 0x2c) ISI Interrupt Enable Register -------- +// -------- ISI_IDR : (ISI Offset: 0x30) ISI Interrupt Disable Register -------- +// -------- ISI_IMR : (ISI Offset: 0x34) ISI Interrupt Mask Register -------- +// -------- ISI_DMACHER : (ISI Offset: 0x38) DMA Channel Enable Register -------- +#define AT91C_ISI_P_CH_EN (0x1 << 0) // (ISI) Preview Channel Enable +#define AT91C_ISI_P_CH_EN_0 (0x0) // (ISI) No effect +#define AT91C_ISI_P_CH_EN_1 (0x1) // (ISI) Enable the Preview Channel +#define AT91C_ISI_C_CH_EN (0x1 << 1) // (ISI) Codec Channel Enable +#define AT91C_ISI_C_CH_EN_0 (0x0 << 1) // (ISI) No effect +#define AT91C_ISI_C_CH_EN_1 (0x1 << 1) // (ISI) Enable the Codec Channel +// -------- ISI_DMACHDR : (ISI Offset: 0x3c) DMA Channel Enable Register -------- +#define AT91C_ISI_P_CH_DIS (0x1 << 0) // (ISI) Preview Channel Disable +#define AT91C_ISI_P_CH_DIS_0 (0x0) // (ISI) No effect +#define AT91C_ISI_P_CH_DIS_1 (0x1) // (ISI) Disable the Preview Channel +#define AT91C_ISI_C_CH_DIS (0x1 << 1) // (ISI) Codec Channel Disable +#define AT91C_ISI_C_CH_DIS_0 (0x0 << 1) // (ISI) No effect +#define AT91C_ISI_C_CH_DIS_1 (0x1 << 1) // (ISI) Disable the Codec Channel +// -------- ISI_DMACHSR : (ISI Offset: 0x40) DMA Channel Status Register -------- +#define AT91C_ISI_P_CH_S (0x1 << 0) // (ISI) Preview Channel Disable +#define AT91C_ISI_P_CH_S_0 (0x0) // (ISI) Preview Channel is disabled +#define AT91C_ISI_P_CH_S_1 (0x1) // (ISI) Preview Channel is enabled +#define AT91C_ISI_C_CH_S (0x1 << 1) // (ISI) Codec Channel Disable +#define AT91C_ISI_C_CH_S_0 (0x0 << 1) // (ISI) Codec Channel is disabled +#define AT91C_ISI_C_CH_S_1 (0x1 << 1) // (ISI) Codec Channel is enabled +// -------- ISI_DMAPCTRL : (ISI Offset: 0x48) DMA Preview Control Register -------- +#define AT91C_ISI_P_FETCH (0x1 << 0) // (ISI) Preview Descriptor Fetch Control Field +#define AT91C_ISI_P_FETCH_DISABLE (0x0) // (ISI) Preview Channel Fetch Operation is disabled +#define AT91C_ISI_P_FETCH_ENABLE (0x1) // (ISI) Preview Channel Fetch Operation is enabled +#define AT91C_ISI_P_DONE (0x1 << 1) // (ISI) Preview Transfer Done Flag +#define AT91C_ISI_P_DONE_0 (0x0 << 1) // (ISI) Preview Transfer has not been performed +#define AT91C_ISI_P_DONE_1 (0x1 << 1) // (ISI) Preview Transfer has completed +// -------- ISI_DMACCTRL : (ISI Offset: 0x54) DMA Codec Control Register -------- +#define AT91C_ISI_C_FETCH (0x1 << 0) // (ISI) Codec Descriptor Fetch Control Field +#define AT91C_ISI_C_FETCH_DISABLE (0x0) // (ISI) Codec Channel Fetch Operation is disabled +#define AT91C_ISI_C_FETCH_ENABLE (0x1) // (ISI) Codec Channel Fetch Operation is enabled +#define AT91C_ISI_C_DONE (0x1 << 1) // (ISI) Codec Transfer Done Flag +#define AT91C_ISI_C_DONE_0 (0x0 << 1) // (ISI) Codec Transfer has not been performed +#define AT91C_ISI_C_DONE_1 (0x1 << 1) // (ISI) Codec Transfer has completed +// -------- ISI_WPCR : (ISI Offset: 0xe4) Write Protection Control Register -------- +#define AT91C_ISI_WP_EN (0x1 << 0) // (ISI) Write Protection Enable +#define AT91C_ISI_WP_EN_DISABLE (0x0) // (ISI) Write Operation is disabled (if WP_KEY corresponds) +#define AT91C_ISI_WP_EN_ENABLE (0x1) // (ISI) Write Operation is enabled (if WP_KEY corresponds) +#define AT91C_ISI_WP_KEY (0xFFFFFF << 8) // (ISI) Write Protection Key +// -------- ISI_WPSR : (ISI Offset: 0xe8) Write Protection Status Register -------- +#define AT91C_ISI_WP_VS (0xF << 0) // (ISI) Write Protection Violation Status +#define AT91C_ISI_WP_VS_NO_VIOLATION (0x0) // (ISI) No Write Protection Violation detected since last read +#define AT91C_ISI_WP_VS_ON_WRITE (0x1) // (ISI) Write Protection Violation detected since last read +#define AT91C_ISI_WP_VS_ON_RESET (0x2) // (ISI) Software Reset Violation detected since last read +#define AT91C_ISI_WP_VS_ON_BOTH (0x3) // (ISI) Write Protection and Software Reset Violation detected since last read +#define AT91C_ISI_WP_VSRC (0xF << 8) // (ISI) Write Protection Violation Source +#define AT91C_ISI_WP_VSRC_NO_VIOLATION (0x0 << 8) // (ISI) No Write Protection Violation detected since last read +#define AT91C_ISI_WP_VSRC_ISI_CFG1 (0x1 << 8) // (ISI) Write Protection Violation detected on ISI_CFG1 since last read +#define AT91C_ISI_WP_VSRC_ISI_CFG2 (0x2 << 8) // (ISI) Write Protection Violation detected on ISI_CFG2 since last read +#define AT91C_ISI_WP_VSRC_ISI_PSIZE (0x3 << 8) // (ISI) Write Protection Violation detected on ISI_PSIZE since last read +#define AT91C_ISI_WP_VSRC_ISI_PDECF (0x4 << 8) // (ISI) Write Protection Violation detected on ISI_PDECF since last read +#define AT91C_ISI_WP_VSRC_ISI_Y2RSET0 (0x5 << 8) // (ISI) Write Protection Violation detected on ISI_Y2RSET0 since last read +#define AT91C_ISI_WP_VSRC_ISI_Y2RSET1 (0x6 << 8) // (ISI) Write Protection Violation detected on ISI_Y2RSET1 since last read +#define AT91C_ISI_WP_VSRC_ISI_R2YSET0 (0x7 << 8) // (ISI) Write Protection Violation detected on ISI_R2YSET0 since last read +#define AT91C_ISI_WP_VSRC_ISI_R2YSET1 (0x8 << 8) // (ISI) Write Protection Violation detected on ISI_R2YSET1 since last read +#define AT91C_ISI_WP_VSRC_ISI_R2YSET2 (0x9 << 8) // (ISI) Write Protection Violation detected on ISI_R2YSET2 since last read + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR USB Host Interface +// ***************************************************************************** +#ifndef __ASSEMBLY__ +typedef struct _AT91S_UHPHS_OHCI { + AT91C_REG UHPHS_OHCI_HcRevision; // Revision + AT91C_REG UHPHS_OHCI_HcControl; // Operating modes for the Host Controller + AT91C_REG UHPHS_OHCI_HcCommandStatus; // Command & status Register + AT91C_REG UHPHS_OHCI_HcInterruptStatus; // Interrupt Status Register + AT91C_REG UHPHS_OHCI_HcInterruptEnable; // Interrupt Enable Register + AT91C_REG UHPHS_OHCI_HcInterruptDisable; // Interrupt Disable Register + AT91C_REG UHPHS_OHCI_HcHCCA; // Pointer to the Host Controller Communication Area + AT91C_REG UHPHS_OHCI_HcPeriodCurrentED; // Current Isochronous or Interrupt Endpoint Descriptor + AT91C_REG UHPHS_OHCI_HcControlHeadED; // First Endpoint Descriptor of the Control list + AT91C_REG UHPHS_OHCI_HcControlCurrentED; // Endpoint Control and Status Register + AT91C_REG UHPHS_OHCI_HcBulkHeadED; // First endpoint register of the Bulk list + AT91C_REG UHPHS_OHCI_HcBulkCurrentED; // Current endpoint of the Bulk list + AT91C_REG UHPHS_OHCI_HcBulkDoneHead; // Last completed transfer descriptor + AT91C_REG UHPHS_OHCI_HcFmInterval; // Bit time between 2 consecutive SOFs + AT91C_REG UHPHS_OHCI_HcFmRemaining; // Bit time remaining in the current Frame + AT91C_REG UHPHS_OHCI_HcFmNumber; // Frame number + AT91C_REG UHPHS_OHCI_HcPeriodicStart; // Periodic Start + AT91C_REG UHPHS_OHCI_HcLSThreshold; // LS Threshold + AT91C_REG UHPHS_OHCI_HcRhDescriptorA; // Root Hub characteristics A + AT91C_REG UHPHS_OHCI_HcRhDescriptorB; // Root Hub characteristics B + AT91C_REG UHPHS_OHCI_HcRhStatus; // Root Hub Status register + AT91C_REG UHPHS_OHCI_HcRhPortStatus[2]; // Root Hub Port Status Register +} AT91S_UHPHS_OHCI, *AT91PS_UHPHS_OHCI; +#else +#define HcRevision (AT91C_CAST(AT91C_REG *) 0x00000000) // (HcRevision) Revision +#define HcControl (AT91C_CAST(AT91C_REG *) 0x00000004) // (HcControl) Operating modes for the Host Controller +#define HcCommandStatus (AT91C_CAST(AT91C_REG *) 0x00000008) // (HcCommandStatus) Command & status Register +#define HcInterruptStatus (AT91C_CAST(AT91C_REG *) 0x0000000C) // (HcInterruptStatus) Interrupt Status Register +#define HcInterruptEnable (AT91C_CAST(AT91C_REG *) 0x00000010) // (HcInterruptEnable) Interrupt Enable Register +#define HcInterruptDisable (AT91C_CAST(AT91C_REG *) 0x00000014) // (HcInterruptDisable) Interrupt Disable Register +#define HcHCCA (AT91C_CAST(AT91C_REG *) 0x00000018) // (HcHCCA) Pointer to the Host Controller Communication Area +#define HcPeriodCurrentED (AT91C_CAST(AT91C_REG *) 0x0000001C) // (HcPeriodCurrentED) Current Isochronous or Interrupt Endpoint Descriptor +#define HcControlHeadED (AT91C_CAST(AT91C_REG *) 0x00000020) // (HcControlHeadED) First Endpoint Descriptor of the Control list +#define HcControlCurrentED (AT91C_CAST(AT91C_REG *) 0x00000024) // (HcControlCurrentED) Endpoint Control and Status Register +#define HcBulkHeadED (AT91C_CAST(AT91C_REG *) 0x00000028) // (HcBulkHeadED) First endpoint register of the Bulk list +#define HcBulkCurrentED (AT91C_CAST(AT91C_REG *) 0x0000002C) // (HcBulkCurrentED) Current endpoint of the Bulk list +#define HcBulkDoneHead (AT91C_CAST(AT91C_REG *) 0x00000030) // (HcBulkDoneHead) Last completed transfer descriptor +#define HcFmInterval (AT91C_CAST(AT91C_REG *) 0x00000034) // (HcFmInterval) Bit time between 2 consecutive SOFs +#define HcFmRemaining (AT91C_CAST(AT91C_REG *) 0x00000038) // (HcFmRemaining) Bit time remaining in the current Frame +#define HcFmNumber (AT91C_CAST(AT91C_REG *) 0x0000003C) // (HcFmNumber) Frame number +#define HcPeriodicStart (AT91C_CAST(AT91C_REG *) 0x00000040) // (HcPeriodicStart) Periodic Start +#define HcLSThreshold (AT91C_CAST(AT91C_REG *) 0x00000044) // (HcLSThreshold) LS Threshold +#define HcRhDescriptorA (AT91C_CAST(AT91C_REG *) 0x00000048) // (HcRhDescriptorA) Root Hub characteristics A +#define HcRhDescriptorB (AT91C_CAST(AT91C_REG *) 0x0000004C) // (HcRhDescriptorB) Root Hub characteristics B +#define HcRhStatus (AT91C_CAST(AT91C_REG *) 0x00000050) // (HcRhStatus) Root Hub Status register +#define HcRhPortStatus (AT91C_CAST(AT91C_REG *) 0x00000054) // (HcRhPortStatus) Root Hub Port Status Register + +#endif + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR USB Host Interface +// ***************************************************************************** +#ifndef __ASSEMBLY__ +typedef struct _AT91S_UHPHS_EHCI { + AT91C_REG UHPHS_EHCI_VERSION; // + AT91C_REG UHPHS_EHCI_HCSPARAMS; // + AT91C_REG UHPHS_EHCI_HCCPARAMS; // + AT91C_REG UHPHS_EHCI_HCSPPORTROUTE; // + AT91C_REG UHPHS_EHCI_USBCMD; // + AT91C_REG UHPHS_EHCI_USBSTS; // + AT91C_REG UHPHS_EHCI_USBINTR; // + AT91C_REG UHPHS_EHCI_FRINDEX; // + AT91C_REG UHPHS_EHCI_CTRLDSSEGMENT; // + AT91C_REG UHPHS_EHCI_PERIODICLISTBASE; // + AT91C_REG UHPHS_EHCI_ASYNCLISTADDR; // + AT91C_REG Reserved0[9]; // + AT91C_REG UHPHS_EHCI_CONFIGFLAG; // + AT91C_REG UHPHS_EHCI_PORTSC[2]; // + AT91C_REG Reserved1[13]; // + AT91C_REG UHPHS_EHCI_INSNREG00; // + AT91C_REG UHPHS_EHCI_INSNREG01; // + AT91C_REG UHPHS_EHCI_INSNREG02; // + AT91C_REG UHPHS_EHCI_INSNREG03; // + AT91C_REG UHPHS_EHCI_INSNREG04; // + AT91C_REG UHPHS_EHCI_INSNREG05; // +} AT91S_UHPHS_EHCI, *AT91PS_UHPHS_EHCI; +#else +#define VERSION (AT91C_CAST(AT91C_REG *) 0x00000000) // (VERSION) +#define HCSPARAMS (AT91C_CAST(AT91C_REG *) 0x00000004) // (HCSPARAMS) +#define HCCPARAMS (AT91C_CAST(AT91C_REG *) 0x00000008) // (HCCPARAMS) +#define HCSPPORTROUTE (AT91C_CAST(AT91C_REG *) 0x0000000C) // (HCSPPORTROUTE) +#define USBCMD (AT91C_CAST(AT91C_REG *) 0x00000010) // (USBCMD) +#define USBSTS (AT91C_CAST(AT91C_REG *) 0x00000014) // (USBSTS) +#define USBINTR (AT91C_CAST(AT91C_REG *) 0x00000018) // (USBINTR) +#define FRINDEX (AT91C_CAST(AT91C_REG *) 0x0000001C) // (FRINDEX) +#define CTRLDSSEGMENT (AT91C_CAST(AT91C_REG *) 0x00000020) // (CTRLDSSEGMENT) +#define PERIODICLISTBASE (AT91C_CAST(AT91C_REG *) 0x00000024) // (PERIODICLISTBASE) +#define ASYNCLISTADDR (AT91C_CAST(AT91C_REG *) 0x00000028) // (ASYNCLISTADDR) +#define CONFIGFLAG (AT91C_CAST(AT91C_REG *) 0x00000050) // (CONFIGFLAG) +#define PORTSC (AT91C_CAST(AT91C_REG *) 0x00000054) // (PORTSC) +#define INSNREG00 (AT91C_CAST(AT91C_REG *) 0x00000090) // (INSNREG00) +#define INSNREG01 (AT91C_CAST(AT91C_REG *) 0x00000094) // (INSNREG01) +#define INSNREG02 (AT91C_CAST(AT91C_REG *) 0x00000098) // (INSNREG02) +#define INSNREG03 (AT91C_CAST(AT91C_REG *) 0x0000009C) // (INSNREG03) +#define INSNREG04 (AT91C_CAST(AT91C_REG *) 0x000000A0) // (INSNREG04) +#define INSNREG05 (AT91C_CAST(AT91C_REG *) 0x000000A4) // (INSNREG05) + +#endif +// -------- VERSION : (UHPHS_EHCI Offset: 0x0) -------- +#define AT91C_UHPHS_CAPLENGTH (0xFF << 0) // (UHPHS_EHCI) CapLength : Offset for control registers +#define AT91C_UHPHS_HCIVERSION (0xFF << 16) // (UHPHS_EHCI) Hci Version + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR True Random Generator +// ***************************************************************************** +#ifndef __ASSEMBLY__ +typedef struct _AT91S_TRNG { + AT91C_REG TRNG_CR; // Control Register + AT91C_REG Reserved0[3]; // + AT91C_REG TRNG_IER; // Interrupt Enable Register + AT91C_REG TRNG_IDR; // Interrupt Disable Register + AT91C_REG TRNG_IMR; // Interrupt Mask Register + AT91C_REG TRNG_ISR; // Interrupt Status Register + AT91C_REG Reserved1[12]; // + AT91C_REG TRNG_ODATA; // Output Data Register + AT91C_REG Reserved2[42]; // + AT91C_REG TRNG_VERSION; // TRNG Version Register +} AT91S_TRNG, *AT91PS_TRNG; +#else +#define TRNG_CR (AT91C_CAST(AT91C_REG *) 0x00000000) // (TRNG_CR) Control Register +#define TRNG_IER (AT91C_CAST(AT91C_REG *) 0x00000010) // (TRNG_IER) Interrupt Enable Register +#define TRNG_IDR (AT91C_CAST(AT91C_REG *) 0x00000014) // (TRNG_IDR) Interrupt Disable Register +#define TRNG_IMR (AT91C_CAST(AT91C_REG *) 0x00000018) // (TRNG_IMR) Interrupt Mask Register +#define TRNG_ISR (AT91C_CAST(AT91C_REG *) 0x0000001C) // (TRNG_ISR) Interrupt Status Register +#define TRNG_ODATA (AT91C_CAST(AT91C_REG *) 0x00000050) // (TRNG_ODATA) Output Data Register +#define TRNG_VERSION (AT91C_CAST(AT91C_REG *) 0x000000FC) // (TRNG_VERSION) TRNG Version Register + +#endif +// -------- TRNG_CR : (TRNG Offset: 0x0) Control Register -------- +#define AT91C_TRNG_ENABLE (0x1 << 0) // (TRNG) Enable TRNG +// -------- TRNG_IER : (TRNG Offset: 0x10) Interrupt Enable Register -------- +#define AT91C_TRNG_DATRDY (0x1 << 0) // (TRNG) DATRDY +// -------- TRNG_IDR : (TRNG Offset: 0x14) Interrupt Disable Register -------- +// -------- TRNG_IMR : (TRNG Offset: 0x18) Interrupt Mask Register -------- +// -------- TRNG_ISR : (TRNG Offset: 0x1c) Interrupt Status Register -------- + +// ***************************************************************************** +// REGISTER ADDRESS DEFINITION FOR AT91SAM9G45 +// ***************************************************************************** +// ========== Register definition for SFR peripheral ========== +#define AT91C_SFR_INT (AT91C_CAST(AT91C_REG *) 0xFFF74014) // (SFR) OHCI suspend Interrupt status +#define AT91C_SFR_DDRCFG (AT91C_CAST(AT91C_REG *) 0xFFF74004) // (SFR) DDR2 SSTL18 control +#define AT91C_SFR_UTMICFG (AT91C_CAST(AT91C_REG *) 0xFFF74010) // (SFR) UTMI Software Reset, and OHCI suspend interrupt control +#define AT91C_SFR_EBIDELAY (AT91C_CAST(AT91C_REG *) 0xFFF7400C) // (SFR) EBI DDR controller clock delay +#define AT91C_SFR_DDRDELAY (AT91C_CAST(AT91C_REG *) 0xFFF74008) // (SFR) DDR2 controller clock delay +#define AT91C_SFR_EMA (AT91C_CAST(AT91C_REG *) 0xFFF74000) // (SFR) memory Extra Margin Adjustment control +// ========== Register definition for SYS peripheral ========== +#define AT91C_SYS_SLCKSEL (AT91C_CAST(AT91C_REG *) 0xFFFFFD50) // (SYS) Slow Clock Selection Register +#define AT91C_SYS_GPBR (AT91C_CAST(AT91C_REG *) 0xFFFFFD60) // (SYS) General Purpose Register +// ========== Register definition for EBI peripheral ========== +#define AT91C_EBI_DUMMY (AT91C_CAST(AT91C_REG *) 0xFFFFE200) // (EBI) Dummy register - Do not use +// ========== Register definition for DDR2CP1 peripheral ========== +#define AT91C_DDR2CP1_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFE434) // (DDR2CP1) Pad delay2 Register +#define AT91C_DDR2CP1_T3PR (AT91C_CAST(AT91C_REG *) 0xFFFFE418) // (DDR2CP1) Timing3 Register +#define AT91C_DDR2CP1_RTR (AT91C_CAST(AT91C_REG *) 0xFFFFE404) // (DDR2CP1) Refresh Timer Register +#define AT91C_DDR2CP1_T0PR (AT91C_CAST(AT91C_REG *) 0xFFFFE40C) // (DDR2CP1) Timing0 Register +#define AT91C_DDR2CP1_WPSR (AT91C_CAST(AT91C_REG *) 0xFFFFE4E8) // (DDR2CP1) High Speed Register +#define AT91C_DDR2CP1_DELAY8 (AT91C_CAST(AT91C_REG *) 0xFFFFE44C) // (DDR2CP1) Pad delay8 Register +#define AT91C_DDR2CP1_LPR (AT91C_CAST(AT91C_REG *) 0xFFFFE41C) // (DDR2CP1) Low-power Register +#define AT91C_DDR2CP1_VER (AT91C_CAST(AT91C_REG *) 0xFFFFE428) // (DDR2CP1) DLL Version Register +#define AT91C_DDR2CP1_DELAY7 (AT91C_CAST(AT91C_REG *) 0xFFFFE448) // (DDR2CP1) Pad delay7 Register +#define AT91C_DDR2CP1_CR (AT91C_CAST(AT91C_REG *) 0xFFFFE408) // (DDR2CP1) Configuration Register +#define AT91C_DDR2CP1_WPCR (AT91C_CAST(AT91C_REG *) 0xFFFFE4E4) // (DDR2CP1) High Speed Register +#define AT91C_DDR2CP1_MR (AT91C_CAST(AT91C_REG *) 0xFFFFE400) // (DDR2CP1) Mode Register +#define AT91C_DDR2CP1_DELAY5 (AT91C_CAST(AT91C_REG *) 0xFFFFE440) // (DDR2CP1) Pad delay5 Register +#define AT91C_DDR2CP1_T2PR (AT91C_CAST(AT91C_REG *) 0xFFFFE414) // (DDR2CP1) Timing2 Register +#define AT91C_DDR2CP1_HS (AT91C_CAST(AT91C_REG *) 0xFFFFE42C) // (DDR2CP1) High Speed Register +#define AT91C_DDR2CP1_MDR (AT91C_CAST(AT91C_REG *) 0xFFFFE420) // (DDR2CP1) Memory Device Register +#define AT91C_DDR2CP1_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFE43C) // (DDR2CP1) Pad delay4 Register +#define AT91C_DDR2CP1_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFE430) // (DDR2CP1) Pad delay1 Register +#define AT91C_DDR2CP1_DELAY6 (AT91C_CAST(AT91C_REG *) 0xFFFFE444) // (DDR2CP1) Pad delay6 Register +#define AT91C_DDR2CP1_DLL (AT91C_CAST(AT91C_REG *) 0xFFFFE424) // (DDR2CP1) DLL Information Register +#define AT91C_DDR2CP1_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFE438) // (DDR2CP1) Pad delay3 Register +#define AT91C_DDR2CP1_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFE4FC) // (DDR2CP1) Version Register +#define AT91C_DDR2CP1_T1PR (AT91C_CAST(AT91C_REG *) 0xFFFFE410) // (DDR2CP1) Timing1 Register +// ========== Register definition for DDR2C peripheral ========== +#define AT91C_DDR2C_DELAY8 (AT91C_CAST(AT91C_REG *) 0xFFFFE64C) // (DDR2C) Pad delay8 Register +#define AT91C_DDR2C_VER (AT91C_CAST(AT91C_REG *) 0xFFFFE628) // (DDR2C) DLL Version Register +#define AT91C_DDR2C_RTR (AT91C_CAST(AT91C_REG *) 0xFFFFE604) // (DDR2C) Refresh Timer Register +#define AT91C_DDR2C_T0PR (AT91C_CAST(AT91C_REG *) 0xFFFFE60C) // (DDR2C) Timing0 Register +#define AT91C_DDR2C_DELAY5 (AT91C_CAST(AT91C_REG *) 0xFFFFE640) // (DDR2C) Pad delay5 Register +#define AT91C_DDR2C_LPR (AT91C_CAST(AT91C_REG *) 0xFFFFE61C) // (DDR2C) Low-power Register +#define AT91C_DDR2C_HS (AT91C_CAST(AT91C_REG *) 0xFFFFE62C) // (DDR2C) High Speed Register +#define AT91C_DDR2C_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFE634) // (DDR2C) Pad delay2 Register +#define AT91C_DDR2C_T2PR (AT91C_CAST(AT91C_REG *) 0xFFFFE614) // (DDR2C) Timing2 Register +#define AT91C_DDR2C_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFE630) // (DDR2C) Pad delay1 Register +#define AT91C_DDR2C_T1PR (AT91C_CAST(AT91C_REG *) 0xFFFFE610) // (DDR2C) Timing1 Register +#define AT91C_DDR2C_MDR (AT91C_CAST(AT91C_REG *) 0xFFFFE620) // (DDR2C) Memory Device Register +#define AT91C_DDR2C_DELAY6 (AT91C_CAST(AT91C_REG *) 0xFFFFE644) // (DDR2C) Pad delay6 Register +#define AT91C_DDR2C_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFE6FC) // (DDR2C) Version Register +#define AT91C_DDR2C_MR (AT91C_CAST(AT91C_REG *) 0xFFFFE600) // (DDR2C) Mode Register +#define AT91C_DDR2C_DLL (AT91C_CAST(AT91C_REG *) 0xFFFFE624) // (DDR2C) DLL Information Register +#define AT91C_DDR2C_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFE63C) // (DDR2C) Pad delay4 Register +#define AT91C_DDR2C_WPCR (AT91C_CAST(AT91C_REG *) 0xFFFFE6E4) // (DDR2C) High Speed Register +#define AT91C_DDR2C_CR (AT91C_CAST(AT91C_REG *) 0xFFFFE608) // (DDR2C) Configuration Register +#define AT91C_DDR2C_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFE638) // (DDR2C) Pad delay3 Register +#define AT91C_DDR2C_WPSR (AT91C_CAST(AT91C_REG *) 0xFFFFE6E8) // (DDR2C) High Speed Register +#define AT91C_DDR2C_DELAY7 (AT91C_CAST(AT91C_REG *) 0xFFFFE648) // (DDR2C) Pad delay7 Register +#define AT91C_DDR2C_T3PR (AT91C_CAST(AT91C_REG *) 0xFFFFE618) // (DDR2C) Timing3 Register +// ========== Register definition for SMC peripheral ========== +#define AT91C_SMC_PULSE7 (AT91C_CAST(AT91C_REG *) 0xFFFFE874) // (SMC) Pulse Register for CS 7 +#define AT91C_SMC_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFE8C0) // (SMC) SMC Delay Control Register +#define AT91C_SMC_CYCLE2 (AT91C_CAST(AT91C_REG *) 0xFFFFE828) // (SMC) Cycle Register for CS 2 +#define AT91C_SMC_DELAY5 (AT91C_CAST(AT91C_REG *) 0xFFFFE8D0) // (SMC) SMC Delay Control Register +#define AT91C_SMC_DELAY6 (AT91C_CAST(AT91C_REG *) 0xFFFFE8D4) // (SMC) SMC Delay Control Register +#define AT91C_SMC_PULSE2 (AT91C_CAST(AT91C_REG *) 0xFFFFE824) // (SMC) Pulse Register for CS 2 +#define AT91C_SMC_SETUP6 (AT91C_CAST(AT91C_REG *) 0xFFFFE860) // (SMC) Setup Register for CS 6 +#define AT91C_SMC_SETUP5 (AT91C_CAST(AT91C_REG *) 0xFFFFE850) // (SMC) Setup Register for CS 5 +#define AT91C_SMC_CYCLE6 (AT91C_CAST(AT91C_REG *) 0xFFFFE868) // (SMC) Cycle Register for CS 6 +#define AT91C_SMC_PULSE6 (AT91C_CAST(AT91C_REG *) 0xFFFFE864) // (SMC) Pulse Register for CS 6 +#define AT91C_SMC_CTRL5 (AT91C_CAST(AT91C_REG *) 0xFFFFE85C) // (SMC) Control Register for CS 5 +#define AT91C_SMC_CTRL3 (AT91C_CAST(AT91C_REG *) 0xFFFFE83C) // (SMC) Control Register for CS 3 +#define AT91C_SMC_DELAY7 (AT91C_CAST(AT91C_REG *) 0xFFFFE8D8) // (SMC) SMC Delay Control Register +#define AT91C_SMC_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFE8C8) // (SMC) SMC Delay Control Register +#define AT91C_SMC_CYCLE0 (AT91C_CAST(AT91C_REG *) 0xFFFFE808) // (SMC) Cycle Register for CS 0 +#define AT91C_SMC_SETUP1 (AT91C_CAST(AT91C_REG *) 0xFFFFE810) // (SMC) Setup Register for CS 1 +#define AT91C_SMC_PULSE5 (AT91C_CAST(AT91C_REG *) 0xFFFFE854) // (SMC) Pulse Register for CS 5 +#define AT91C_SMC_SETUP7 (AT91C_CAST(AT91C_REG *) 0xFFFFE870) // (SMC) Setup Register for CS 7 +#define AT91C_SMC_CTRL4 (AT91C_CAST(AT91C_REG *) 0xFFFFE84C) // (SMC) Control Register for CS 4 +#define AT91C_SMC_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFE8C4) // (SMC) SMC Delay Control Register +#define AT91C_SMC_PULSE3 (AT91C_CAST(AT91C_REG *) 0xFFFFE834) // (SMC) Pulse Register for CS 3 +#define AT91C_SMC_CYCLE4 (AT91C_CAST(AT91C_REG *) 0xFFFFE848) // (SMC) Cycle Register for CS 4 +#define AT91C_SMC_CTRL1 (AT91C_CAST(AT91C_REG *) 0xFFFFE81C) // (SMC) Control Register for CS 1 +#define AT91C_SMC_SETUP3 (AT91C_CAST(AT91C_REG *) 0xFFFFE830) // (SMC) Setup Register for CS 3 +#define AT91C_SMC_CTRL0 (AT91C_CAST(AT91C_REG *) 0xFFFFE80C) // (SMC) Control Register for CS 0 +#define AT91C_SMC_CYCLE7 (AT91C_CAST(AT91C_REG *) 0xFFFFE878) // (SMC) Cycle Register for CS 7 +#define AT91C_SMC_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFE8CC) // (SMC) SMC Delay Control Register +#define AT91C_SMC_CYCLE1 (AT91C_CAST(AT91C_REG *) 0xFFFFE818) // (SMC) Cycle Register for CS 1 +#define AT91C_SMC_SETUP2 (AT91C_CAST(AT91C_REG *) 0xFFFFE820) // (SMC) Setup Register for CS 2 +#define AT91C_SMC_PULSE1 (AT91C_CAST(AT91C_REG *) 0xFFFFE814) // (SMC) Pulse Register for CS 1 +#define AT91C_SMC_DELAY8 (AT91C_CAST(AT91C_REG *) 0xFFFFE8DC) // (SMC) SMC Delay Control Register +#define AT91C_SMC_CTRL2 (AT91C_CAST(AT91C_REG *) 0xFFFFE82C) // (SMC) Control Register for CS 2 +#define AT91C_SMC_PULSE4 (AT91C_CAST(AT91C_REG *) 0xFFFFE844) // (SMC) Pulse Register for CS 4 +#define AT91C_SMC_SETUP4 (AT91C_CAST(AT91C_REG *) 0xFFFFE840) // (SMC) Setup Register for CS 4 +#define AT91C_SMC_CYCLE3 (AT91C_CAST(AT91C_REG *) 0xFFFFE838) // (SMC) Cycle Register for CS 3 +#define AT91C_SMC_SETUP0 (AT91C_CAST(AT91C_REG *) 0xFFFFE800) // (SMC) Setup Register for CS 0 +#define AT91C_SMC_CYCLE5 (AT91C_CAST(AT91C_REG *) 0xFFFFE858) // (SMC) Cycle Register for CS 5 +#define AT91C_SMC_PULSE0 (AT91C_CAST(AT91C_REG *) 0xFFFFE804) // (SMC) Pulse Register for CS 0 +#define AT91C_SMC_CTRL6 (AT91C_CAST(AT91C_REG *) 0xFFFFE86C) // (SMC) Control Register for CS 6 +#define AT91C_SMC_CTRL7 (AT91C_CAST(AT91C_REG *) 0xFFFFE87C) // (SMC) Control Register for CS 7 +// ========== Register definition for MATRIX peripheral ========== +#define AT91C_MATRIX_SCFG1 (AT91C_CAST(AT91C_REG *) 0xFFFFEA44) // (MATRIX) Slave Configuration Register 1 : SRAM S1 +#define AT91C_MATRIX_MRCR (AT91C_CAST(AT91C_REG *) 0xFFFFEB00) // (MATRIX) Master Remap Control Register +#define AT91C_MATRIX_PRAS2 (AT91C_CAST(AT91C_REG *) 0xFFFFEA90) // (MATRIX) PRAS2 : SRAM S2 +#define AT91C_MATRIX_PRAS1 (AT91C_CAST(AT91C_REG *) 0xFFFFEA88) // (MATRIX) PRAS1 : SRAM S1 +#define AT91C_MATRIX_PRAS0 (AT91C_CAST(AT91C_REG *) 0xFFFFEA80) // (MATRIX) PRAS0 : SRAM S0 +#define AT91C_MATRIX_MCFG8 (AT91C_CAST(AT91C_REG *) 0xFFFFEA20) // (MATRIX) Master Configuration Register 8 : eMAC +#define AT91C_MATRIX_MCFG2 (AT91C_CAST(AT91C_REG *) 0xFFFFEA08) // (MATRIX) Master Configuration Register 2 : pdc +#define AT91C_MATRIX_EBICSA (AT91C_CAST(AT91C_REG *) 0xFFFFEB28) // (MATRIX) EBI Chip Select Assignment Register +#define AT91C_MATRIX_PRAS4 (AT91C_CAST(AT91C_REG *) 0xFFFFEAA0) // (MATRIX) PRAS4 : ROM + USB Dev + USB EHCI + USB OHCI + LCD + Video Decoder +#define AT91C_MATRIX_MCFG3 (AT91C_CAST(AT91C_REG *) 0xFFFFEA0C) // (MATRIX) Master Configuration Register 3 : USB Host OHCI +#define AT91C_MATRIX_SCFG0 (AT91C_CAST(AT91C_REG *) 0xFFFFEA40) // (MATRIX) Slave Configuration Register 0 : SRAM S0 +#define AT91C_MATRIX_MCFG7 (AT91C_CAST(AT91C_REG *) 0xFFFFEA1C) // (MATRIX) Master Configuration Register 7 : lcdc +#define AT91C_MATRIX_PRAS6 (AT91C_CAST(AT91C_REG *) 0xFFFFEAB0) // (MATRIX) PRAS6 : DDR2 S1 +#define AT91C_MATRIX_SCFG7 (AT91C_CAST(AT91C_REG *) 0xFFFFEA5C) // (MATRIX) Slave Configuration Register 7 : DDR2 S2 +#define AT91C_MATRIX_PRAS7 (AT91C_CAST(AT91C_REG *) 0xFFFFEAB8) // (MATRIX) PRAS7 : DDR2 S2 +#define AT91C_MATRIX_SCFG2 (AT91C_CAST(AT91C_REG *) 0xFFFFEA48) // (MATRIX) Slave Configuration Register 2 : SRAM S2 +#define AT91C_MATRIX_WRPROTST (AT91C_CAST(AT91C_REG *) 0xFFFFEBE8) // (MATRIX) Write Protection Status Register +#define AT91C_MATRIX_PRBS0 (AT91C_CAST(AT91C_REG *) 0xFFFFEA84) // (MATRIX) PRBS0 : SRAM S0 +#define AT91C_MATRIX_PRBS2 (AT91C_CAST(AT91C_REG *) 0xFFFFEA94) // (MATRIX) PRBS2 : SRAM S2 +#define AT91C_MATRIX_MCFG4 (AT91C_CAST(AT91C_REG *) 0xFFFFEA10) // (MATRIX) Master Configuration Register 4 : DMA0 +#define AT91C_MATRIX_SCFG5 (AT91C_CAST(AT91C_REG *) 0xFFFFEA54) // (MATRIX) Slave Configuration Register 5 : DDR2 S0 +#define AT91C_MATRIX_PRBS6 (AT91C_CAST(AT91C_REG *) 0xFFFFEAB4) // (MATRIX) PRBS6 : DDR2 S1 +#define AT91C_MATRIX_MCFG1 (AT91C_CAST(AT91C_REG *) 0xFFFFEA04) // (MATRIX) Master Configuration Register 1 ; ARM-D +#define AT91C_MATRIX_SCFG6 (AT91C_CAST(AT91C_REG *) 0xFFFFEA58) // (MATRIX) Slave Configuration Register 6 : DDR2 S1 +#define AT91C_MATRIX_SCFG4 (AT91C_CAST(AT91C_REG *) 0xFFFFEA50) // (MATRIX) Slave Configuration Register 4 ; ROM + USB Dev + USB EHCI + USB OHCI + LCD + Video Decoder +#define AT91C_MATRIX_PRBS1 (AT91C_CAST(AT91C_REG *) 0xFFFFEA8C) // (MATRIX) PRBS1 : SRAM S1 +#define AT91C_MATRIX_PRBS3 (AT91C_CAST(AT91C_REG *) 0xFFFFEA9C) // (MATRIX) PRBS3 : SRAM S3 +#define AT91C_MATRIX_WRPROTEN (AT91C_CAST(AT91C_REG *) 0xFFFFEBE4) // (MATRIX) Write Protection Control Register +#define AT91C_MATRIX_TCMR (AT91C_CAST(AT91C_REG *) 0xFFFFEB10) // (MATRIX) Bus Matrix TCM Configuration Register +#define AT91C_MATRIX_MCFG0 (AT91C_CAST(AT91C_REG *) 0xFFFFEA00) // (MATRIX) Master Configuration Register 0 : ARM-I +#define AT91C_MATRIX_PRAS5 (AT91C_CAST(AT91C_REG *) 0xFFFFEAA8) // (MATRIX) PRAS5 : DDR2 S0 +#define AT91C_MATRIX_DDRMPR (AT91C_CAST(AT91C_REG *) 0xFFFFEB18) // (MATRIX) DDR Multi-Port Register +#define AT91C_MATRIX_PRBS4 (AT91C_CAST(AT91C_REG *) 0xFFFFEAA4) // (MATRIX) PRBS4 : ROM + USB Dev + USB EHCI + USB OHCI + LCD + Video Decoder +#define AT91C_MATRIX_MCFG6 (AT91C_CAST(AT91C_REG *) 0xFFFFEA18) // (MATRIX) Master Configuration Register 6 : hisi +#define AT91C_MATRIX_PRBS5 (AT91C_CAST(AT91C_REG *) 0xFFFFEAAC) // (MATRIX) PRBS5 : DDR2 S0 +#define AT91C_MATRIX_MCFG9 (AT91C_CAST(AT91C_REG *) 0xFFFFEA24) // (MATRIX) Master Configuration Register 9 : USB Device +#define AT91C_MATRIX_MCFG5 (AT91C_CAST(AT91C_REG *) 0xFFFFEA14) // (MATRIX) Master Configuration Register 5 : DMA1 +#define AT91C_MATRIX_PRBS7 (AT91C_CAST(AT91C_REG *) 0xFFFFEABC) // (MATRIX) PRBS7 : DDR2 S2 +#define AT91C_MATRIX_MCFG10 (AT91C_CAST(AT91C_REG *) 0xFFFFEA28) // (MATRIX) Master Configuration Register 10 : USB Host EHCI +#define AT91C_MATRIX_PRAS3 (AT91C_CAST(AT91C_REG *) 0xFFFFEA98) // (MATRIX) PRAS3 : SRAM S3 +#define AT91C_MATRIX_SCFG3 (AT91C_CAST(AT91C_REG *) 0xFFFFEA4C) // (MATRIX) Slave Configuration Register 3 : SRAM S3 +// ========== Register definition for AIC peripheral ========== +#define AT91C_AIC_IVR (AT91C_CAST(AT91C_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register +#define AT91C_AIC_SMR (AT91C_CAST(AT91C_REG *) 0xFFFFF000) // (AIC) Source Mode Register +#define AT91C_AIC_FVR (AT91C_CAST(AT91C_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register +#define AT91C_AIC_DCR (AT91C_CAST(AT91C_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) +#define AT91C_AIC_EOICR (AT91C_CAST(AT91C_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register +#define AT91C_AIC_SVR (AT91C_CAST(AT91C_REG *) 0xFFFFF080) // (AIC) Source Vector Register +#define AT91C_AIC_FFSR (AT91C_CAST(AT91C_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register +#define AT91C_AIC_ICCR (AT91C_CAST(AT91C_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register +#define AT91C_AIC_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register +#define AT91C_AIC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register +#define AT91C_AIC_IPR (AT91C_CAST(AT91C_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register +#define AT91C_AIC_FFER (AT91C_CAST(AT91C_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register +#define AT91C_AIC_IECR (AT91C_CAST(AT91C_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register +#define AT91C_AIC_ISCR (AT91C_CAST(AT91C_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register +#define AT91C_AIC_FFDR (AT91C_CAST(AT91C_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register +#define AT91C_AIC_CISR (AT91C_CAST(AT91C_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register +#define AT91C_AIC_IDCR (AT91C_CAST(AT91C_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register +#define AT91C_AIC_SPU (AT91C_CAST(AT91C_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register +// ========== Register definition for PDC_DBGU peripheral ========== +#define AT91C_DBGU_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFFEF20) // (PDC_DBGU) PDC Transfer Control Register +#define AT91C_DBGU_RCR (AT91C_CAST(AT91C_REG *) 0xFFFFEF04) // (PDC_DBGU) Receive Counter Register +#define AT91C_DBGU_TCR (AT91C_CAST(AT91C_REG *) 0xFFFFEF0C) // (PDC_DBGU) Transmit Counter Register +#define AT91C_DBGU_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFFEF14) // (PDC_DBGU) Receive Next Counter Register +#define AT91C_DBGU_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFFEF18) // (PDC_DBGU) Transmit Next Pointer Register +#define AT91C_DBGU_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFFEF10) // (PDC_DBGU) Receive Next Pointer Register +#define AT91C_DBGU_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFFEF24) // (PDC_DBGU) PDC Transfer Status Register +#define AT91C_DBGU_RPR (AT91C_CAST(AT91C_REG *) 0xFFFFEF00) // (PDC_DBGU) Receive Pointer Register +#define AT91C_DBGU_TPR (AT91C_CAST(AT91C_REG *) 0xFFFFEF08) // (PDC_DBGU) Transmit Pointer Register +#define AT91C_DBGU_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFFEF1C) // (PDC_DBGU) Transmit Next Counter Register +// ========== Register definition for DBGU peripheral ========== +#define AT91C_DBGU_BRGR (AT91C_CAST(AT91C_REG *) 0xFFFFEE20) // (DBGU) Baud Rate Generator Register +#define AT91C_DBGU_CR (AT91C_CAST(AT91C_REG *) 0xFFFFEE00) // (DBGU) Control Register +#define AT91C_DBGU_THR (AT91C_CAST(AT91C_REG *) 0xFFFFEE1C) // (DBGU) Transmitter Holding Register +#define AT91C_DBGU_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFEE0C) // (DBGU) Interrupt Disable Register +#define AT91C_DBGU_EXID (AT91C_CAST(AT91C_REG *) 0xFFFFEE44) // (DBGU) Chip ID Extension Register +#define AT91C_DBGU_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFEE10) // (DBGU) Interrupt Mask Register +#define AT91C_DBGU_FNTR (AT91C_CAST(AT91C_REG *) 0xFFFFEE48) // (DBGU) Force NTRST Register +#define AT91C_DBGU_IER (AT91C_CAST(AT91C_REG *) 0xFFFFEE08) // (DBGU) Interrupt Enable Register +#define AT91C_DBGU_CSR (AT91C_CAST(AT91C_REG *) 0xFFFFEE14) // (DBGU) Channel Status Register +#define AT91C_DBGU_MR (AT91C_CAST(AT91C_REG *) 0xFFFFEE04) // (DBGU) Mode Register +#define AT91C_DBGU_RHR (AT91C_CAST(AT91C_REG *) 0xFFFFEE18) // (DBGU) Receiver Holding Register +#define AT91C_DBGU_CIDR (AT91C_CAST(AT91C_REG *) 0xFFFFEE40) // (DBGU) Chip ID Register +// ========== Register definition for PIOA peripheral ========== +#define AT91C_PIOA_OWDR (AT91C_CAST(AT91C_REG *) 0xFFFFF2A4) // (PIOA) Output Write Disable Register +#define AT91C_PIOA_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFF2C8) // (PIOA) PIO Delay Control Register +#define AT91C_PIOA_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFF24C) // (PIOA) Interrupt Status Register +#define AT91C_PIOA_PDR (AT91C_CAST(AT91C_REG *) 0xFFFFF204) // (PIOA) PIO Disable Register +#define AT91C_PIOA_OSR (AT91C_CAST(AT91C_REG *) 0xFFFFF218) // (PIOA) Output Status Register +#define AT91C_PIOA_ABSR (AT91C_CAST(AT91C_REG *) 0xFFFFF278) // (PIOA) AB Select Status Register +#define AT91C_PIOA_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFF2C4) // (PIOA) PIO Delay Control Register +#define AT91C_PIOA_PDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF23C) // (PIOA) Pin Data Status Register +#define AT91C_PIOA_BSR (AT91C_CAST(AT91C_REG *) 0xFFFFF274) // (PIOA) Select B Register +#define AT91C_PIOA_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFF2C0) // (PIOA) PIO Delay Control Register +#define AT91C_PIOA_PPUER (AT91C_CAST(AT91C_REG *) 0xFFFFF264) // (PIOA) Pull-up Enable Register +#define AT91C_PIOA_OER (AT91C_CAST(AT91C_REG *) 0xFFFFF210) // (PIOA) Output Enable Register +#define AT91C_PIOA_PER (AT91C_CAST(AT91C_REG *) 0xFFFFF200) // (PIOA) PIO Enable Register +#define AT91C_PIOA_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFF2FC) // (PIOA) PIO Version Register +#define AT91C_PIOA_PPUDR (AT91C_CAST(AT91C_REG *) 0xFFFFF260) // (PIOA) Pull-up Disable Register +#define AT91C_PIOA_ODSR (AT91C_CAST(AT91C_REG *) 0xFFFFF238) // (PIOA) Output Data Status Register +#define AT91C_PIOA_SLEWRATE1 (AT91C_CAST(AT91C_REG *) 0xFFFFF2B0) // (PIOA) PIO Slewrate Control Register +#define AT91C_PIOA_MDDR (AT91C_CAST(AT91C_REG *) 0xFFFFF254) // (PIOA) Multi-driver Disable Register +#define AT91C_PIOA_IFSR (AT91C_CAST(AT91C_REG *) 0xFFFFF228) // (PIOA) Input Filter Status Register +#define AT91C_PIOA_CODR (AT91C_CAST(AT91C_REG *) 0xFFFFF234) // (PIOA) Clear Output Data Register +#define AT91C_PIOA_ASR (AT91C_CAST(AT91C_REG *) 0xFFFFF270) // (PIOA) Select A Register +#define AT91C_PIOA_OWSR (AT91C_CAST(AT91C_REG *) 0xFFFFF2A8) // (PIOA) Output Write Status Register +#define AT91C_PIOA_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFF248) // (PIOA) Interrupt Mask Register +#define AT91C_PIOA_PPUSR (AT91C_CAST(AT91C_REG *) 0xFFFFF268) // (PIOA) Pull-up Status Register +#define AT91C_PIOA_MDER (AT91C_CAST(AT91C_REG *) 0xFFFFF250) // (PIOA) Multi-driver Enable Register +#define AT91C_PIOA_IFDR (AT91C_CAST(AT91C_REG *) 0xFFFFF224) // (PIOA) Input Filter Disable Register +#define AT91C_PIOA_SODR (AT91C_CAST(AT91C_REG *) 0xFFFFF230) // (PIOA) Set Output Data Register +#define AT91C_PIOA_OWER (AT91C_CAST(AT91C_REG *) 0xFFFFF2A0) // (PIOA) Output Write Enable Register +#define AT91C_PIOA_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFF244) // (PIOA) Interrupt Disable Register +#define AT91C_PIOA_IFER (AT91C_CAST(AT91C_REG *) 0xFFFFF220) // (PIOA) Input Filter Enable Register +#define AT91C_PIOA_IER (AT91C_CAST(AT91C_REG *) 0xFFFFF240) // (PIOA) Interrupt Enable Register +#define AT91C_PIOA_ODR (AT91C_CAST(AT91C_REG *) 0xFFFFF214) // (PIOA) Output Disable Registerr +#define AT91C_PIOA_MDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF258) // (PIOA) Multi-driver Status Register +#define AT91C_PIOA_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFF2CC) // (PIOA) PIO Delay Control Register +#define AT91C_PIOA_PSR (AT91C_CAST(AT91C_REG *) 0xFFFFF208) // (PIOA) PIO Status Register +// ========== Register definition for PIOB peripheral ========== +#define AT91C_PIOB_ODR (AT91C_CAST(AT91C_REG *) 0xFFFFF414) // (PIOB) Output Disable Registerr +#define AT91C_PIOB_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFF4CC) // (PIOB) PIO Delay Control Register +#define AT91C_PIOB_SODR (AT91C_CAST(AT91C_REG *) 0xFFFFF430) // (PIOB) Set Output Data Register +#define AT91C_PIOB_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFF44C) // (PIOB) Interrupt Status Register +#define AT91C_PIOB_ABSR (AT91C_CAST(AT91C_REG *) 0xFFFFF478) // (PIOB) AB Select Status Register +#define AT91C_PIOB_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFF448) // (PIOB) Interrupt Mask Register +#define AT91C_PIOB_MDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF458) // (PIOB) Multi-driver Status Register +#define AT91C_PIOB_PPUSR (AT91C_CAST(AT91C_REG *) 0xFFFFF468) // (PIOB) Pull-up Status Register +#define AT91C_PIOB_PDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF43C) // (PIOB) Pin Data Status Register +#define AT91C_PIOB_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFF4C8) // (PIOB) PIO Delay Control Register +#define AT91C_PIOB_MDDR (AT91C_CAST(AT91C_REG *) 0xFFFFF454) // (PIOB) Multi-driver Disable Register +#define AT91C_PIOB_CODR (AT91C_CAST(AT91C_REG *) 0xFFFFF434) // (PIOB) Clear Output Data Register +#define AT91C_PIOB_MDER (AT91C_CAST(AT91C_REG *) 0xFFFFF450) // (PIOB) Multi-driver Enable Register +#define AT91C_PIOB_PDR (AT91C_CAST(AT91C_REG *) 0xFFFFF404) // (PIOB) PIO Disable Register +#define AT91C_PIOB_IFSR (AT91C_CAST(AT91C_REG *) 0xFFFFF428) // (PIOB) Input Filter Status Register +#define AT91C_PIOB_PSR (AT91C_CAST(AT91C_REG *) 0xFFFFF408) // (PIOB) PIO Status Register +#define AT91C_PIOB_SLEWRATE1 (AT91C_CAST(AT91C_REG *) 0xFFFFF4B0) // (PIOB) PIO Slewrate Control Register +#define AT91C_PIOB_IER (AT91C_CAST(AT91C_REG *) 0xFFFFF440) // (PIOB) Interrupt Enable Register +#define AT91C_PIOB_PPUDR (AT91C_CAST(AT91C_REG *) 0xFFFFF460) // (PIOB) Pull-up Disable Register +#define AT91C_PIOB_PER (AT91C_CAST(AT91C_REG *) 0xFFFFF400) // (PIOB) PIO Enable Register +#define AT91C_PIOB_IFDR (AT91C_CAST(AT91C_REG *) 0xFFFFF424) // (PIOB) Input Filter Disable Register +#define AT91C_PIOB_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFF444) // (PIOB) Interrupt Disable Register +#define AT91C_PIOB_OWDR (AT91C_CAST(AT91C_REG *) 0xFFFFF4A4) // (PIOB) Output Write Disable Register +#define AT91C_PIOB_ODSR (AT91C_CAST(AT91C_REG *) 0xFFFFF438) // (PIOB) Output Data Status Register +#define AT91C_PIOB_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFF4C4) // (PIOB) PIO Delay Control Register +#define AT91C_PIOB_OWSR (AT91C_CAST(AT91C_REG *) 0xFFFFF4A8) // (PIOB) Output Write Status Register +#define AT91C_PIOB_BSR (AT91C_CAST(AT91C_REG *) 0xFFFFF474) // (PIOB) Select B Register +#define AT91C_PIOB_IFER (AT91C_CAST(AT91C_REG *) 0xFFFFF420) // (PIOB) Input Filter Enable Register +#define AT91C_PIOB_OWER (AT91C_CAST(AT91C_REG *) 0xFFFFF4A0) // (PIOB) Output Write Enable Register +#define AT91C_PIOB_PPUER (AT91C_CAST(AT91C_REG *) 0xFFFFF464) // (PIOB) Pull-up Enable Register +#define AT91C_PIOB_OSR (AT91C_CAST(AT91C_REG *) 0xFFFFF418) // (PIOB) Output Status Register +#define AT91C_PIOB_ASR (AT91C_CAST(AT91C_REG *) 0xFFFFF470) // (PIOB) Select A Register +#define AT91C_PIOB_OER (AT91C_CAST(AT91C_REG *) 0xFFFFF410) // (PIOB) Output Enable Register +#define AT91C_PIOB_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFF4FC) // (PIOB) PIO Version Register +#define AT91C_PIOB_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFF4C0) // (PIOB) PIO Delay Control Register +// ========== Register definition for PIOC peripheral ========== +#define AT91C_PIOC_OWDR (AT91C_CAST(AT91C_REG *) 0xFFFFF6A4) // (PIOC) Output Write Disable Register +#define AT91C_PIOC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFF648) // (PIOC) Interrupt Mask Register +#define AT91C_PIOC_ASR (AT91C_CAST(AT91C_REG *) 0xFFFFF670) // (PIOC) Select A Register +#define AT91C_PIOC_PPUDR (AT91C_CAST(AT91C_REG *) 0xFFFFF660) // (PIOC) Pull-up Disable Register +#define AT91C_PIOC_CODR (AT91C_CAST(AT91C_REG *) 0xFFFFF634) // (PIOC) Clear Output Data Register +#define AT91C_PIOC_OWER (AT91C_CAST(AT91C_REG *) 0xFFFFF6A0) // (PIOC) Output Write Enable Register +#define AT91C_PIOC_ABSR (AT91C_CAST(AT91C_REG *) 0xFFFFF678) // (PIOC) AB Select Status Register +#define AT91C_PIOC_IFDR (AT91C_CAST(AT91C_REG *) 0xFFFFF624) // (PIOC) Input Filter Disable Register +#define AT91C_PIOC_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFF6FC) // (PIOC) PIO Version Register +#define AT91C_PIOC_ODR (AT91C_CAST(AT91C_REG *) 0xFFFFF614) // (PIOC) Output Disable Registerr +#define AT91C_PIOC_PPUER (AT91C_CAST(AT91C_REG *) 0xFFFFF664) // (PIOC) Pull-up Enable Register +#define AT91C_PIOC_SODR (AT91C_CAST(AT91C_REG *) 0xFFFFF630) // (PIOC) Set Output Data Register +#define AT91C_PIOC_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFF64C) // (PIOC) Interrupt Status Register +#define AT91C_PIOC_OSR (AT91C_CAST(AT91C_REG *) 0xFFFFF618) // (PIOC) Output Status Register +#define AT91C_PIOC_MDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF658) // (PIOC) Multi-driver Status Register +#define AT91C_PIOC_IFER (AT91C_CAST(AT91C_REG *) 0xFFFFF620) // (PIOC) Input Filter Enable Register +#define AT91C_PIOC_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFF6C4) // (PIOC) PIO Delay Control Register +#define AT91C_PIOC_MDER (AT91C_CAST(AT91C_REG *) 0xFFFFF650) // (PIOC) Multi-driver Enable Register +#define AT91C_PIOC_PPUSR (AT91C_CAST(AT91C_REG *) 0xFFFFF668) // (PIOC) Pull-up Status Register +#define AT91C_PIOC_PSR (AT91C_CAST(AT91C_REG *) 0xFFFFF608) // (PIOC) PIO Status Register +#define AT91C_PIOC_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFF6CC) // (PIOC) PIO Delay Control Register +#define AT91C_PIOC_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFF6C8) // (PIOC) PIO Delay Control Register +#define AT91C_PIOC_IER (AT91C_CAST(AT91C_REG *) 0xFFFFF640) // (PIOC) Interrupt Enable Register +#define AT91C_PIOC_SLEWRATE1 (AT91C_CAST(AT91C_REG *) 0xFFFFF6B0) // (PIOC) PIO Slewrate Control Register +#define AT91C_PIOC_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFF644) // (PIOC) Interrupt Disable Register +#define AT91C_PIOC_PDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF63C) // (PIOC) Pin Data Status Register +#define AT91C_PIOC_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFF6C0) // (PIOC) PIO Delay Control Register +#define AT91C_PIOC_PDR (AT91C_CAST(AT91C_REG *) 0xFFFFF604) // (PIOC) PIO Disable Register +#define AT91C_PIOC_OWSR (AT91C_CAST(AT91C_REG *) 0xFFFFF6A8) // (PIOC) Output Write Status Register +#define AT91C_PIOC_IFSR (AT91C_CAST(AT91C_REG *) 0xFFFFF628) // (PIOC) Input Filter Status Register +#define AT91C_PIOC_ODSR (AT91C_CAST(AT91C_REG *) 0xFFFFF638) // (PIOC) Output Data Status Register +#define AT91C_PIOC_OER (AT91C_CAST(AT91C_REG *) 0xFFFFF610) // (PIOC) Output Enable Register +#define AT91C_PIOC_MDDR (AT91C_CAST(AT91C_REG *) 0xFFFFF654) // (PIOC) Multi-driver Disable Register +#define AT91C_PIOC_BSR (AT91C_CAST(AT91C_REG *) 0xFFFFF674) // (PIOC) Select B Register +#define AT91C_PIOC_PER (AT91C_CAST(AT91C_REG *) 0xFFFFF600) // (PIOC) PIO Enable Register +// ========== Register definition for PIOD peripheral ========== +#define AT91C_PIOD_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFF8C0) // (PIOD) PIO Delay Control Register +#define AT91C_PIOD_OWDR (AT91C_CAST(AT91C_REG *) 0xFFFFF8A4) // (PIOD) Output Write Disable Register +#define AT91C_PIOD_SODR (AT91C_CAST(AT91C_REG *) 0xFFFFF830) // (PIOD) Set Output Data Register +#define AT91C_PIOD_PPUER (AT91C_CAST(AT91C_REG *) 0xFFFFF864) // (PIOD) Pull-up Enable Register +#define AT91C_PIOD_CODR (AT91C_CAST(AT91C_REG *) 0xFFFFF834) // (PIOD) Clear Output Data Register +#define AT91C_PIOD_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFF8CC) // (PIOD) PIO Delay Control Register +#define AT91C_PIOD_PSR (AT91C_CAST(AT91C_REG *) 0xFFFFF808) // (PIOD) PIO Status Register +#define AT91C_PIOD_PDR (AT91C_CAST(AT91C_REG *) 0xFFFFF804) // (PIOD) PIO Disable Register +#define AT91C_PIOD_ODR (AT91C_CAST(AT91C_REG *) 0xFFFFF814) // (PIOD) Output Disable Registerr +#define AT91C_PIOD_PPUSR (AT91C_CAST(AT91C_REG *) 0xFFFFF868) // (PIOD) Pull-up Status Register +#define AT91C_PIOD_IFSR (AT91C_CAST(AT91C_REG *) 0xFFFFF828) // (PIOD) Input Filter Status Register +#define AT91C_PIOD_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFF848) // (PIOD) Interrupt Mask Register +#define AT91C_PIOD_ASR (AT91C_CAST(AT91C_REG *) 0xFFFFF870) // (PIOD) Select A Register +#define AT91C_PIOD_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFF8C4) // (PIOD) PIO Delay Control Register +#define AT91C_PIOD_OWSR (AT91C_CAST(AT91C_REG *) 0xFFFFF8A8) // (PIOD) Output Write Status Register +#define AT91C_PIOD_PER (AT91C_CAST(AT91C_REG *) 0xFFFFF800) // (PIOD) PIO Enable Register +#define AT91C_PIOD_MDER (AT91C_CAST(AT91C_REG *) 0xFFFFF850) // (PIOD) Multi-driver Enable Register +#define AT91C_PIOD_PDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF83C) // (PIOD) Pin Data Status Register +#define AT91C_PIOD_MDSR (AT91C_CAST(AT91C_REG *) 0xFFFFF858) // (PIOD) Multi-driver Status Register +#define AT91C_PIOD_OWER (AT91C_CAST(AT91C_REG *) 0xFFFFF8A0) // (PIOD) Output Write Enable Register +#define AT91C_PIOD_BSR (AT91C_CAST(AT91C_REG *) 0xFFFFF874) // (PIOD) Select B Register +#define AT91C_PIOD_IFDR (AT91C_CAST(AT91C_REG *) 0xFFFFF824) // (PIOD) Input Filter Disable Register +#define AT91C_PIOD_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFF8C8) // (PIOD) PIO Delay Control Register +#define AT91C_PIOD_ABSR (AT91C_CAST(AT91C_REG *) 0xFFFFF878) // (PIOD) AB Select Status Register +#define AT91C_PIOD_OER (AT91C_CAST(AT91C_REG *) 0xFFFFF810) // (PIOD) Output Enable Register +#define AT91C_PIOD_MDDR (AT91C_CAST(AT91C_REG *) 0xFFFFF854) // (PIOD) Multi-driver Disable Register +#define AT91C_PIOD_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFF844) // (PIOD) Interrupt Disable Register +#define AT91C_PIOD_IER (AT91C_CAST(AT91C_REG *) 0xFFFFF840) // (PIOD) Interrupt Enable Register +#define AT91C_PIOD_PPUDR (AT91C_CAST(AT91C_REG *) 0xFFFFF860) // (PIOD) Pull-up Disable Register +#define AT91C_PIOD_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFF8FC) // (PIOD) PIO Version Register +#define AT91C_PIOD_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFF84C) // (PIOD) Interrupt Status Register +#define AT91C_PIOD_ODSR (AT91C_CAST(AT91C_REG *) 0xFFFFF838) // (PIOD) Output Data Status Register +#define AT91C_PIOD_OSR (AT91C_CAST(AT91C_REG *) 0xFFFFF818) // (PIOD) Output Status Register +#define AT91C_PIOD_IFER (AT91C_CAST(AT91C_REG *) 0xFFFFF820) // (PIOD) Input Filter Enable Register +#define AT91C_PIOD_SLEWRATE1 (AT91C_CAST(AT91C_REG *) 0xFFFFF8B0) // (PIOD) PIO Slewrate Control Register +// ========== Register definition for PIOE peripheral ========== +#define AT91C_PIOE_ODSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA38) // (PIOE) Output Data Status Register +#define AT91C_PIOE_ABSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA78) // (PIOE) AB Select Status Register +#define AT91C_PIOE_PSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA08) // (PIOE) PIO Status Register +#define AT91C_PIOE_PPUDR (AT91C_CAST(AT91C_REG *) 0xFFFFFA60) // (PIOE) Pull-up Disable Register +#define AT91C_PIOE_OER (AT91C_CAST(AT91C_REG *) 0xFFFFFA10) // (PIOE) Output Enable Register +#define AT91C_PIOE_IFSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA28) // (PIOE) Input Filter Status Register +#define AT91C_PIOE_IFER (AT91C_CAST(AT91C_REG *) 0xFFFFFA20) // (PIOE) Input Filter Enable Register +#define AT91C_PIOE_DELAY3 (AT91C_CAST(AT91C_REG *) 0xFFFFFAC8) // (PIOE) PIO Delay Control Register +#define AT91C_PIOE_ODR (AT91C_CAST(AT91C_REG *) 0xFFFFFA14) // (PIOE) Output Disable Registerr +#define AT91C_PIOE_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFFA44) // (PIOE) Interrupt Disable Register +#define AT91C_PIOE_DELAY1 (AT91C_CAST(AT91C_REG *) 0xFFFFFAC0) // (PIOE) PIO Delay Control Register +#define AT91C_PIOE_OSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA18) // (PIOE) Output Status Register +#define AT91C_PIOE_CODR (AT91C_CAST(AT91C_REG *) 0xFFFFFA34) // (PIOE) Clear Output Data Register +#define AT91C_PIOE_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFFAFC) // (PIOE) PIO Version Register +#define AT91C_PIOE_MDSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA58) // (PIOE) Multi-driver Status Register +#define AT91C_PIOE_PDR (AT91C_CAST(AT91C_REG *) 0xFFFFFA04) // (PIOE) PIO Disable Register +#define AT91C_PIOE_IER (AT91C_CAST(AT91C_REG *) 0xFFFFFA40) // (PIOE) Interrupt Enable Register +#define AT91C_PIOE_OWSR (AT91C_CAST(AT91C_REG *) 0xFFFFFAA8) // (PIOE) Output Write Status Register +#define AT91C_PIOE_BSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA74) // (PIOE) Select B Register +#define AT91C_PIOE_SLEWRATE1 (AT91C_CAST(AT91C_REG *) 0xFFFFFAB0) // (PIOE) PIO Slewrate Control Register +#define AT91C_PIOE_DELAY4 (AT91C_CAST(AT91C_REG *) 0xFFFFFACC) // (PIOE) PIO Delay Control Register +#define AT91C_PIOE_PER (AT91C_CAST(AT91C_REG *) 0xFFFFFA00) // (PIOE) PIO Enable Register +#define AT91C_PIOE_OWDR (AT91C_CAST(AT91C_REG *) 0xFFFFFAA4) // (PIOE) Output Write Disable Register +#define AT91C_PIOE_IFDR (AT91C_CAST(AT91C_REG *) 0xFFFFFA24) // (PIOE) Input Filter Disable Register +#define AT91C_PIOE_PPUSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA68) // (PIOE) Pull-up Status Register +#define AT91C_PIOE_PDSR (AT91C_CAST(AT91C_REG *) 0xFFFFFA3C) // (PIOE) Pin Data Status Register +#define AT91C_PIOE_PPUER (AT91C_CAST(AT91C_REG *) 0xFFFFFA64) // (PIOE) Pull-up Enable Register +#define AT91C_PIOE_MDDR (AT91C_CAST(AT91C_REG *) 0xFFFFFA54) // (PIOE) Multi-driver Disable Register +#define AT91C_PIOE_ISR (AT91C_CAST(AT91C_REG *) 0xFFFFFA4C) // (PIOE) Interrupt Status Register +#define AT91C_PIOE_DELAY2 (AT91C_CAST(AT91C_REG *) 0xFFFFFAC4) // (PIOE) PIO Delay Control Register +#define AT91C_PIOE_SODR (AT91C_CAST(AT91C_REG *) 0xFFFFFA30) // (PIOE) Set Output Data Register +#define AT91C_PIOE_ASR (AT91C_CAST(AT91C_REG *) 0xFFFFFA70) // (PIOE) Select A Register +#define AT91C_PIOE_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFFA48) // (PIOE) Interrupt Mask Register +#define AT91C_PIOE_OWER (AT91C_CAST(AT91C_REG *) 0xFFFFFAA0) // (PIOE) Output Write Enable Register +#define AT91C_PIOE_MDER (AT91C_CAST(AT91C_REG *) 0xFFFFFA50) // (PIOE) Multi-driver Enable Register +// ========== Register definition for PMC peripheral ========== +#define AT91C_PMC_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFFFFCEC) // (PMC) +#define AT91C_PMC_PCER (AT91C_CAST(AT91C_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register +#define AT91C_PMC_PCKR (AT91C_CAST(AT91C_REG *) 0xFFFFFC40) // (PMC) Programmable Clock 0 Register +#define AT91C_PMC_MCKR (AT91C_CAST(AT91C_REG *) 0xFFFFFC30) // (PMC) Master Clock Register +#define AT91C_PMC_PLLAR (AT91C_CAST(AT91C_REG *) 0xFFFFFC28) // (PMC) PLL A Register +#define AT91C_PMC_NAME2 (AT91C_CAST(AT91C_REG *) 0xFFFFFCF4) // (PMC) +#define AT91C_PMC_PCDR (AT91C_CAST(AT91C_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register +#define AT91C_PMC_SCSR (AT91C_CAST(AT91C_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register +#define AT91C_PMC_MCFR (AT91C_CAST(AT91C_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register +#define AT91C_PMC_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFFFFCF8) // (PMC) +#define AT91C_PMC_PLLICPR (AT91C_CAST(AT91C_REG *) 0xFFFFFC80) // (PMC) PLL Charge Pump Current Register +#define AT91C_PMC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register +#define AT91C_PMC_IER (AT91C_CAST(AT91C_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register +#define AT91C_PMC_UCKR (AT91C_CAST(AT91C_REG *) 0xFFFFFC1C) // (PMC) UTMI Clock Configuration Register +#define AT91C_PMC_USB (AT91C_CAST(AT91C_REG *) 0xFFFFFC38) // (PMC) USB clock register +#define AT91C_PMC_MOR (AT91C_CAST(AT91C_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register +#define AT91C_PMC_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register +#define AT91C_PMC_NAME1 (AT91C_CAST(AT91C_REG *) 0xFFFFFCF0) // (PMC) +#define AT91C_PMC_SCDR (AT91C_CAST(AT91C_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register +#define AT91C_PMC_PCSR (AT91C_CAST(AT91C_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register +#define AT91C_PMC_SCER (AT91C_CAST(AT91C_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register +#define AT91C_PMC_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFFFCFC) // (PMC) +#define AT91C_PMC_SR (AT91C_CAST(AT91C_REG *) 0xFFFFFC68) // (PMC) Status Register +// ========== Register definition for CKGR peripheral ========== +#define AT91C_CKGR_MOR (AT91C_CAST(AT91C_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register +#define AT91C_CKGR_MCFR (AT91C_CAST(AT91C_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register +#define AT91C_CKGR_PLLAR (AT91C_CAST(AT91C_REG *) 0xFFFFFC28) // (CKGR) PLL A Register +#define AT91C_CKGR_UCKR (AT91C_CAST(AT91C_REG *) 0xFFFFFC1C) // (CKGR) UTMI Clock Configuration Register +// ========== Register definition for RSTC peripheral ========== +#define AT91C_RSTC_RCR (AT91C_CAST(AT91C_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register +#define AT91C_RSTC_VER (AT91C_CAST(AT91C_REG *) 0xFFFFFDFC) // (RSTC) Version Register +#define AT91C_RSTC_RMR (AT91C_CAST(AT91C_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register +#define AT91C_RSTC_RSR (AT91C_CAST(AT91C_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register +// ========== Register definition for SHDWC peripheral ========== +#define AT91C_SHDWC_SHSR (AT91C_CAST(AT91C_REG *) 0xFFFFFD18) // (SHDWC) Shut Down Status Register +#define AT91C_SHDWC_SHMR (AT91C_CAST(AT91C_REG *) 0xFFFFFD14) // (SHDWC) Shut Down Mode Register +#define AT91C_SHDWC_SHCR (AT91C_CAST(AT91C_REG *) 0xFFFFFD10) // (SHDWC) Shut Down Control Register +// ========== Register definition for RTTC peripheral ========== +#define AT91C_RTTC_RTSR (AT91C_CAST(AT91C_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register +#define AT91C_RTTC_RTMR (AT91C_CAST(AT91C_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register +#define AT91C_RTTC_RTVR (AT91C_CAST(AT91C_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register +#define AT91C_RTTC_RTAR (AT91C_CAST(AT91C_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register +// ========== Register definition for PITC peripheral ========== +#define AT91C_PITC_PIVR (AT91C_CAST(AT91C_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register +#define AT91C_PITC_PISR (AT91C_CAST(AT91C_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register +#define AT91C_PITC_PIIR (AT91C_CAST(AT91C_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register +#define AT91C_PITC_PIMR (AT91C_CAST(AT91C_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register +// ========== Register definition for WDTC peripheral ========== +#define AT91C_WDTC_WDCR (AT91C_CAST(AT91C_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register +#define AT91C_WDTC_WDSR (AT91C_CAST(AT91C_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register +#define AT91C_WDTC_WDMR (AT91C_CAST(AT91C_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register +// ========== Register definition for RTC peripheral ========== +#define AT91C_RTC_IDR (AT91C_CAST(AT91C_REG *) 0xFFFFFDD4) // (RTC) Interrupt Disable Register +#define AT91C_RTC_SR (AT91C_CAST(AT91C_REG *) 0xFFFFFDC8) // (RTC) Status Register +#define AT91C_RTC_MR (AT91C_CAST(AT91C_REG *) 0xFFFFFDB4) // (RTC) Mode Register +#define AT91C_RTC_IER (AT91C_CAST(AT91C_REG *) 0xFFFFFDD0) // (RTC) Interrupt Enable Register +#define AT91C_RTC_TIMALR (AT91C_CAST(AT91C_REG *) 0xFFFFFDC0) // (RTC) Time Alarm Register +#define AT91C_RTC_CALALR (AT91C_CAST(AT91C_REG *) 0xFFFFFDC4) // (RTC) Calendar Alarm Register +#define AT91C_RTC_CR (AT91C_CAST(AT91C_REG *) 0xFFFFFDB0) // (RTC) Control Register +#define AT91C_RTC_TIMR (AT91C_CAST(AT91C_REG *) 0xFFFFFDB8) // (RTC) Time Register +#define AT91C_RTC_CALR (AT91C_CAST(AT91C_REG *) 0xFFFFFDBC) // (RTC) Calendar Register +#define AT91C_RTC_VER (AT91C_CAST(AT91C_REG *) 0xFFFFFDDC) // (RTC) Valid Entry Register +#define AT91C_RTC_SCCR (AT91C_CAST(AT91C_REG *) 0xFFFFFDCC) // (RTC) Status Clear Command Register +#define AT91C_RTC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFFFDD8) // (RTC) Interrupt Mask Register +// ========== Register definition for TC0 peripheral ========== +#define AT91C_TC0_IER (AT91C_CAST(AT91C_REG *) 0xFFF7C024) // (TC0) Interrupt Enable Register +#define AT91C_TC0_IMR (AT91C_CAST(AT91C_REG *) 0xFFF7C02C) // (TC0) Interrupt Mask Register +#define AT91C_TC0_CCR (AT91C_CAST(AT91C_REG *) 0xFFF7C000) // (TC0) Channel Control Register +#define AT91C_TC0_RB (AT91C_CAST(AT91C_REG *) 0xFFF7C018) // (TC0) Register B +#define AT91C_TC0_CV (AT91C_CAST(AT91C_REG *) 0xFFF7C010) // (TC0) Counter Value +#define AT91C_TC0_SR (AT91C_CAST(AT91C_REG *) 0xFFF7C020) // (TC0) Status Register +#define AT91C_TC0_CMR (AT91C_CAST(AT91C_REG *) 0xFFF7C004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC0_RA (AT91C_CAST(AT91C_REG *) 0xFFF7C014) // (TC0) Register A +#define AT91C_TC0_RC (AT91C_CAST(AT91C_REG *) 0xFFF7C01C) // (TC0) Register C +#define AT91C_TC0_IDR (AT91C_CAST(AT91C_REG *) 0xFFF7C028) // (TC0) Interrupt Disable Register +// ========== Register definition for TC1 peripheral ========== +#define AT91C_TC1_IER (AT91C_CAST(AT91C_REG *) 0xFFF7C064) // (TC1) Interrupt Enable Register +#define AT91C_TC1_SR (AT91C_CAST(AT91C_REG *) 0xFFF7C060) // (TC1) Status Register +#define AT91C_TC1_RC (AT91C_CAST(AT91C_REG *) 0xFFF7C05C) // (TC1) Register C +#define AT91C_TC1_CV (AT91C_CAST(AT91C_REG *) 0xFFF7C050) // (TC1) Counter Value +#define AT91C_TC1_RA (AT91C_CAST(AT91C_REG *) 0xFFF7C054) // (TC1) Register A +#define AT91C_TC1_CMR (AT91C_CAST(AT91C_REG *) 0xFFF7C044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC1_IDR (AT91C_CAST(AT91C_REG *) 0xFFF7C068) // (TC1) Interrupt Disable Register +#define AT91C_TC1_RB (AT91C_CAST(AT91C_REG *) 0xFFF7C058) // (TC1) Register B +#define AT91C_TC1_IMR (AT91C_CAST(AT91C_REG *) 0xFFF7C06C) // (TC1) Interrupt Mask Register +#define AT91C_TC1_CCR (AT91C_CAST(AT91C_REG *) 0xFFF7C040) // (TC1) Channel Control Register +// ========== Register definition for TC2 peripheral ========== +#define AT91C_TC2_SR (AT91C_CAST(AT91C_REG *) 0xFFF7C0A0) // (TC2) Status Register +#define AT91C_TC2_IMR (AT91C_CAST(AT91C_REG *) 0xFFF7C0AC) // (TC2) Interrupt Mask Register +#define AT91C_TC2_IER (AT91C_CAST(AT91C_REG *) 0xFFF7C0A4) // (TC2) Interrupt Enable Register +#define AT91C_TC2_CV (AT91C_CAST(AT91C_REG *) 0xFFF7C090) // (TC2) Counter Value +#define AT91C_TC2_RB (AT91C_CAST(AT91C_REG *) 0xFFF7C098) // (TC2) Register B +#define AT91C_TC2_CCR (AT91C_CAST(AT91C_REG *) 0xFFF7C080) // (TC2) Channel Control Register +#define AT91C_TC2_CMR (AT91C_CAST(AT91C_REG *) 0xFFF7C084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC2_RA (AT91C_CAST(AT91C_REG *) 0xFFF7C094) // (TC2) Register A +#define AT91C_TC2_IDR (AT91C_CAST(AT91C_REG *) 0xFFF7C0A8) // (TC2) Interrupt Disable Register +#define AT91C_TC2_RC (AT91C_CAST(AT91C_REG *) 0xFFF7C09C) // (TC2) Register C +// ========== Register definition for TC3 peripheral ========== +#define AT91C_TC3_SR (AT91C_CAST(AT91C_REG *) 0xFFFD4020) // (TC3) Status Register +#define AT91C_TC3_RC (AT91C_CAST(AT91C_REG *) 0xFFFD401C) // (TC3) Register C +#define AT91C_TC3_IER (AT91C_CAST(AT91C_REG *) 0xFFFD4024) // (TC3) Interrupt Enable Register +#define AT91C_TC3_CV (AT91C_CAST(AT91C_REG *) 0xFFFD4010) // (TC3) Counter Value +#define AT91C_TC3_IDR (AT91C_CAST(AT91C_REG *) 0xFFFD4028) // (TC3) Interrupt Disable Register +#define AT91C_TC3_IMR (AT91C_CAST(AT91C_REG *) 0xFFFD402C) // (TC3) Interrupt Mask Register +#define AT91C_TC3_CMR (AT91C_CAST(AT91C_REG *) 0xFFFD4004) // (TC3) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC3_RB (AT91C_CAST(AT91C_REG *) 0xFFFD4018) // (TC3) Register B +#define AT91C_TC3_CCR (AT91C_CAST(AT91C_REG *) 0xFFFD4000) // (TC3) Channel Control Register +#define AT91C_TC3_RA (AT91C_CAST(AT91C_REG *) 0xFFFD4014) // (TC3) Register A +// ========== Register definition for TC4 peripheral ========== +#define AT91C_TC4_CV (AT91C_CAST(AT91C_REG *) 0xFFFD4050) // (TC4) Counter Value +#define AT91C_TC4_RA (AT91C_CAST(AT91C_REG *) 0xFFFD4054) // (TC4) Register A +#define AT91C_TC4_IDR (AT91C_CAST(AT91C_REG *) 0xFFFD4068) // (TC4) Interrupt Disable Register +#define AT91C_TC4_SR (AT91C_CAST(AT91C_REG *) 0xFFFD4060) // (TC4) Status Register +#define AT91C_TC4_CMR (AT91C_CAST(AT91C_REG *) 0xFFFD4044) // (TC4) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC4_CCR (AT91C_CAST(AT91C_REG *) 0xFFFD4040) // (TC4) Channel Control Register +#define AT91C_TC4_RB (AT91C_CAST(AT91C_REG *) 0xFFFD4058) // (TC4) Register B +#define AT91C_TC4_RC (AT91C_CAST(AT91C_REG *) 0xFFFD405C) // (TC4) Register C +#define AT91C_TC4_IER (AT91C_CAST(AT91C_REG *) 0xFFFD4064) // (TC4) Interrupt Enable Register +#define AT91C_TC4_IMR (AT91C_CAST(AT91C_REG *) 0xFFFD406C) // (TC4) Interrupt Mask Register +// ========== Register definition for TC5 peripheral ========== +#define AT91C_TC5_IER (AT91C_CAST(AT91C_REG *) 0xFFFD40A4) // (TC5) Interrupt Enable Register +#define AT91C_TC5_IDR (AT91C_CAST(AT91C_REG *) 0xFFFD40A8) // (TC5) Interrupt Disable Register +#define AT91C_TC5_RA (AT91C_CAST(AT91C_REG *) 0xFFFD4094) // (TC5) Register A +#define AT91C_TC5_RB (AT91C_CAST(AT91C_REG *) 0xFFFD4098) // (TC5) Register B +#define AT91C_TC5_CCR (AT91C_CAST(AT91C_REG *) 0xFFFD4080) // (TC5) Channel Control Register +#define AT91C_TC5_SR (AT91C_CAST(AT91C_REG *) 0xFFFD40A0) // (TC5) Status Register +#define AT91C_TC5_CV (AT91C_CAST(AT91C_REG *) 0xFFFD4090) // (TC5) Counter Value +#define AT91C_TC5_RC (AT91C_CAST(AT91C_REG *) 0xFFFD409C) // (TC5) Register C +#define AT91C_TC5_IMR (AT91C_CAST(AT91C_REG *) 0xFFFD40AC) // (TC5) Interrupt Mask Register +#define AT91C_TC5_CMR (AT91C_CAST(AT91C_REG *) 0xFFFD4084) // (TC5) Channel Mode Register (Capture Mode / Waveform Mode) +// ========== Register definition for TCB0 peripheral ========== +#define AT91C_TCB0_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF7C0F0) // (TCB0) TC IPNAME1 REGISTER +#define AT91C_TCB0_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF7C0F4) // (TCB0) TC IPNAME2 REGISTER +#define AT91C_TCB0_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF7C0F8) // (TCB0) TC FEATURES REGISTER +#define AT91C_TCB0_BCR (AT91C_CAST(AT91C_REG *) 0xFFF7C0C0) // (TCB0) TC Block Control Register +#define AT91C_TCB0_VER (AT91C_CAST(AT91C_REG *) 0xFFF7C0FC) // (TCB0) Version Register +#define AT91C_TCB0_BMR (AT91C_CAST(AT91C_REG *) 0xFFF7C0C4) // (TCB0) TC Block Mode Register +#define AT91C_TCB0_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF7C0EC) // (TCB0) TC ADDRSIZE REGISTER +// ========== Register definition for TCB1 peripheral ========== +#define AT91C_TCB1_VER (AT91C_CAST(AT91C_REG *) 0xFFFD40FC) // (TCB1) Version Register +#define AT91C_TCB1_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFFD40F4) // (TCB1) TC IPNAME2 REGISTER +#define AT91C_TCB1_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFFD40EC) // (TCB1) TC ADDRSIZE REGISTER +#define AT91C_TCB1_BMR (AT91C_CAST(AT91C_REG *) 0xFFFD40C4) // (TCB1) TC Block Mode Register +#define AT91C_TCB1_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFFD40F8) // (TCB1) TC FEATURES REGISTER +#define AT91C_TCB1_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFFD40F0) // (TCB1) TC IPNAME1 REGISTER +#define AT91C_TCB1_BCR (AT91C_CAST(AT91C_REG *) 0xFFFD40C0) // (TCB1) TC Block Control Register +// ========== Register definition for MCI0 peripheral ========== +#define AT91C_MCI0_IMR (AT91C_CAST(AT91C_REG *) 0xFFF8004C) // (MCI0) MCI Interrupt Mask Register +#define AT91C_MCI0_MR (AT91C_CAST(AT91C_REG *) 0xFFF80004) // (MCI0) MCI Mode Register +#define AT91C_MCI0_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF800EC) // (MCI0) MCI ADDRSIZE REGISTER +#define AT91C_MCI0_CR (AT91C_CAST(AT91C_REG *) 0xFFF80000) // (MCI0) MCI Control Register +#define AT91C_MCI0_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF800F4) // (MCI0) MCI IPNAME2 REGISTER +#define AT91C_MCI0_IER (AT91C_CAST(AT91C_REG *) 0xFFF80044) // (MCI0) MCI Interrupt Enable Register +#define AT91C_MCI0_FIFO (AT91C_CAST(AT91C_REG *) 0xFFF80200) // (MCI0) MCI FIFO Aperture Register +#define AT91C_MCI0_DTOR (AT91C_CAST(AT91C_REG *) 0xFFF80008) // (MCI0) MCI Data Timeout Register +#define AT91C_MCI0_SDCR (AT91C_CAST(AT91C_REG *) 0xFFF8000C) // (MCI0) MCI SD/SDIO Card Register +#define AT91C_MCI0_BLKR (AT91C_CAST(AT91C_REG *) 0xFFF80018) // (MCI0) MCI Block Register +#define AT91C_MCI0_VER (AT91C_CAST(AT91C_REG *) 0xFFF800FC) // (MCI0) MCI VERSION REGISTER +#define AT91C_MCI0_WPSR (AT91C_CAST(AT91C_REG *) 0xFFF800E8) // (MCI0) MCI Write Protection Status Register +#define AT91C_MCI0_CMDR (AT91C_CAST(AT91C_REG *) 0xFFF80014) // (MCI0) MCI Command Register +#define AT91C_MCI0_CSTOR (AT91C_CAST(AT91C_REG *) 0xFFF8001C) // (MCI0) MCI Completion Signal Timeout Register +#define AT91C_MCI0_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF800F0) // (MCI0) MCI IPNAME1 REGISTER +#define AT91C_MCI0_DMA (AT91C_CAST(AT91C_REG *) 0xFFF80050) // (MCI0) MCI DMA Configuration Register +#define AT91C_MCI0_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF800F8) // (MCI0) MCI FEATURES REGISTER +#define AT91C_MCI0_RDR (AT91C_CAST(AT91C_REG *) 0xFFF80030) // (MCI0) MCI Receive Data Register +#define AT91C_MCI0_SR (AT91C_CAST(AT91C_REG *) 0xFFF80040) // (MCI0) MCI Status Register +#define AT91C_MCI0_TDR (AT91C_CAST(AT91C_REG *) 0xFFF80034) // (MCI0) MCI Transmit Data Register +#define AT91C_MCI0_CFG (AT91C_CAST(AT91C_REG *) 0xFFF80054) // (MCI0) MCI Configuration Register +#define AT91C_MCI0_ARGR (AT91C_CAST(AT91C_REG *) 0xFFF80010) // (MCI0) MCI Argument Register +#define AT91C_MCI0_RSPR (AT91C_CAST(AT91C_REG *) 0xFFF80020) // (MCI0) MCI Response Register +#define AT91C_MCI0_WPCR (AT91C_CAST(AT91C_REG *) 0xFFF800E4) // (MCI0) MCI Write Protection Control Register +#define AT91C_MCI0_IDR (AT91C_CAST(AT91C_REG *) 0xFFF80048) // (MCI0) MCI Interrupt Disable Register +// ========== Register definition for MCI1 peripheral ========== +#define AT91C_MCI1_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFFD00F0) // (MCI1) MCI IPNAME1 REGISTER +#define AT91C_MCI1_IDR (AT91C_CAST(AT91C_REG *) 0xFFFD0048) // (MCI1) MCI Interrupt Disable Register +#define AT91C_MCI1_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFFD00F4) // (MCI1) MCI IPNAME2 REGISTER +#define AT91C_MCI1_MR (AT91C_CAST(AT91C_REG *) 0xFFFD0004) // (MCI1) MCI Mode Register +#define AT91C_MCI1_SR (AT91C_CAST(AT91C_REG *) 0xFFFD0040) // (MCI1) MCI Status Register +#define AT91C_MCI1_DTOR (AT91C_CAST(AT91C_REG *) 0xFFFD0008) // (MCI1) MCI Data Timeout Register +#define AT91C_MCI1_WPCR (AT91C_CAST(AT91C_REG *) 0xFFFD00E4) // (MCI1) MCI Write Protection Control Register +#define AT91C_MCI1_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFFD00EC) // (MCI1) MCI ADDRSIZE REGISTER +#define AT91C_MCI1_ARGR (AT91C_CAST(AT91C_REG *) 0xFFFD0010) // (MCI1) MCI Argument Register +#define AT91C_MCI1_FIFO (AT91C_CAST(AT91C_REG *) 0xFFFD0200) // (MCI1) MCI FIFO Aperture Register +#define AT91C_MCI1_IER (AT91C_CAST(AT91C_REG *) 0xFFFD0044) // (MCI1) MCI Interrupt Enable Register +#define AT91C_MCI1_SDCR (AT91C_CAST(AT91C_REG *) 0xFFFD000C) // (MCI1) MCI SD/SDIO Card Register +#define AT91C_MCI1_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFFD00F8) // (MCI1) MCI FEATURES REGISTER +#define AT91C_MCI1_CR (AT91C_CAST(AT91C_REG *) 0xFFFD0000) // (MCI1) MCI Control Register +#define AT91C_MCI1_CSTOR (AT91C_CAST(AT91C_REG *) 0xFFFD001C) // (MCI1) MCI Completion Signal Timeout Register +#define AT91C_MCI1_RSPR (AT91C_CAST(AT91C_REG *) 0xFFFD0020) // (MCI1) MCI Response Register +#define AT91C_MCI1_IMR (AT91C_CAST(AT91C_REG *) 0xFFFD004C) // (MCI1) MCI Interrupt Mask Register +#define AT91C_MCI1_DMA (AT91C_CAST(AT91C_REG *) 0xFFFD0050) // (MCI1) MCI DMA Configuration Register +#define AT91C_MCI1_BLKR (AT91C_CAST(AT91C_REG *) 0xFFFD0018) // (MCI1) MCI Block Register +#define AT91C_MCI1_RDR (AT91C_CAST(AT91C_REG *) 0xFFFD0030) // (MCI1) MCI Receive Data Register +#define AT91C_MCI1_CFG (AT91C_CAST(AT91C_REG *) 0xFFFD0054) // (MCI1) MCI Configuration Register +#define AT91C_MCI1_WPSR (AT91C_CAST(AT91C_REG *) 0xFFFD00E8) // (MCI1) MCI Write Protection Status Register +#define AT91C_MCI1_CMDR (AT91C_CAST(AT91C_REG *) 0xFFFD0014) // (MCI1) MCI Command Register +#define AT91C_MCI1_TDR (AT91C_CAST(AT91C_REG *) 0xFFFD0034) // (MCI1) MCI Transmit Data Register +#define AT91C_MCI1_VER (AT91C_CAST(AT91C_REG *) 0xFFFD00FC) // (MCI1) MCI VERSION REGISTER +// ========== Register definition for TWI0 peripheral ========== +#define AT91C_TWI0_RHR (AT91C_CAST(AT91C_REG *) 0xFFF84030) // (TWI0) Receive Holding Register +#define AT91C_TWI0_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF840EC) // (TWI0) TWI ADDRSIZE REGISTER +#define AT91C_TWI0_SMR (AT91C_CAST(AT91C_REG *) 0xFFF84008) // (TWI0) Slave Mode Register +#define AT91C_TWI0_IDR (AT91C_CAST(AT91C_REG *) 0xFFF84028) // (TWI0) Interrupt Disable Register +#define AT91C_TWI0_CWGR (AT91C_CAST(AT91C_REG *) 0xFFF84010) // (TWI0) Clock Waveform Generator Register +#define AT91C_TWI0_IER (AT91C_CAST(AT91C_REG *) 0xFFF84024) // (TWI0) Interrupt Enable Register +#define AT91C_TWI0_THR (AT91C_CAST(AT91C_REG *) 0xFFF84034) // (TWI0) Transmit Holding Register +#define AT91C_TWI0_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF840F4) // (TWI0) TWI IPNAME2 REGISTER +#define AT91C_TWI0_CR (AT91C_CAST(AT91C_REG *) 0xFFF84000) // (TWI0) Control Register +#define AT91C_TWI0_MMR (AT91C_CAST(AT91C_REG *) 0xFFF84004) // (TWI0) Master Mode Register +#define AT91C_TWI0_SR (AT91C_CAST(AT91C_REG *) 0xFFF84020) // (TWI0) Status Register +#define AT91C_TWI0_IMR (AT91C_CAST(AT91C_REG *) 0xFFF8402C) // (TWI0) Interrupt Mask Register +#define AT91C_TWI0_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF840F8) // (TWI0) TWI FEATURES REGISTER +#define AT91C_TWI0_IADR (AT91C_CAST(AT91C_REG *) 0xFFF8400C) // (TWI0) Internal Address Register +#define AT91C_TWI0_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF840F0) // (TWI0) TWI IPNAME1 REGISTER +#define AT91C_TWI0_VER (AT91C_CAST(AT91C_REG *) 0xFFF840FC) // (TWI0) Version Register +// ========== Register definition for TWI1 peripheral ========== +#define AT91C_TWI1_VER (AT91C_CAST(AT91C_REG *) 0xFFF880FC) // (TWI1) Version Register +#define AT91C_TWI1_IMR (AT91C_CAST(AT91C_REG *) 0xFFF8802C) // (TWI1) Interrupt Mask Register +#define AT91C_TWI1_THR (AT91C_CAST(AT91C_REG *) 0xFFF88034) // (TWI1) Transmit Holding Register +#define AT91C_TWI1_IER (AT91C_CAST(AT91C_REG *) 0xFFF88024) // (TWI1) Interrupt Enable Register +#define AT91C_TWI1_MMR (AT91C_CAST(AT91C_REG *) 0xFFF88004) // (TWI1) Master Mode Register +#define AT91C_TWI1_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF880F0) // (TWI1) TWI IPNAME1 REGISTER +#define AT91C_TWI1_CR (AT91C_CAST(AT91C_REG *) 0xFFF88000) // (TWI1) Control Register +#define AT91C_TWI1_SR (AT91C_CAST(AT91C_REG *) 0xFFF88020) // (TWI1) Status Register +#define AT91C_TWI1_CWGR (AT91C_CAST(AT91C_REG *) 0xFFF88010) // (TWI1) Clock Waveform Generator Register +#define AT91C_TWI1_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF880F4) // (TWI1) TWI IPNAME2 REGISTER +#define AT91C_TWI1_IDR (AT91C_CAST(AT91C_REG *) 0xFFF88028) // (TWI1) Interrupt Disable Register +#define AT91C_TWI1_RHR (AT91C_CAST(AT91C_REG *) 0xFFF88030) // (TWI1) Receive Holding Register +#define AT91C_TWI1_IADR (AT91C_CAST(AT91C_REG *) 0xFFF8800C) // (TWI1) Internal Address Register +#define AT91C_TWI1_SMR (AT91C_CAST(AT91C_REG *) 0xFFF88008) // (TWI1) Slave Mode Register +#define AT91C_TWI1_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF880F8) // (TWI1) TWI FEATURES REGISTER +#define AT91C_TWI1_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF880EC) // (TWI1) TWI ADDRSIZE REGISTER +// ========== Register definition for PDC_US0 peripheral ========== +#define AT91C_US0_TNPR (AT91C_CAST(AT91C_REG *) 0xFFF8C118) // (PDC_US0) Transmit Next Pointer Register +#define AT91C_US0_PTSR (AT91C_CAST(AT91C_REG *) 0xFFF8C124) // (PDC_US0) PDC Transfer Status Register +#define AT91C_US0_PTCR (AT91C_CAST(AT91C_REG *) 0xFFF8C120) // (PDC_US0) PDC Transfer Control Register +#define AT91C_US0_RNCR (AT91C_CAST(AT91C_REG *) 0xFFF8C114) // (PDC_US0) Receive Next Counter Register +#define AT91C_US0_RCR (AT91C_CAST(AT91C_REG *) 0xFFF8C104) // (PDC_US0) Receive Counter Register +#define AT91C_US0_TNCR (AT91C_CAST(AT91C_REG *) 0xFFF8C11C) // (PDC_US0) Transmit Next Counter Register +#define AT91C_US0_TCR (AT91C_CAST(AT91C_REG *) 0xFFF8C10C) // (PDC_US0) Transmit Counter Register +#define AT91C_US0_RNPR (AT91C_CAST(AT91C_REG *) 0xFFF8C110) // (PDC_US0) Receive Next Pointer Register +#define AT91C_US0_RPR (AT91C_CAST(AT91C_REG *) 0xFFF8C100) // (PDC_US0) Receive Pointer Register +#define AT91C_US0_TPR (AT91C_CAST(AT91C_REG *) 0xFFF8C108) // (PDC_US0) Transmit Pointer Register +// ========== Register definition for US0 peripheral ========== +#define AT91C_US0_MAN (AT91C_CAST(AT91C_REG *) 0xFFF8C050) // (US0) Manchester Encoder Decoder Register +#define AT91C_US0_MR (AT91C_CAST(AT91C_REG *) 0xFFF8C004) // (US0) Mode Register +#define AT91C_US0_RHR (AT91C_CAST(AT91C_REG *) 0xFFF8C018) // (US0) Receiver Holding Register +#define AT91C_US0_CSR (AT91C_CAST(AT91C_REG *) 0xFFF8C014) // (US0) Channel Status Register +#define AT91C_US0_CR (AT91C_CAST(AT91C_REG *) 0xFFF8C000) // (US0) Control Register +#define AT91C_US0_VER (AT91C_CAST(AT91C_REG *) 0xFFF8C0FC) // (US0) VERSION Register +#define AT91C_US0_IER (AT91C_CAST(AT91C_REG *) 0xFFF8C008) // (US0) Interrupt Enable Register +#define AT91C_US0_BRGR (AT91C_CAST(AT91C_REG *) 0xFFF8C020) // (US0) Baud Rate Generator Register +#define AT91C_US0_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF8C0F8) // (US0) US FEATURES REGISTER +#define AT91C_US0_RTOR (AT91C_CAST(AT91C_REG *) 0xFFF8C024) // (US0) Receiver Time-out Register +#define AT91C_US0_THR (AT91C_CAST(AT91C_REG *) 0xFFF8C01C) // (US0) Transmitter Holding Register +#define AT91C_US0_NER (AT91C_CAST(AT91C_REG *) 0xFFF8C044) // (US0) Nb Errors Register +#define AT91C_US0_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF8C0F0) // (US0) US IPNAME1 REGISTER +#define AT91C_US0_IMR (AT91C_CAST(AT91C_REG *) 0xFFF8C010) // (US0) Interrupt Mask Register +#define AT91C_US0_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF8C0EC) // (US0) US ADDRSIZE REGISTER +#define AT91C_US0_IDR (AT91C_CAST(AT91C_REG *) 0xFFF8C00C) // (US0) Interrupt Disable Register +#define AT91C_US0_FIDI (AT91C_CAST(AT91C_REG *) 0xFFF8C040) // (US0) FI_DI_Ratio Register +#define AT91C_US0_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF8C0F4) // (US0) US IPNAME2 REGISTER +#define AT91C_US0_TTGR (AT91C_CAST(AT91C_REG *) 0xFFF8C028) // (US0) Transmitter Time-guard Register +#define AT91C_US0_IF (AT91C_CAST(AT91C_REG *) 0xFFF8C04C) // (US0) IRDA_FILTER Register +// ========== Register definition for PDC_US1 peripheral ========== +#define AT91C_US1_PTCR (AT91C_CAST(AT91C_REG *) 0xFFF90120) // (PDC_US1) PDC Transfer Control Register +#define AT91C_US1_TNCR (AT91C_CAST(AT91C_REG *) 0xFFF9011C) // (PDC_US1) Transmit Next Counter Register +#define AT91C_US1_RCR (AT91C_CAST(AT91C_REG *) 0xFFF90104) // (PDC_US1) Receive Counter Register +#define AT91C_US1_RPR (AT91C_CAST(AT91C_REG *) 0xFFF90100) // (PDC_US1) Receive Pointer Register +#define AT91C_US1_TPR (AT91C_CAST(AT91C_REG *) 0xFFF90108) // (PDC_US1) Transmit Pointer Register +#define AT91C_US1_TCR (AT91C_CAST(AT91C_REG *) 0xFFF9010C) // (PDC_US1) Transmit Counter Register +#define AT91C_US1_RNPR (AT91C_CAST(AT91C_REG *) 0xFFF90110) // (PDC_US1) Receive Next Pointer Register +#define AT91C_US1_TNPR (AT91C_CAST(AT91C_REG *) 0xFFF90118) // (PDC_US1) Transmit Next Pointer Register +#define AT91C_US1_RNCR (AT91C_CAST(AT91C_REG *) 0xFFF90114) // (PDC_US1) Receive Next Counter Register +#define AT91C_US1_PTSR (AT91C_CAST(AT91C_REG *) 0xFFF90124) // (PDC_US1) PDC Transfer Status Register +// ========== Register definition for US1 peripheral ========== +#define AT91C_US1_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF900F8) // (US1) US FEATURES REGISTER +#define AT91C_US1_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF900EC) // (US1) US ADDRSIZE REGISTER +#define AT91C_US1_NER (AT91C_CAST(AT91C_REG *) 0xFFF90044) // (US1) Nb Errors Register +#define AT91C_US1_RHR (AT91C_CAST(AT91C_REG *) 0xFFF90018) // (US1) Receiver Holding Register +#define AT91C_US1_IF (AT91C_CAST(AT91C_REG *) 0xFFF9004C) // (US1) IRDA_FILTER Register +#define AT91C_US1_CR (AT91C_CAST(AT91C_REG *) 0xFFF90000) // (US1) Control Register +#define AT91C_US1_TTGR (AT91C_CAST(AT91C_REG *) 0xFFF90028) // (US1) Transmitter Time-guard Register +#define AT91C_US1_MR (AT91C_CAST(AT91C_REG *) 0xFFF90004) // (US1) Mode Register +#define AT91C_US1_FIDI (AT91C_CAST(AT91C_REG *) 0xFFF90040) // (US1) FI_DI_Ratio Register +#define AT91C_US1_RTOR (AT91C_CAST(AT91C_REG *) 0xFFF90024) // (US1) Receiver Time-out Register +#define AT91C_US1_IER (AT91C_CAST(AT91C_REG *) 0xFFF90008) // (US1) Interrupt Enable Register +#define AT91C_US1_MAN (AT91C_CAST(AT91C_REG *) 0xFFF90050) // (US1) Manchester Encoder Decoder Register +#define AT91C_US1_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF900F4) // (US1) US IPNAME2 REGISTER +#define AT91C_US1_IMR (AT91C_CAST(AT91C_REG *) 0xFFF90010) // (US1) Interrupt Mask Register +#define AT91C_US1_IDR (AT91C_CAST(AT91C_REG *) 0xFFF9000C) // (US1) Interrupt Disable Register +#define AT91C_US1_CSR (AT91C_CAST(AT91C_REG *) 0xFFF90014) // (US1) Channel Status Register +#define AT91C_US1_BRGR (AT91C_CAST(AT91C_REG *) 0xFFF90020) // (US1) Baud Rate Generator Register +#define AT91C_US1_THR (AT91C_CAST(AT91C_REG *) 0xFFF9001C) // (US1) Transmitter Holding Register +#define AT91C_US1_VER (AT91C_CAST(AT91C_REG *) 0xFFF900FC) // (US1) VERSION Register +#define AT91C_US1_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF900F0) // (US1) US IPNAME1 REGISTER +// ========== Register definition for PDC_US2 peripheral ========== +#define AT91C_US2_RNCR (AT91C_CAST(AT91C_REG *) 0xFFF94114) // (PDC_US2) Receive Next Counter Register +#define AT91C_US2_PTCR (AT91C_CAST(AT91C_REG *) 0xFFF94120) // (PDC_US2) PDC Transfer Control Register +#define AT91C_US2_TNPR (AT91C_CAST(AT91C_REG *) 0xFFF94118) // (PDC_US2) Transmit Next Pointer Register +#define AT91C_US2_TNCR (AT91C_CAST(AT91C_REG *) 0xFFF9411C) // (PDC_US2) Transmit Next Counter Register +#define AT91C_US2_TPR (AT91C_CAST(AT91C_REG *) 0xFFF94108) // (PDC_US2) Transmit Pointer Register +#define AT91C_US2_RCR (AT91C_CAST(AT91C_REG *) 0xFFF94104) // (PDC_US2) Receive Counter Register +#define AT91C_US2_PTSR (AT91C_CAST(AT91C_REG *) 0xFFF94124) // (PDC_US2) PDC Transfer Status Register +#define AT91C_US2_TCR (AT91C_CAST(AT91C_REG *) 0xFFF9410C) // (PDC_US2) Transmit Counter Register +#define AT91C_US2_RPR (AT91C_CAST(AT91C_REG *) 0xFFF94100) // (PDC_US2) Receive Pointer Register +#define AT91C_US2_RNPR (AT91C_CAST(AT91C_REG *) 0xFFF94110) // (PDC_US2) Receive Next Pointer Register +// ========== Register definition for US2 peripheral ========== +#define AT91C_US2_TTGR (AT91C_CAST(AT91C_REG *) 0xFFF94028) // (US2) Transmitter Time-guard Register +#define AT91C_US2_IER (AT91C_CAST(AT91C_REG *) 0xFFF94008) // (US2) Interrupt Enable Register +#define AT91C_US2_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF940EC) // (US2) US ADDRSIZE REGISTER +#define AT91C_US2_NER (AT91C_CAST(AT91C_REG *) 0xFFF94044) // (US2) Nb Errors Register +#define AT91C_US2_CR (AT91C_CAST(AT91C_REG *) 0xFFF94000) // (US2) Control Register +#define AT91C_US2_IDR (AT91C_CAST(AT91C_REG *) 0xFFF9400C) // (US2) Interrupt Disable Register +#define AT91C_US2_VER (AT91C_CAST(AT91C_REG *) 0xFFF940FC) // (US2) VERSION Register +#define AT91C_US2_THR (AT91C_CAST(AT91C_REG *) 0xFFF9401C) // (US2) Transmitter Holding Register +#define AT91C_US2_BRGR (AT91C_CAST(AT91C_REG *) 0xFFF94020) // (US2) Baud Rate Generator Register +#define AT91C_US2_CSR (AT91C_CAST(AT91C_REG *) 0xFFF94014) // (US2) Channel Status Register +#define AT91C_US2_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF940F4) // (US2) US IPNAME2 REGISTER +#define AT91C_US2_IMR (AT91C_CAST(AT91C_REG *) 0xFFF94010) // (US2) Interrupt Mask Register +#define AT91C_US2_RHR (AT91C_CAST(AT91C_REG *) 0xFFF94018) // (US2) Receiver Holding Register +#define AT91C_US2_MR (AT91C_CAST(AT91C_REG *) 0xFFF94004) // (US2) Mode Register +#define AT91C_US2_FIDI (AT91C_CAST(AT91C_REG *) 0xFFF94040) // (US2) FI_DI_Ratio Register +#define AT91C_US2_MAN (AT91C_CAST(AT91C_REG *) 0xFFF94050) // (US2) Manchester Encoder Decoder Register +#define AT91C_US2_IF (AT91C_CAST(AT91C_REG *) 0xFFF9404C) // (US2) IRDA_FILTER Register +#define AT91C_US2_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF940F8) // (US2) US FEATURES REGISTER +#define AT91C_US2_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF940F0) // (US2) US IPNAME1 REGISTER +#define AT91C_US2_RTOR (AT91C_CAST(AT91C_REG *) 0xFFF94024) // (US2) Receiver Time-out Register +// ========== Register definition for PDC_US3 peripheral ========== +#define AT91C_US3_PTSR (AT91C_CAST(AT91C_REG *) 0xFFF98124) // (PDC_US3) PDC Transfer Status Register +#define AT91C_US3_TCR (AT91C_CAST(AT91C_REG *) 0xFFF9810C) // (PDC_US3) Transmit Counter Register +#define AT91C_US3_RNPR (AT91C_CAST(AT91C_REG *) 0xFFF98110) // (PDC_US3) Receive Next Pointer Register +#define AT91C_US3_RNCR (AT91C_CAST(AT91C_REG *) 0xFFF98114) // (PDC_US3) Receive Next Counter Register +#define AT91C_US3_TNPR (AT91C_CAST(AT91C_REG *) 0xFFF98118) // (PDC_US3) Transmit Next Pointer Register +#define AT91C_US3_RPR (AT91C_CAST(AT91C_REG *) 0xFFF98100) // (PDC_US3) Receive Pointer Register +#define AT91C_US3_TPR (AT91C_CAST(AT91C_REG *) 0xFFF98108) // (PDC_US3) Transmit Pointer Register +#define AT91C_US3_RCR (AT91C_CAST(AT91C_REG *) 0xFFF98104) // (PDC_US3) Receive Counter Register +#define AT91C_US3_TNCR (AT91C_CAST(AT91C_REG *) 0xFFF9811C) // (PDC_US3) Transmit Next Counter Register +#define AT91C_US3_PTCR (AT91C_CAST(AT91C_REG *) 0xFFF98120) // (PDC_US3) PDC Transfer Control Register +// ========== Register definition for US3 peripheral ========== +#define AT91C_US3_VER (AT91C_CAST(AT91C_REG *) 0xFFF980FC) // (US3) VERSION Register +#define AT91C_US3_BRGR (AT91C_CAST(AT91C_REG *) 0xFFF98020) // (US3) Baud Rate Generator Register +#define AT91C_US3_TTGR (AT91C_CAST(AT91C_REG *) 0xFFF98028) // (US3) Transmitter Time-guard Register +#define AT91C_US3_RTOR (AT91C_CAST(AT91C_REG *) 0xFFF98024) // (US3) Receiver Time-out Register +#define AT91C_US3_MAN (AT91C_CAST(AT91C_REG *) 0xFFF98050) // (US3) Manchester Encoder Decoder Register +#define AT91C_US3_NER (AT91C_CAST(AT91C_REG *) 0xFFF98044) // (US3) Nb Errors Register +#define AT91C_US3_CR (AT91C_CAST(AT91C_REG *) 0xFFF98000) // (US3) Control Register +#define AT91C_US3_IDR (AT91C_CAST(AT91C_REG *) 0xFFF9800C) // (US3) Interrupt Disable Register +#define AT91C_US3_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF980EC) // (US3) US ADDRSIZE REGISTER +#define AT91C_US3_CSR (AT91C_CAST(AT91C_REG *) 0xFFF98014) // (US3) Channel Status Register +#define AT91C_US3_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF980F4) // (US3) US IPNAME2 REGISTER +#define AT91C_US3_IER (AT91C_CAST(AT91C_REG *) 0xFFF98008) // (US3) Interrupt Enable Register +#define AT91C_US3_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF980F8) // (US3) US FEATURES REGISTER +#define AT91C_US3_MR (AT91C_CAST(AT91C_REG *) 0xFFF98004) // (US3) Mode Register +#define AT91C_US3_IF (AT91C_CAST(AT91C_REG *) 0xFFF9804C) // (US3) IRDA_FILTER Register +#define AT91C_US3_THR (AT91C_CAST(AT91C_REG *) 0xFFF9801C) // (US3) Transmitter Holding Register +#define AT91C_US3_IMR (AT91C_CAST(AT91C_REG *) 0xFFF98010) // (US3) Interrupt Mask Register +#define AT91C_US3_FIDI (AT91C_CAST(AT91C_REG *) 0xFFF98040) // (US3) FI_DI_Ratio Register +#define AT91C_US3_RHR (AT91C_CAST(AT91C_REG *) 0xFFF98018) // (US3) Receiver Holding Register +#define AT91C_US3_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF980F0) // (US3) US IPNAME1 REGISTER +// ========== Register definition for PDC_SSC0 peripheral ========== +#define AT91C_SSC0_TNPR (AT91C_CAST(AT91C_REG *) 0xFFF9C118) // (PDC_SSC0) Transmit Next Pointer Register +#define AT91C_SSC0_PTSR (AT91C_CAST(AT91C_REG *) 0xFFF9C124) // (PDC_SSC0) PDC Transfer Status Register +#define AT91C_SSC0_TNCR (AT91C_CAST(AT91C_REG *) 0xFFF9C11C) // (PDC_SSC0) Transmit Next Counter Register +#define AT91C_SSC0_RNCR (AT91C_CAST(AT91C_REG *) 0xFFF9C114) // (PDC_SSC0) Receive Next Counter Register +#define AT91C_SSC0_TPR (AT91C_CAST(AT91C_REG *) 0xFFF9C108) // (PDC_SSC0) Transmit Pointer Register +#define AT91C_SSC0_RCR (AT91C_CAST(AT91C_REG *) 0xFFF9C104) // (PDC_SSC0) Receive Counter Register +#define AT91C_SSC0_PTCR (AT91C_CAST(AT91C_REG *) 0xFFF9C120) // (PDC_SSC0) PDC Transfer Control Register +#define AT91C_SSC0_RNPR (AT91C_CAST(AT91C_REG *) 0xFFF9C110) // (PDC_SSC0) Receive Next Pointer Register +#define AT91C_SSC0_TCR (AT91C_CAST(AT91C_REG *) 0xFFF9C10C) // (PDC_SSC0) Transmit Counter Register +#define AT91C_SSC0_RPR (AT91C_CAST(AT91C_REG *) 0xFFF9C100) // (PDC_SSC0) Receive Pointer Register +// ========== Register definition for SSC0 peripheral ========== +#define AT91C_SSC0_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF9C0F4) // (SSC0) SSC IPNAME2 REGISTER +#define AT91C_SSC0_SR (AT91C_CAST(AT91C_REG *) 0xFFF9C040) // (SSC0) Status Register +#define AT91C_SSC0_TSHR (AT91C_CAST(AT91C_REG *) 0xFFF9C034) // (SSC0) Transmit Sync Holding Register +#define AT91C_SSC0_TCMR (AT91C_CAST(AT91C_REG *) 0xFFF9C018) // (SSC0) Transmit Clock Mode Register +#define AT91C_SSC0_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF9C0EC) // (SSC0) SSC ADDRSIZE REGISTER +#define AT91C_SSC0_IMR (AT91C_CAST(AT91C_REG *) 0xFFF9C04C) // (SSC0) Interrupt Mask Register +#define AT91C_SSC0_IDR (AT91C_CAST(AT91C_REG *) 0xFFF9C048) // (SSC0) Interrupt Disable Register +#define AT91C_SSC0_CR (AT91C_CAST(AT91C_REG *) 0xFFF9C000) // (SSC0) Control Register +#define AT91C_SSC0_VER (AT91C_CAST(AT91C_REG *) 0xFFF9C0FC) // (SSC0) Version Register +#define AT91C_SSC0_RHR (AT91C_CAST(AT91C_REG *) 0xFFF9C020) // (SSC0) Receive Holding Register +#define AT91C_SSC0_THR (AT91C_CAST(AT91C_REG *) 0xFFF9C024) // (SSC0) Transmit Holding Register +#define AT91C_SSC0_CMR (AT91C_CAST(AT91C_REG *) 0xFFF9C004) // (SSC0) Clock Mode Register +#define AT91C_SSC0_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFF9C0F8) // (SSC0) SSC FEATURES REGISTER +#define AT91C_SSC0_RCMR (AT91C_CAST(AT91C_REG *) 0xFFF9C010) // (SSC0) Receive Clock ModeRegister +#define AT91C_SSC0_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF9C0F0) // (SSC0) SSC IPNAME1 REGISTER +#define AT91C_SSC0_RSHR (AT91C_CAST(AT91C_REG *) 0xFFF9C030) // (SSC0) Receive Sync Holding Register +#define AT91C_SSC0_IER (AT91C_CAST(AT91C_REG *) 0xFFF9C044) // (SSC0) Interrupt Enable Register +#define AT91C_SSC0_TFMR (AT91C_CAST(AT91C_REG *) 0xFFF9C01C) // (SSC0) Transmit Frame Mode Register +#define AT91C_SSC0_RFMR (AT91C_CAST(AT91C_REG *) 0xFFF9C014) // (SSC0) Receive Frame Mode Register +// ========== Register definition for PDC_SSC1 peripheral ========== +#define AT91C_SSC1_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFA0110) // (PDC_SSC1) Receive Next Pointer Register +#define AT91C_SSC1_TCR (AT91C_CAST(AT91C_REG *) 0xFFFA010C) // (PDC_SSC1) Transmit Counter Register +#define AT91C_SSC1_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFA011C) // (PDC_SSC1) Transmit Next Counter Register +#define AT91C_SSC1_RCR (AT91C_CAST(AT91C_REG *) 0xFFFA0104) // (PDC_SSC1) Receive Counter Register +#define AT91C_SSC1_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFA0114) // (PDC_SSC1) Receive Next Counter Register +#define AT91C_SSC1_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFA0120) // (PDC_SSC1) PDC Transfer Control Register +#define AT91C_SSC1_TPR (AT91C_CAST(AT91C_REG *) 0xFFFA0108) // (PDC_SSC1) Transmit Pointer Register +#define AT91C_SSC1_RPR (AT91C_CAST(AT91C_REG *) 0xFFFA0100) // (PDC_SSC1) Receive Pointer Register +#define AT91C_SSC1_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFA0124) // (PDC_SSC1) PDC Transfer Status Register +#define AT91C_SSC1_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFA0118) // (PDC_SSC1) Transmit Next Pointer Register +// ========== Register definition for SSC1 peripheral ========== +#define AT91C_SSC1_SR (AT91C_CAST(AT91C_REG *) 0xFFFA0040) // (SSC1) Status Register +#define AT91C_SSC1_TFMR (AT91C_CAST(AT91C_REG *) 0xFFFA001C) // (SSC1) Transmit Frame Mode Register +#define AT91C_SSC1_IPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFFA00F0) // (SSC1) SSC IPNAME1 REGISTER +#define AT91C_SSC1_CMR (AT91C_CAST(AT91C_REG *) 0xFFFA0004) // (SSC1) Clock Mode Register +#define AT91C_SSC1_THR (AT91C_CAST(AT91C_REG *) 0xFFFA0024) // (SSC1) Transmit Holding Register +#define AT91C_SSC1_FEATURES (AT91C_CAST(AT91C_REG *) 0xFFFA00F8) // (SSC1) SSC FEATURES REGISTER +#define AT91C_SSC1_TSHR (AT91C_CAST(AT91C_REG *) 0xFFFA0034) // (SSC1) Transmit Sync Holding Register +#define AT91C_SSC1_RCMR (AT91C_CAST(AT91C_REG *) 0xFFFA0010) // (SSC1) Receive Clock ModeRegister +#define AT91C_SSC1_RHR (AT91C_CAST(AT91C_REG *) 0xFFFA0020) // (SSC1) Receive Holding Register +#define AT91C_SSC1_VER (AT91C_CAST(AT91C_REG *) 0xFFFA00FC) // (SSC1) Version Register +#define AT91C_SSC1_TCMR (AT91C_CAST(AT91C_REG *) 0xFFFA0018) // (SSC1) Transmit Clock Mode Register +#define AT91C_SSC1_CR (AT91C_CAST(AT91C_REG *) 0xFFFA0000) // (SSC1) Control Register +#define AT91C_SSC1_RSHR (AT91C_CAST(AT91C_REG *) 0xFFFA0030) // (SSC1) Receive Sync Holding Register +#define AT91C_SSC1_IER (AT91C_CAST(AT91C_REG *) 0xFFFA0044) // (SSC1) Interrupt Enable Register +#define AT91C_SSC1_ADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFFA00EC) // (SSC1) SSC ADDRSIZE REGISTER +#define AT91C_SSC1_RFMR (AT91C_CAST(AT91C_REG *) 0xFFFA0014) // (SSC1) Receive Frame Mode Register +#define AT91C_SSC1_IMR (AT91C_CAST(AT91C_REG *) 0xFFFA004C) // (SSC1) Interrupt Mask Register +#define AT91C_SSC1_IDR (AT91C_CAST(AT91C_REG *) 0xFFFA0048) // (SSC1) Interrupt Disable Register +#define AT91C_SSC1_IPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFFA00F4) // (SSC1) SSC IPNAME2 REGISTER +// ========== Register definition for PWMC_CH0 peripheral ========== +#define AT91C_PWMC_CH0_CCNTR (AT91C_CAST(AT91C_REG *) 0xFFFB820C) // (PWMC_CH0) Channel Counter Register +#define AT91C_PWMC_CH0_CPRDR (AT91C_CAST(AT91C_REG *) 0xFFFB8208) // (PWMC_CH0) Channel Period Register +#define AT91C_PWMC_CH0_CUPDR (AT91C_CAST(AT91C_REG *) 0xFFFB8210) // (PWMC_CH0) Channel Update Register +#define AT91C_PWMC_CH0_CDTYR (AT91C_CAST(AT91C_REG *) 0xFFFB8204) // (PWMC_CH0) Channel Duty Cycle Register +#define AT91C_PWMC_CH0_CMR (AT91C_CAST(AT91C_REG *) 0xFFFB8200) // (PWMC_CH0) Channel Mode Register +#define AT91C_PWMC_CH0_Reserved (AT91C_CAST(AT91C_REG *) 0xFFFB8214) // (PWMC_CH0) Reserved +// ========== Register definition for PWMC_CH1 peripheral ========== +#define AT91C_PWMC_CH1_CCNTR (AT91C_CAST(AT91C_REG *) 0xFFFB822C) // (PWMC_CH1) Channel Counter Register +#define AT91C_PWMC_CH1_CDTYR (AT91C_CAST(AT91C_REG *) 0xFFFB8224) // (PWMC_CH1) Channel Duty Cycle Register +#define AT91C_PWMC_CH1_CMR (AT91C_CAST(AT91C_REG *) 0xFFFB8220) // (PWMC_CH1) Channel Mode Register +#define AT91C_PWMC_CH1_CPRDR (AT91C_CAST(AT91C_REG *) 0xFFFB8228) // (PWMC_CH1) Channel Period Register +#define AT91C_PWMC_CH1_Reserved (AT91C_CAST(AT91C_REG *) 0xFFFB8234) // (PWMC_CH1) Reserved +#define AT91C_PWMC_CH1_CUPDR (AT91C_CAST(AT91C_REG *) 0xFFFB8230) // (PWMC_CH1) Channel Update Register +// ========== Register definition for PWMC_CH2 peripheral ========== +#define AT91C_PWMC_CH2_CUPDR (AT91C_CAST(AT91C_REG *) 0xFFFB8250) // (PWMC_CH2) Channel Update Register +#define AT91C_PWMC_CH2_CMR (AT91C_CAST(AT91C_REG *) 0xFFFB8240) // (PWMC_CH2) Channel Mode Register +#define AT91C_PWMC_CH2_Reserved (AT91C_CAST(AT91C_REG *) 0xFFFB8254) // (PWMC_CH2) Reserved +#define AT91C_PWMC_CH2_CPRDR (AT91C_CAST(AT91C_REG *) 0xFFFB8248) // (PWMC_CH2) Channel Period Register +#define AT91C_PWMC_CH2_CDTYR (AT91C_CAST(AT91C_REG *) 0xFFFB8244) // (PWMC_CH2) Channel Duty Cycle Register +#define AT91C_PWMC_CH2_CCNTR (AT91C_CAST(AT91C_REG *) 0xFFFB824C) // (PWMC_CH2) Channel Counter Register +// ========== Register definition for PWMC_CH3 peripheral ========== +#define AT91C_PWMC_CH3_CPRDR (AT91C_CAST(AT91C_REG *) 0xFFFB8268) // (PWMC_CH3) Channel Period Register +#define AT91C_PWMC_CH3_Reserved (AT91C_CAST(AT91C_REG *) 0xFFFB8274) // (PWMC_CH3) Reserved +#define AT91C_PWMC_CH3_CUPDR (AT91C_CAST(AT91C_REG *) 0xFFFB8270) // (PWMC_CH3) Channel Update Register +#define AT91C_PWMC_CH3_CDTYR (AT91C_CAST(AT91C_REG *) 0xFFFB8264) // (PWMC_CH3) Channel Duty Cycle Register +#define AT91C_PWMC_CH3_CCNTR (AT91C_CAST(AT91C_REG *) 0xFFFB826C) // (PWMC_CH3) Channel Counter Register +#define AT91C_PWMC_CH3_CMR (AT91C_CAST(AT91C_REG *) 0xFFFB8260) // (PWMC_CH3) Channel Mode Register +// ========== Register definition for PWMC peripheral ========== +#define AT91C_PWMC_IDR (AT91C_CAST(AT91C_REG *) 0xFFFB8014) // (PWMC) PWMC Interrupt Disable Register +#define AT91C_PWMC_MR (AT91C_CAST(AT91C_REG *) 0xFFFB8000) // (PWMC) PWMC Mode Register +#define AT91C_PWMC_VR (AT91C_CAST(AT91C_REG *) 0xFFFB80FC) // (PWMC) PWMC Version Register +#define AT91C_PWMC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFB8018) // (PWMC) PWMC Interrupt Mask Register +#define AT91C_PWMC_SR (AT91C_CAST(AT91C_REG *) 0xFFFB800C) // (PWMC) PWMC Status Register +#define AT91C_PWMC_ISR (AT91C_CAST(AT91C_REG *) 0xFFFB801C) // (PWMC) PWMC Interrupt Status Register +#define AT91C_PWMC_ENA (AT91C_CAST(AT91C_REG *) 0xFFFB8004) // (PWMC) PWMC Enable Register +#define AT91C_PWMC_IER (AT91C_CAST(AT91C_REG *) 0xFFFB8010) // (PWMC) PWMC Interrupt Enable Register +#define AT91C_PWMC_DIS (AT91C_CAST(AT91C_REG *) 0xFFFB8008) // (PWMC) PWMC Disable Register +// ========== Register definition for PDC_SPI0 peripheral ========== +#define AT91C_SPI0_TPR (AT91C_CAST(AT91C_REG *) 0xFFFA4108) // (PDC_SPI0) Transmit Pointer Register +#define AT91C_SPI0_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFA4120) // (PDC_SPI0) PDC Transfer Control Register +#define AT91C_SPI0_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFA4110) // (PDC_SPI0) Receive Next Pointer Register +#define AT91C_SPI0_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFA411C) // (PDC_SPI0) Transmit Next Counter Register +#define AT91C_SPI0_TCR (AT91C_CAST(AT91C_REG *) 0xFFFA410C) // (PDC_SPI0) Transmit Counter Register +#define AT91C_SPI0_RCR (AT91C_CAST(AT91C_REG *) 0xFFFA4104) // (PDC_SPI0) Receive Counter Register +#define AT91C_SPI0_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFA4114) // (PDC_SPI0) Receive Next Counter Register +#define AT91C_SPI0_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFA4118) // (PDC_SPI0) Transmit Next Pointer Register +#define AT91C_SPI0_RPR (AT91C_CAST(AT91C_REG *) 0xFFFA4100) // (PDC_SPI0) Receive Pointer Register +#define AT91C_SPI0_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFA4124) // (PDC_SPI0) PDC Transfer Status Register +// ========== Register definition for PDC_SPI1 peripheral ========== +#define AT91C_SPI1_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFA8114) // (PDC_SPI1) Receive Next Counter Register +#define AT91C_SPI1_TCR (AT91C_CAST(AT91C_REG *) 0xFFFA810C) // (PDC_SPI1) Transmit Counter Register +#define AT91C_SPI1_RCR (AT91C_CAST(AT91C_REG *) 0xFFFA8104) // (PDC_SPI1) Receive Counter Register +#define AT91C_SPI1_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFA8118) // (PDC_SPI1) Transmit Next Pointer Register +#define AT91C_SPI1_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFA8110) // (PDC_SPI1) Receive Next Pointer Register +#define AT91C_SPI1_RPR (AT91C_CAST(AT91C_REG *) 0xFFFA8100) // (PDC_SPI1) Receive Pointer Register +#define AT91C_SPI1_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFA811C) // (PDC_SPI1) Transmit Next Counter Register +#define AT91C_SPI1_TPR (AT91C_CAST(AT91C_REG *) 0xFFFA8108) // (PDC_SPI1) Transmit Pointer Register +#define AT91C_SPI1_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFA8124) // (PDC_SPI1) PDC Transfer Status Register +#define AT91C_SPI1_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFA8120) // (PDC_SPI1) PDC Transfer Control Register +// ========== Register definition for SPI0 peripheral ========== +#define AT91C_SPI0_MR (AT91C_CAST(AT91C_REG *) 0xFFFA4004) // (SPI0) Mode Register +#define AT91C_SPI0_RDR (AT91C_CAST(AT91C_REG *) 0xFFFA4008) // (SPI0) Receive Data Register +#define AT91C_SPI0_CR (AT91C_CAST(AT91C_REG *) 0xFFFA4000) // (SPI0) Control Register +#define AT91C_SPI0_IER (AT91C_CAST(AT91C_REG *) 0xFFFA4014) // (SPI0) Interrupt Enable Register +#define AT91C_SPI0_TDR (AT91C_CAST(AT91C_REG *) 0xFFFA400C) // (SPI0) Transmit Data Register +#define AT91C_SPI0_IDR (AT91C_CAST(AT91C_REG *) 0xFFFA4018) // (SPI0) Interrupt Disable Register +#define AT91C_SPI0_CSR (AT91C_CAST(AT91C_REG *) 0xFFFA4030) // (SPI0) Chip Select Register +#define AT91C_SPI0_SR (AT91C_CAST(AT91C_REG *) 0xFFFA4010) // (SPI0) Status Register +#define AT91C_SPI0_IMR (AT91C_CAST(AT91C_REG *) 0xFFFA401C) // (SPI0) Interrupt Mask Register +// ========== Register definition for SPI1 peripheral ========== +#define AT91C_SPI1_CSR (AT91C_CAST(AT91C_REG *) 0xFFFA8030) // (SPI1) Chip Select Register +#define AT91C_SPI1_IER (AT91C_CAST(AT91C_REG *) 0xFFFA8014) // (SPI1) Interrupt Enable Register +#define AT91C_SPI1_RDR (AT91C_CAST(AT91C_REG *) 0xFFFA8008) // (SPI1) Receive Data Register +#define AT91C_SPI1_IDR (AT91C_CAST(AT91C_REG *) 0xFFFA8018) // (SPI1) Interrupt Disable Register +#define AT91C_SPI1_MR (AT91C_CAST(AT91C_REG *) 0xFFFA8004) // (SPI1) Mode Register +#define AT91C_SPI1_CR (AT91C_CAST(AT91C_REG *) 0xFFFA8000) // (SPI1) Control Register +#define AT91C_SPI1_SR (AT91C_CAST(AT91C_REG *) 0xFFFA8010) // (SPI1) Status Register +#define AT91C_SPI1_TDR (AT91C_CAST(AT91C_REG *) 0xFFFA800C) // (SPI1) Transmit Data Register +#define AT91C_SPI1_IMR (AT91C_CAST(AT91C_REG *) 0xFFFA801C) // (SPI1) Interrupt Mask Register +// ========== Register definition for PDC_TSADC peripheral ========== +#define AT91C_TSADC_TCR (AT91C_CAST(AT91C_REG *) 0xFFFB010C) // (PDC_TSADC) Transmit Counter Register +#define AT91C_TSADC_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFB0120) // (PDC_TSADC) PDC Transfer Control Register +#define AT91C_TSADC_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFB0114) // (PDC_TSADC) Receive Next Counter Register +#define AT91C_TSADC_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFB0124) // (PDC_TSADC) PDC Transfer Status Register +#define AT91C_TSADC_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFB011C) // (PDC_TSADC) Transmit Next Counter Register +#define AT91C_TSADC_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFB0110) // (PDC_TSADC) Receive Next Pointer Register +#define AT91C_TSADC_RCR (AT91C_CAST(AT91C_REG *) 0xFFFB0104) // (PDC_TSADC) Receive Counter Register +#define AT91C_TSADC_TPR (AT91C_CAST(AT91C_REG *) 0xFFFB0108) // (PDC_TSADC) Transmit Pointer Register +#define AT91C_TSADC_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFB0118) // (PDC_TSADC) Transmit Next Pointer Register +#define AT91C_TSADC_RPR (AT91C_CAST(AT91C_REG *) 0xFFFB0100) // (PDC_TSADC) Receive Pointer Register +// ========== Register definition for TSADC peripheral ========== +#define AT91C_TSADC_CHSR (AT91C_CAST(AT91C_REG *) 0xFFFB0018) // (TSADC) Channel Status Register +#define AT91C_TSADC_CDR5 (AT91C_CAST(AT91C_REG *) 0xFFFB0044) // (TSADC) Channel Data Register 5 +#define AT91C_TSADC_CR (AT91C_CAST(AT91C_REG *) 0xFFFB0000) // (TSADC) Control Register +#define AT91C_TSADC_IMR (AT91C_CAST(AT91C_REG *) 0xFFFB002C) // (TSADC) Interrupt Mask Register +#define AT91C_TSADC_CHDR (AT91C_CAST(AT91C_REG *) 0xFFFB0014) // (TSADC) Channel Disable Register +#define AT91C_TSADC_LCDR (AT91C_CAST(AT91C_REG *) 0xFFFB0020) // (TSADC) Last Converted Register +#define AT91C_TSADC_IER (AT91C_CAST(AT91C_REG *) 0xFFFB0024) // (TSADC) Interrupt Enable Register +#define AT91C_TSADC_TSR (AT91C_CAST(AT91C_REG *) 0xFFFB000C) // (TSADC) Touch Screen Register +#define AT91C_TSADC_CDR2 (AT91C_CAST(AT91C_REG *) 0xFFFB0038) // (TSADC) Channel Data Register 2 +#define AT91C_TSADC_CDR4 (AT91C_CAST(AT91C_REG *) 0xFFFB0040) // (TSADC) Channel Data Register 4 +#define AT91C_TSADC_CHER (AT91C_CAST(AT91C_REG *) 0xFFFB0010) // (TSADC) Channel Enable Register +#define AT91C_TSADC_TRGR (AT91C_CAST(AT91C_REG *) 0xFFFB0008) // (TSADC) Trigger Register +#define AT91C_TSADC_CDR3 (AT91C_CAST(AT91C_REG *) 0xFFFB003C) // (TSADC) Channel Data Register 3 +#define AT91C_TSADC_SR (AT91C_CAST(AT91C_REG *) 0xFFFB001C) // (TSADC) Status Register +#define AT91C_TSADC_CDR0 (AT91C_CAST(AT91C_REG *) 0xFFFB0030) // (TSADC) Channel Data Register 0 +#define AT91C_TSADC_CDR6 (AT91C_CAST(AT91C_REG *) 0xFFFB0048) // (TSADC) Channel Data Register 6 +#define AT91C_TSADC_IDR (AT91C_CAST(AT91C_REG *) 0xFFFB0028) // (TSADC) Interrupt Disable Register +#define AT91C_TSADC_MR (AT91C_CAST(AT91C_REG *) 0xFFFB0004) // (TSADC) Mode Register +#define AT91C_TSADC_CDR7 (AT91C_CAST(AT91C_REG *) 0xFFFB004C) // (TSADC) Channel Data Register 7 +#define AT91C_TSADC_CDR1 (AT91C_CAST(AT91C_REG *) 0xFFFB0034) // (TSADC) Channel Data Register 1 +// ========== Register definition for UDPHS_EPTFIFO peripheral ========== +#define AT91C_UDPHS_EPTFIFO_READEPT3 (AT91C_CAST(AT91C_REG *) 0x00630000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 3 +#define AT91C_UDPHS_EPTFIFO_READEPT5 (AT91C_CAST(AT91C_REG *) 0x00650000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 5 +#define AT91C_UDPHS_EPTFIFO_READEPT1 (AT91C_CAST(AT91C_REG *) 0x00610000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 1 +#define AT91C_UDPHS_EPTFIFO_READEPT0 (AT91C_CAST(AT91C_REG *) 0x00600000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 0 +#define AT91C_UDPHS_EPTFIFO_READEPT6 (AT91C_CAST(AT91C_REG *) 0x00660000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 6 +#define AT91C_UDPHS_EPTFIFO_READEPT2 (AT91C_CAST(AT91C_REG *) 0x00620000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 2 +#define AT91C_UDPHS_EPTFIFO_READEPT4 (AT91C_CAST(AT91C_REG *) 0x00640000) // (UDPHS_EPTFIFO) FIFO Endpoint Data Register 4 +// ========== Register definition for UDPHS_EPT_0 peripheral ========== +#define AT91C_UDPHS_EPT_0_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF7811C) // (UDPHS_EPT_0) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_0_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF7810C) // (UDPHS_EPT_0) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_0_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF78108) // (UDPHS_EPT_0) UDPHS Endpoint Control Disable Register +#define AT91C_UDPHS_EPT_0_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF78100) // (UDPHS_EPT_0) UDPHS Endpoint Config Register +#define AT91C_UDPHS_EPT_0_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF78118) // (UDPHS_EPT_0) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_0_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF78114) // (UDPHS_EPT_0) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_0_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF78104) // (UDPHS_EPT_0) UDPHS Endpoint Control Enable Register +// ========== Register definition for UDPHS_EPT_1 peripheral ========== +#define AT91C_UDPHS_EPT_1_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF78124) // (UDPHS_EPT_1) UDPHS Endpoint Control Enable Register +#define AT91C_UDPHS_EPT_1_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF78120) // (UDPHS_EPT_1) UDPHS Endpoint Config Register +#define AT91C_UDPHS_EPT_1_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF7812C) // (UDPHS_EPT_1) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_1_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF7813C) // (UDPHS_EPT_1) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_1_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF78138) // (UDPHS_EPT_1) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_1_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF78134) // (UDPHS_EPT_1) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_1_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF78128) // (UDPHS_EPT_1) UDPHS Endpoint Control Disable Register +// ========== Register definition for UDPHS_EPT_2 peripheral ========== +#define AT91C_UDPHS_EPT_2_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF78158) // (UDPHS_EPT_2) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_2_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF78148) // (UDPHS_EPT_2) UDPHS Endpoint Control Disable Register +#define AT91C_UDPHS_EPT_2_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF7815C) // (UDPHS_EPT_2) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_2_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF78154) // (UDPHS_EPT_2) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_2_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF7814C) // (UDPHS_EPT_2) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_2_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF78140) // (UDPHS_EPT_2) UDPHS Endpoint Config Register +#define AT91C_UDPHS_EPT_2_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF78144) // (UDPHS_EPT_2) UDPHS Endpoint Control Enable Register +// ========== Register definition for UDPHS_EPT_3 peripheral ========== +#define AT91C_UDPHS_EPT_3_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF7816C) // (UDPHS_EPT_3) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_3_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF78178) // (UDPHS_EPT_3) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_3_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF78168) // (UDPHS_EPT_3) UDPHS Endpoint Control Disable Register +#define AT91C_UDPHS_EPT_3_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF7817C) // (UDPHS_EPT_3) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_3_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF78174) // (UDPHS_EPT_3) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_3_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF78164) // (UDPHS_EPT_3) UDPHS Endpoint Control Enable Register +#define AT91C_UDPHS_EPT_3_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF78160) // (UDPHS_EPT_3) UDPHS Endpoint Config Register +// ========== Register definition for UDPHS_EPT_4 peripheral ========== +#define AT91C_UDPHS_EPT_4_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF78198) // (UDPHS_EPT_4) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_4_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF7818C) // (UDPHS_EPT_4) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_4_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF78184) // (UDPHS_EPT_4) UDPHS Endpoint Control Enable Register +#define AT91C_UDPHS_EPT_4_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF7819C) // (UDPHS_EPT_4) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_4_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF78194) // (UDPHS_EPT_4) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_4_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF78180) // (UDPHS_EPT_4) UDPHS Endpoint Config Register +#define AT91C_UDPHS_EPT_4_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF78188) // (UDPHS_EPT_4) UDPHS Endpoint Control Disable Register +// ========== Register definition for UDPHS_EPT_5 peripheral ========== +#define AT91C_UDPHS_EPT_5_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF781BC) // (UDPHS_EPT_5) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_5_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF781B8) // (UDPHS_EPT_5) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_5_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF781A4) // (UDPHS_EPT_5) UDPHS Endpoint Control Enable Register +#define AT91C_UDPHS_EPT_5_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF781B4) // (UDPHS_EPT_5) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_5_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF781A8) // (UDPHS_EPT_5) UDPHS Endpoint Control Disable Register +#define AT91C_UDPHS_EPT_5_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF781A0) // (UDPHS_EPT_5) UDPHS Endpoint Config Register +#define AT91C_UDPHS_EPT_5_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF781AC) // (UDPHS_EPT_5) UDPHS Endpoint Control Register +// ========== Register definition for UDPHS_EPT_6 peripheral ========== +#define AT91C_UDPHS_EPT_6_EPTCLRSTA (AT91C_CAST(AT91C_REG *) 0xFFF781D8) // (UDPHS_EPT_6) UDPHS Endpoint Clear Status Register +#define AT91C_UDPHS_EPT_6_EPTCTLENB (AT91C_CAST(AT91C_REG *) 0xFFF781C4) // (UDPHS_EPT_6) UDPHS Endpoint Control Enable Register +#define AT91C_UDPHS_EPT_6_EPTCTL (AT91C_CAST(AT91C_REG *) 0xFFF781CC) // (UDPHS_EPT_6) UDPHS Endpoint Control Register +#define AT91C_UDPHS_EPT_6_EPTSETSTA (AT91C_CAST(AT91C_REG *) 0xFFF781D4) // (UDPHS_EPT_6) UDPHS Endpoint Set Status Register +#define AT91C_UDPHS_EPT_6_EPTCTLDIS (AT91C_CAST(AT91C_REG *) 0xFFF781C8) // (UDPHS_EPT_6) UDPHS Endpoint Control Disable Register +#define AT91C_UDPHS_EPT_6_EPTSTA (AT91C_CAST(AT91C_REG *) 0xFFF781DC) // (UDPHS_EPT_6) UDPHS Endpoint Status Register +#define AT91C_UDPHS_EPT_6_EPTCFG (AT91C_CAST(AT91C_REG *) 0xFFF781C0) // (UDPHS_EPT_6) UDPHS Endpoint Config Register +// ========== Register definition for UDPHS_DMA_1 peripheral ========== +#define AT91C_UDPHS_DMA_1_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7831C) // (UDPHS_DMA_1) UDPHS DMA Channel Status Register +#define AT91C_UDPHS_DMA_1_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78310) // (UDPHS_DMA_1) UDPHS DMA Channel Next Descriptor Address +#define AT91C_UDPHS_DMA_1_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78318) // (UDPHS_DMA_1) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_1_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78314) // (UDPHS_DMA_1) UDPHS DMA Channel Address Register +// ========== Register definition for UDPHS_DMA_2 peripheral ========== +#define AT91C_UDPHS_DMA_2_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78328) // (UDPHS_DMA_2) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_2_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7832C) // (UDPHS_DMA_2) UDPHS DMA Channel Status Register +#define AT91C_UDPHS_DMA_2_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78324) // (UDPHS_DMA_2) UDPHS DMA Channel Address Register +#define AT91C_UDPHS_DMA_2_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78320) // (UDPHS_DMA_2) UDPHS DMA Channel Next Descriptor Address +// ========== Register definition for UDPHS_DMA_3 peripheral ========== +#define AT91C_UDPHS_DMA_3_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78334) // (UDPHS_DMA_3) UDPHS DMA Channel Address Register +#define AT91C_UDPHS_DMA_3_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78330) // (UDPHS_DMA_3) UDPHS DMA Channel Next Descriptor Address +#define AT91C_UDPHS_DMA_3_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78338) // (UDPHS_DMA_3) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_3_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7833C) // (UDPHS_DMA_3) UDPHS DMA Channel Status Register +// ========== Register definition for UDPHS_DMA_4 peripheral ========== +#define AT91C_UDPHS_DMA_4_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78340) // (UDPHS_DMA_4) UDPHS DMA Channel Next Descriptor Address +#define AT91C_UDPHS_DMA_4_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78344) // (UDPHS_DMA_4) UDPHS DMA Channel Address Register +#define AT91C_UDPHS_DMA_4_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78348) // (UDPHS_DMA_4) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_4_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7834C) // (UDPHS_DMA_4) UDPHS DMA Channel Status Register +// ========== Register definition for UDPHS_DMA_5 peripheral ========== +#define AT91C_UDPHS_DMA_5_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7835C) // (UDPHS_DMA_5) UDPHS DMA Channel Status Register +#define AT91C_UDPHS_DMA_5_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78358) // (UDPHS_DMA_5) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_5_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78350) // (UDPHS_DMA_5) UDPHS DMA Channel Next Descriptor Address +#define AT91C_UDPHS_DMA_5_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78354) // (UDPHS_DMA_5) UDPHS DMA Channel Address Register +// ========== Register definition for UDPHS_DMA_6 peripheral ========== +#define AT91C_UDPHS_DMA_6_DMANXTDSC (AT91C_CAST(AT91C_REG *) 0xFFF78360) // (UDPHS_DMA_6) UDPHS DMA Channel Next Descriptor Address +#define AT91C_UDPHS_DMA_6_DMACONTROL (AT91C_CAST(AT91C_REG *) 0xFFF78368) // (UDPHS_DMA_6) UDPHS DMA Channel Control Register +#define AT91C_UDPHS_DMA_6_DMASTATUS (AT91C_CAST(AT91C_REG *) 0xFFF7836C) // (UDPHS_DMA_6) UDPHS DMA Channel Status Register +#define AT91C_UDPHS_DMA_6_DMAADDRESS (AT91C_CAST(AT91C_REG *) 0xFFF78364) // (UDPHS_DMA_6) UDPHS DMA Channel Address Register +// ========== Register definition for UDPHS peripheral ========== +#define AT91C_UDPHS_IEN (AT91C_CAST(AT91C_REG *) 0xFFF78010) // (UDPHS) UDPHS Interrupt Enable Register +#define AT91C_UDPHS_TSTSOFCNT (AT91C_CAST(AT91C_REG *) 0xFFF780D0) // (UDPHS) UDPHS Test SOF Counter Register +#define AT91C_UDPHS_IPFEATURES (AT91C_CAST(AT91C_REG *) 0xFFF780F8) // (UDPHS) UDPHS Features Register +#define AT91C_UDPHS_TST (AT91C_CAST(AT91C_REG *) 0xFFF780E0) // (UDPHS) UDPHS Test Register +#define AT91C_UDPHS_FNUM (AT91C_CAST(AT91C_REG *) 0xFFF78004) // (UDPHS) UDPHS Frame Number Register +#define AT91C_UDPHS_TSTCNTB (AT91C_CAST(AT91C_REG *) 0xFFF780D8) // (UDPHS) UDPHS Test B Counter Register +#define AT91C_UDPHS_RIPPADDRSIZE (AT91C_CAST(AT91C_REG *) 0xFFF780EC) // (UDPHS) UDPHS PADDRSIZE Register +#define AT91C_UDPHS_INTSTA (AT91C_CAST(AT91C_REG *) 0xFFF78014) // (UDPHS) UDPHS Interrupt Status Register +#define AT91C_UDPHS_EPTRST (AT91C_CAST(AT91C_REG *) 0xFFF7801C) // (UDPHS) UDPHS Endpoints Reset Register +#define AT91C_UDPHS_TSTCNTA (AT91C_CAST(AT91C_REG *) 0xFFF780D4) // (UDPHS) UDPHS Test A Counter Register +#define AT91C_UDPHS_RIPNAME2 (AT91C_CAST(AT91C_REG *) 0xFFF780F4) // (UDPHS) UDPHS Name2 Register +#define AT91C_UDPHS_RIPNAME1 (AT91C_CAST(AT91C_REG *) 0xFFF780F0) // (UDPHS) UDPHS Name1 Register +#define AT91C_UDPHS_TSTMODREG (AT91C_CAST(AT91C_REG *) 0xFFF780DC) // (UDPHS) UDPHS Test Mode Register +#define AT91C_UDPHS_CLRINT (AT91C_CAST(AT91C_REG *) 0xFFF78018) // (UDPHS) UDPHS Clear Interrupt Register +#define AT91C_UDPHS_IPVERSION (AT91C_CAST(AT91C_REG *) 0xFFF780FC) // (UDPHS) UDPHS Version Register +#define AT91C_UDPHS_CTRL (AT91C_CAST(AT91C_REG *) 0xFFF78000) // (UDPHS) UDPHS Control Register +// ========== Register definition for PDC_AC97C peripheral ========== +#define AT91C_AC97C_PTSR (AT91C_CAST(AT91C_REG *) 0xFFFAC124) // (PDC_AC97C) PDC Transfer Status Register +#define AT91C_AC97C_RPR (AT91C_CAST(AT91C_REG *) 0xFFFAC100) // (PDC_AC97C) Receive Pointer Register +#define AT91C_AC97C_RNCR (AT91C_CAST(AT91C_REG *) 0xFFFAC114) // (PDC_AC97C) Receive Next Counter Register +#define AT91C_AC97C_RCR (AT91C_CAST(AT91C_REG *) 0xFFFAC104) // (PDC_AC97C) Receive Counter Register +#define AT91C_AC97C_PTCR (AT91C_CAST(AT91C_REG *) 0xFFFAC120) // (PDC_AC97C) PDC Transfer Control Register +#define AT91C_AC97C_TPR (AT91C_CAST(AT91C_REG *) 0xFFFAC108) // (PDC_AC97C) Transmit Pointer Register +#define AT91C_AC97C_RNPR (AT91C_CAST(AT91C_REG *) 0xFFFAC110) // (PDC_AC97C) Receive Next Pointer Register +#define AT91C_AC97C_TNPR (AT91C_CAST(AT91C_REG *) 0xFFFAC118) // (PDC_AC97C) Transmit Next Pointer Register +#define AT91C_AC97C_TCR (AT91C_CAST(AT91C_REG *) 0xFFFAC10C) // (PDC_AC97C) Transmit Counter Register +#define AT91C_AC97C_TNCR (AT91C_CAST(AT91C_REG *) 0xFFFAC11C) // (PDC_AC97C) Transmit Next Counter Register +// ========== Register definition for AC97C peripheral ========== +#define AT91C_AC97C_IER (AT91C_CAST(AT91C_REG *) 0xFFFAC054) // (AC97C) Interrupt Enable Register +#define AT91C_AC97C_COTHR (AT91C_CAST(AT91C_REG *) 0xFFFAC044) // (AC97C) COdec Transmit Holding Register +#define AT91C_AC97C_IDR (AT91C_CAST(AT91C_REG *) 0xFFFAC058) // (AC97C) Interrupt Disable Register +#define AT91C_AC97C_ICA (AT91C_CAST(AT91C_REG *) 0xFFFAC010) // (AC97C) Input Channel AssignementRegister +#define AT91C_AC97C_CATHR (AT91C_CAST(AT91C_REG *) 0xFFFAC024) // (AC97C) Channel A Transmit Holding Register +#define AT91C_AC97C_CBSR (AT91C_CAST(AT91C_REG *) 0xFFFAC038) // (AC97C) Channel B Status Register +#define AT91C_AC97C_CAMR (AT91C_CAST(AT91C_REG *) 0xFFFAC02C) // (AC97C) Channel A Mode Register +#define AT91C_AC97C_SR (AT91C_CAST(AT91C_REG *) 0xFFFAC050) // (AC97C) Status Register +#define AT91C_AC97C_CBTHR (AT91C_CAST(AT91C_REG *) 0xFFFAC034) // (AC97C) Channel B Transmit Holding Register (optional) +#define AT91C_AC97C_CASR (AT91C_CAST(AT91C_REG *) 0xFFFAC028) // (AC97C) Channel A Status Register +#define AT91C_AC97C_COSR (AT91C_CAST(AT91C_REG *) 0xFFFAC048) // (AC97C) CODEC Status Register +#define AT91C_AC97C_MR (AT91C_CAST(AT91C_REG *) 0xFFFAC008) // (AC97C) Mode Register +#define AT91C_AC97C_OCA (AT91C_CAST(AT91C_REG *) 0xFFFAC014) // (AC97C) Output Channel Assignement Register +#define AT91C_AC97C_CORHR (AT91C_CAST(AT91C_REG *) 0xFFFAC040) // (AC97C) COdec Transmit Holding Register +#define AT91C_AC97C_CBRHR (AT91C_CAST(AT91C_REG *) 0xFFFAC030) // (AC97C) Channel B Receive Holding Register (optional) +#define AT91C_AC97C_IMR (AT91C_CAST(AT91C_REG *) 0xFFFAC05C) // (AC97C) Interrupt Mask Register +#define AT91C_AC97C_COMR (AT91C_CAST(AT91C_REG *) 0xFFFAC04C) // (AC97C) CODEC Mask Status Register +#define AT91C_AC97C_CARHR (AT91C_CAST(AT91C_REG *) 0xFFFAC020) // (AC97C) Channel A Receive Holding Register +#define AT91C_AC97C_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFAC0FC) // (AC97C) Version Register +#define AT91C_AC97C_CBMR (AT91C_CAST(AT91C_REG *) 0xFFFAC03C) // (AC97C) Channel B Mode Register +// ========== Register definition for LCDC peripheral ========== +#define AT91C_LCDC_MVAL (AT91C_CAST(AT91C_REG *) 0x00500818) // (LCDC) LCD Mode Toggle Rate Value Register +#define AT91C_LCDC_PWRCON (AT91C_CAST(AT91C_REG *) 0x0050083C) // (LCDC) Power Control Register +#define AT91C_LCDC_ISR (AT91C_CAST(AT91C_REG *) 0x00500854) // (LCDC) Interrupt Enable Register +#define AT91C_LCDC_FRMP1 (AT91C_CAST(AT91C_REG *) 0x00500008) // (LCDC) DMA Frame Pointer Register 1 +#define AT91C_LCDC_CTRSTVAL (AT91C_CAST(AT91C_REG *) 0x00500844) // (LCDC) Contrast Value Register +#define AT91C_LCDC_ICR (AT91C_CAST(AT91C_REG *) 0x00500858) // (LCDC) Interrupt Clear Register +#define AT91C_LCDC_TIM1 (AT91C_CAST(AT91C_REG *) 0x00500808) // (LCDC) LCD Timing Config 1 Register +#define AT91C_LCDC_DMACON (AT91C_CAST(AT91C_REG *) 0x0050001C) // (LCDC) DMA Control Register +#define AT91C_LCDC_ITR (AT91C_CAST(AT91C_REG *) 0x00500860) // (LCDC) Interrupts Test Register +#define AT91C_LCDC_IDR (AT91C_CAST(AT91C_REG *) 0x0050084C) // (LCDC) Interrupt Disable Register +#define AT91C_LCDC_DP4_7 (AT91C_CAST(AT91C_REG *) 0x00500820) // (LCDC) Dithering Pattern DP4_7 Register +#define AT91C_LCDC_DP5_7 (AT91C_CAST(AT91C_REG *) 0x0050082C) // (LCDC) Dithering Pattern DP5_7 Register +#define AT91C_LCDC_IRR (AT91C_CAST(AT91C_REG *) 0x00500864) // (LCDC) Interrupts Raw Status Register +#define AT91C_LCDC_DP3_4 (AT91C_CAST(AT91C_REG *) 0x00500830) // (LCDC) Dithering Pattern DP3_4 Register +#define AT91C_LCDC_IMR (AT91C_CAST(AT91C_REG *) 0x00500850) // (LCDC) Interrupt Mask Register +#define AT91C_LCDC_LCDFRCFG (AT91C_CAST(AT91C_REG *) 0x00500810) // (LCDC) LCD Frame Config Register +#define AT91C_LCDC_CTRSTCON (AT91C_CAST(AT91C_REG *) 0x00500840) // (LCDC) Contrast Control Register +#define AT91C_LCDC_DP1_2 (AT91C_CAST(AT91C_REG *) 0x0050081C) // (LCDC) Dithering Pattern DP1_2 Register +#define AT91C_LCDC_FRMP2 (AT91C_CAST(AT91C_REG *) 0x0050000C) // (LCDC) DMA Frame Pointer Register 2 +#define AT91C_LCDC_LCDCON1 (AT91C_CAST(AT91C_REG *) 0x00500800) // (LCDC) LCD Control 1 Register +#define AT91C_LCDC_DP4_5 (AT91C_CAST(AT91C_REG *) 0x00500834) // (LCDC) Dithering Pattern DP4_5 Register +#define AT91C_LCDC_FRMA2 (AT91C_CAST(AT91C_REG *) 0x00500014) // (LCDC) DMA Frame Address Register 2 +#define AT91C_LCDC_BA1 (AT91C_CAST(AT91C_REG *) 0x00500000) // (LCDC) DMA Base Address Register 1 +#define AT91C_LCDC_DMA2DCFG (AT91C_CAST(AT91C_REG *) 0x00500020) // (LCDC) DMA 2D addressing configuration +#define AT91C_LCDC_LUT_ENTRY (AT91C_CAST(AT91C_REG *) 0x00500C00) // (LCDC) LUT Entries Register +#define AT91C_LCDC_DP6_7 (AT91C_CAST(AT91C_REG *) 0x00500838) // (LCDC) Dithering Pattern DP6_7 Register +#define AT91C_LCDC_FRMCFG (AT91C_CAST(AT91C_REG *) 0x00500018) // (LCDC) DMA Frame Configuration Register +#define AT91C_LCDC_TIM2 (AT91C_CAST(AT91C_REG *) 0x0050080C) // (LCDC) LCD Timing Config 2 Register +#define AT91C_LCDC_DP3_5 (AT91C_CAST(AT91C_REG *) 0x00500824) // (LCDC) Dithering Pattern DP3_5 Register +#define AT91C_LCDC_FRMA1 (AT91C_CAST(AT91C_REG *) 0x00500010) // (LCDC) DMA Frame Address Register 1 +#define AT91C_LCDC_IER (AT91C_CAST(AT91C_REG *) 0x00500848) // (LCDC) Interrupt Enable Register +#define AT91C_LCDC_DP2_3 (AT91C_CAST(AT91C_REG *) 0x00500828) // (LCDC) Dithering Pattern DP2_3 Register +#define AT91C_LCDC_FIFO (AT91C_CAST(AT91C_REG *) 0x00500814) // (LCDC) LCD FIFO Register +#define AT91C_LCDC_BA2 (AT91C_CAST(AT91C_REG *) 0x00500004) // (LCDC) DMA Base Address Register 2 +#define AT91C_LCDC_LCDCON2 (AT91C_CAST(AT91C_REG *) 0x00500804) // (LCDC) LCD Control 2 Register +#define AT91C_LCDC_GPR (AT91C_CAST(AT91C_REG *) 0x0050085C) // (LCDC) General Purpose Register +// ========== Register definition for LCDC_16B_TFT peripheral ========== +#define AT91C_TFT_MVAL (AT91C_CAST(AT91C_REG *) 0x00500818) // (LCDC_16B_TFT) LCD Mode Toggle Rate Value Register +#define AT91C_TFT_PWRCON (AT91C_CAST(AT91C_REG *) 0x0050083C) // (LCDC_16B_TFT) Power Control Register +#define AT91C_TFT_ISR (AT91C_CAST(AT91C_REG *) 0x00500854) // (LCDC_16B_TFT) Interrupt Enable Register +#define AT91C_TFT_FRMP1 (AT91C_CAST(AT91C_REG *) 0x00500008) // (LCDC_16B_TFT) DMA Frame Pointer Register 1 +#define AT91C_TFT_CTRSTVAL (AT91C_CAST(AT91C_REG *) 0x00500844) // (LCDC_16B_TFT) Contrast Value Register +#define AT91C_TFT_ICR (AT91C_CAST(AT91C_REG *) 0x00500858) // (LCDC_16B_TFT) Interrupt Clear Register +#define AT91C_TFT_TIM1 (AT91C_CAST(AT91C_REG *) 0x00500808) // (LCDC_16B_TFT) LCD Timing Config 1 Register +#define AT91C_TFT_DMACON (AT91C_CAST(AT91C_REG *) 0x0050001C) // (LCDC_16B_TFT) DMA Control Register +#define AT91C_TFT_ITR (AT91C_CAST(AT91C_REG *) 0x00500860) // (LCDC_16B_TFT) Interrupts Test Register +#define AT91C_TFT_IDR (AT91C_CAST(AT91C_REG *) 0x0050084C) // (LCDC_16B_TFT) Interrupt Disable Register +#define AT91C_TFT_DP4_7 (AT91C_CAST(AT91C_REG *) 0x00500820) // (LCDC_16B_TFT) Dithering Pattern DP4_7 Register +#define AT91C_TFT_DP5_7 (AT91C_CAST(AT91C_REG *) 0x0050082C) // (LCDC_16B_TFT) Dithering Pattern DP5_7 Register +#define AT91C_TFT_IRR (AT91C_CAST(AT91C_REG *) 0x00500864) // (LCDC_16B_TFT) Interrupts Raw Status Register +#define AT91C_TFT_DP3_4 (AT91C_CAST(AT91C_REG *) 0x00500830) // (LCDC_16B_TFT) Dithering Pattern DP3_4 Register +#define AT91C_TFT_IMR (AT91C_CAST(AT91C_REG *) 0x00500850) // (LCDC_16B_TFT) Interrupt Mask Register +#define AT91C_TFT_LCDFRCFG (AT91C_CAST(AT91C_REG *) 0x00500810) // (LCDC_16B_TFT) LCD Frame Config Register +#define AT91C_TFT_CTRSTCON (AT91C_CAST(AT91C_REG *) 0x00500840) // (LCDC_16B_TFT) Contrast Control Register +#define AT91C_TFT_DP1_2 (AT91C_CAST(AT91C_REG *) 0x0050081C) // (LCDC_16B_TFT) Dithering Pattern DP1_2 Register +#define AT91C_TFT_FRMP2 (AT91C_CAST(AT91C_REG *) 0x0050000C) // (LCDC_16B_TFT) DMA Frame Pointer Register 2 +#define AT91C_TFT_LCDCON1 (AT91C_CAST(AT91C_REG *) 0x00500800) // (LCDC_16B_TFT) LCD Control 1 Register +#define AT91C_TFT_DP4_5 (AT91C_CAST(AT91C_REG *) 0x00500834) // (LCDC_16B_TFT) Dithering Pattern DP4_5 Register +#define AT91C_TFT_FRMA2 (AT91C_CAST(AT91C_REG *) 0x00500014) // (LCDC_16B_TFT) DMA Frame Address Register 2 +#define AT91C_TFT_BA1 (AT91C_CAST(AT91C_REG *) 0x00500000) // (LCDC_16B_TFT) DMA Base Address Register 1 +#define AT91C_TFT_DMA2DCFG (AT91C_CAST(AT91C_REG *) 0x00500020) // (LCDC_16B_TFT) DMA 2D addressing configuration +#define AT91C_TFT_LUT_ENTRY (AT91C_CAST(AT91C_REG *) 0x00500C00) // (LCDC_16B_TFT) LUT Entries Register +#define AT91C_TFT_DP6_7 (AT91C_CAST(AT91C_REG *) 0x00500838) // (LCDC_16B_TFT) Dithering Pattern DP6_7 Register +#define AT91C_TFT_FRMCFG (AT91C_CAST(AT91C_REG *) 0x00500018) // (LCDC_16B_TFT) DMA Frame Configuration Register +#define AT91C_TFT_TIM2 (AT91C_CAST(AT91C_REG *) 0x0050080C) // (LCDC_16B_TFT) LCD Timing Config 2 Register +#define AT91C_TFT_DP3_5 (AT91C_CAST(AT91C_REG *) 0x00500824) // (LCDC_16B_TFT) Dithering Pattern DP3_5 Register +#define AT91C_TFT_FRMA1 (AT91C_CAST(AT91C_REG *) 0x00500010) // (LCDC_16B_TFT) DMA Frame Address Register 1 +#define AT91C_TFT_IER (AT91C_CAST(AT91C_REG *) 0x00500848) // (LCDC_16B_TFT) Interrupt Enable Register +#define AT91C_TFT_DP2_3 (AT91C_CAST(AT91C_REG *) 0x00500828) // (LCDC_16B_TFT) Dithering Pattern DP2_3 Register +#define AT91C_TFT_FIFO (AT91C_CAST(AT91C_REG *) 0x00500814) // (LCDC_16B_TFT) LCD FIFO Register +#define AT91C_TFT_BA2 (AT91C_CAST(AT91C_REG *) 0x00500004) // (LCDC_16B_TFT) DMA Base Address Register 2 +#define AT91C_TFT_LCDCON2 (AT91C_CAST(AT91C_REG *) 0x00500804) // (LCDC_16B_TFT) LCD Control 2 Register +#define AT91C_TFT_GPR (AT91C_CAST(AT91C_REG *) 0x0050085C) // (LCDC_16B_TFT) General Purpose Register +// ========== Register definition for HDMA_CH_0 peripheral ========== +#define AT91C_HDMA_CH_0_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFEC5C) // (HDMA_CH_0) HDMA Reserved +#define AT91C_HDMA_CH_0_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC40) // (HDMA_CH_0) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_0_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFEC58) // (HDMA_CH_0) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_0_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFEC44) // (HDMA_CH_0) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_0_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFEC50) // (HDMA_CH_0) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_0_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFEC54) // (HDMA_CH_0) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_0_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC60) // (HDMA_CH_0) HDMA Reserved +#define AT91C_HDMA_CH_0_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFEC48) // (HDMA_CH_0) HDMA Channel Control A Register +#define AT91C_HDMA_CH_0_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFEC4C) // (HDMA_CH_0) HDMA Channel Control B Register +#define AT91C_HDMA_CH_0_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC3C) // (HDMA_CH_0) HDMA Channel Source Address Register +// ========== Register definition for HDMA_CH_1 peripheral ========== +#define AT91C_HDMA_CH_1_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC88) // (HDMA_CH_1) HDMA Reserved +#define AT91C_HDMA_CH_1_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFEC80) // (HDMA_CH_1) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_1_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFEC74) // (HDMA_CH_1) HDMA Channel Control B Register +#define AT91C_HDMA_CH_1_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC64) // (HDMA_CH_1) HDMA Channel Source Address Register +#define AT91C_HDMA_CH_1_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFEC84) // (HDMA_CH_1) HDMA Reserved +#define AT91C_HDMA_CH_1_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFEC78) // (HDMA_CH_1) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_1_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFEC6C) // (HDMA_CH_1) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_1_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC68) // (HDMA_CH_1) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_1_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFEC70) // (HDMA_CH_1) HDMA Channel Control A Register +#define AT91C_HDMA_CH_1_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFEC7C) // (HDMA_CH_1) HDMA Channel Source Picture in Picture Configuration Register +// ========== Register definition for HDMA_CH_2 peripheral ========== +#define AT91C_HDMA_CH_2_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC8C) // (HDMA_CH_2) HDMA Channel Source Address Register +#define AT91C_HDMA_CH_2_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFECAC) // (HDMA_CH_2) HDMA Reserved +#define AT91C_HDMA_CH_2_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECA8) // (HDMA_CH_2) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_2_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECA4) // (HDMA_CH_2) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_2_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC90) // (HDMA_CH_2) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_2_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFEC94) // (HDMA_CH_2) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_2_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFEC98) // (HDMA_CH_2) HDMA Channel Control A Register +#define AT91C_HDMA_CH_2_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECB0) // (HDMA_CH_2) HDMA Reserved +#define AT91C_HDMA_CH_2_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFECA0) // (HDMA_CH_2) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_2_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFEC9C) // (HDMA_CH_2) HDMA Channel Control B Register +// ========== Register definition for HDMA_CH_3 peripheral ========== +#define AT91C_HDMA_CH_3_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECCC) // (HDMA_CH_3) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_3_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFECC0) // (HDMA_CH_3) HDMA Channel Control A Register +#define AT91C_HDMA_CH_3_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECD0) // (HDMA_CH_3) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_3_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFECC4) // (HDMA_CH_3) HDMA Channel Control B Register +#define AT91C_HDMA_CH_3_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFECD4) // (HDMA_CH_3) HDMA Reserved +#define AT91C_HDMA_CH_3_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFECBC) // (HDMA_CH_3) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_3_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECD8) // (HDMA_CH_3) HDMA Reserved +#define AT91C_HDMA_CH_3_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFECC8) // (HDMA_CH_3) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_3_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECB8) // (HDMA_CH_3) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_3_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECB4) // (HDMA_CH_3) HDMA Channel Source Address Register +// ========== Register definition for HDMA_CH_4 peripheral ========== +#define AT91C_HDMA_CH_4_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFECF0) // (HDMA_CH_4) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_4_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFECFC) // (HDMA_CH_4) HDMA Reserved +#define AT91C_HDMA_CH_4_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED00) // (HDMA_CH_4) HDMA Reserved +#define AT91C_HDMA_CH_4_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECE0) // (HDMA_CH_4) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_4_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFECE8) // (HDMA_CH_4) HDMA Channel Control A Register +#define AT91C_HDMA_CH_4_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFECDC) // (HDMA_CH_4) HDMA Channel Source Address Register +#define AT91C_HDMA_CH_4_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFECEC) // (HDMA_CH_4) HDMA Channel Control B Register +#define AT91C_HDMA_CH_4_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFECE4) // (HDMA_CH_4) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_4_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECF4) // (HDMA_CH_4) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_4_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFECF8) // (HDMA_CH_4) HDMA Channel Destination Picture in Picture Configuration Register +// ========== Register definition for HDMA_CH_5 peripheral ========== +#define AT91C_HDMA_CH_5_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFED14) // (HDMA_CH_5) HDMA Channel Control B Register +#define AT91C_HDMA_CH_5_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED08) // (HDMA_CH_5) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_5_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED1C) // (HDMA_CH_5) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_5_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED0C) // (HDMA_CH_5) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_5_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED20) // (HDMA_CH_5) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_5_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFED18) // (HDMA_CH_5) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_5_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED28) // (HDMA_CH_5) HDMA Reserved +#define AT91C_HDMA_CH_5_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED04) // (HDMA_CH_5) HDMA Channel Source Address Register +#define AT91C_HDMA_CH_5_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED24) // (HDMA_CH_5) HDMA Reserved +#define AT91C_HDMA_CH_5_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFED10) // (HDMA_CH_5) HDMA Channel Control A Register +// ========== Register definition for HDMA_CH_6 peripheral ========== +#define AT91C_HDMA_CH_6_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED2C) // (HDMA_CH_6) HDMA Channel Source Address Register +#define AT91C_HDMA_CH_6_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED4C) // (HDMA_CH_6) HDMA Reserved +#define AT91C_HDMA_CH_6_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED50) // (HDMA_CH_6) HDMA Reserved +#define AT91C_HDMA_CH_6_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED44) // (HDMA_CH_6) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_6_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFED3C) // (HDMA_CH_6) HDMA Channel Control B Register +#define AT91C_HDMA_CH_6_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED34) // (HDMA_CH_6) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_6_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFED40) // (HDMA_CH_6) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_6_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED48) // (HDMA_CH_6) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_6_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED30) // (HDMA_CH_6) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_6_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFED38) // (HDMA_CH_6) HDMA Channel Control A Register +// ========== Register definition for HDMA_CH_7 peripheral ========== +#define AT91C_HDMA_CH_7_CADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED78) // (HDMA_CH_7) HDMA Reserved +#define AT91C_HDMA_CH_7_CFG (AT91C_CAST(AT91C_REG *) 0xFFFFED68) // (HDMA_CH_7) HDMA Channel Configuration Register +#define AT91C_HDMA_CH_7_DADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED58) // (HDMA_CH_7) HDMA Channel Destination Address Register +#define AT91C_HDMA_CH_7_CTRLB (AT91C_CAST(AT91C_REG *) 0xFFFFED64) // (HDMA_CH_7) HDMA Channel Control B Register +#define AT91C_HDMA_CH_7_DSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED5C) // (HDMA_CH_7) HDMA Channel Descriptor Address Register +#define AT91C_HDMA_CH_7_DPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED70) // (HDMA_CH_7) HDMA Channel Destination Picture in Picture Configuration Register +#define AT91C_HDMA_CH_7_CTRLA (AT91C_CAST(AT91C_REG *) 0xFFFFED60) // (HDMA_CH_7) HDMA Channel Control A Register +#define AT91C_HDMA_CH_7_BDSCR (AT91C_CAST(AT91C_REG *) 0xFFFFED74) // (HDMA_CH_7) HDMA Reserved +#define AT91C_HDMA_CH_7_SPIP (AT91C_CAST(AT91C_REG *) 0xFFFFED6C) // (HDMA_CH_7) HDMA Channel Source Picture in Picture Configuration Register +#define AT91C_HDMA_CH_7_SADDR (AT91C_CAST(AT91C_REG *) 0xFFFFED54) // (HDMA_CH_7) HDMA Channel Source Address Register +// ========== Register definition for HDMA peripheral ========== +#define AT91C_HDMA_EBCIDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC1C) // (HDMA) HDMA Error, Chained Buffer transfer completed and Buffer transfer completed Interrupt Disable register +#define AT91C_HDMA_LAST (AT91C_CAST(AT91C_REG *) 0xFFFFEC10) // (HDMA) HDMA Software Last Transfer Flag Register +#define AT91C_HDMA_SREQ (AT91C_CAST(AT91C_REG *) 0xFFFFEC08) // (HDMA) HDMA Software Single Request Register +#define AT91C_HDMA_RSVD0 (AT91C_CAST(AT91C_REG *) 0xFFFFEC34) // (HDMA) HDMA Reserved +#define AT91C_HDMA_EBCIER (AT91C_CAST(AT91C_REG *) 0xFFFFEC18) // (HDMA) HDMA Error, Chained Buffer transfer completed and Buffer transfer completed Interrupt Enable register +#define AT91C_HDMA_GCFG (AT91C_CAST(AT91C_REG *) 0xFFFFEC00) // (HDMA) HDMA Global Configuration Register +#define AT91C_HDMA_CHER (AT91C_CAST(AT91C_REG *) 0xFFFFEC28) // (HDMA) HDMA Channel Handler Enable Register +#define AT91C_HDMA_RSVD1 (AT91C_CAST(AT91C_REG *) 0xFFFFEC38) // (HDMA) HDMA Reserved +#define AT91C_HDMA_CHDR (AT91C_CAST(AT91C_REG *) 0xFFFFEC2C) // (HDMA) HDMA Channel Handler Disable Register +#define AT91C_HDMA_EBCIMR (AT91C_CAST(AT91C_REG *) 0xFFFFEC20) // (HDMA) HDMA Error, Chained Buffer transfer completed and Buffer transfer completed Mask Register +#define AT91C_HDMA_CREQ (AT91C_CAST(AT91C_REG *) 0xFFFFEC0C) // (HDMA) HDMA Software Chunk Transfer Request Register +#define AT91C_HDMA_SYNC (AT91C_CAST(AT91C_REG *) 0xFFFFEC14) // (HDMA) HDMA Request Synchronization Register +#define AT91C_HDMA_EN (AT91C_CAST(AT91C_REG *) 0xFFFFEC04) // (HDMA) HDMA Controller Enable Register +#define AT91C_HDMA_EBCISR (AT91C_CAST(AT91C_REG *) 0xFFFFEC24) // (HDMA) HDMA Error, Chained Buffer transfer completed and Buffer transfer completed Status Register +#define AT91C_HDMA_CHSR (AT91C_CAST(AT91C_REG *) 0xFFFFEC30) // (HDMA) HDMA Channel Handler Status Register +// ========== Register definition for HECC peripheral ========== +#define AT91C_HECC_VR (AT91C_CAST(AT91C_REG *) 0xFFFFE2FC) // (HECC) ECC Version register +#define AT91C_HECC_SR (AT91C_CAST(AT91C_REG *) 0xFFFFE208) // (HECC) ECC Status register +#define AT91C_HECC_CR (AT91C_CAST(AT91C_REG *) 0xFFFFE200) // (HECC) ECC reset register +#define AT91C_HECC_NPR (AT91C_CAST(AT91C_REG *) 0xFFFFE210) // (HECC) ECC Parity N register +#define AT91C_HECC_PR (AT91C_CAST(AT91C_REG *) 0xFFFFE20C) // (HECC) ECC Parity register +#define AT91C_HECC_MR (AT91C_CAST(AT91C_REG *) 0xFFFFE204) // (HECC) ECC Page size register +// ========== Register definition for EMACB peripheral ========== +#define AT91C_EMACB_ALE (AT91C_CAST(AT91C_REG *) 0xFFFBC054) // (EMACB) Alignment Error Register +#define AT91C_EMACB_RRE (AT91C_CAST(AT91C_REG *) 0xFFFBC06C) // (EMACB) Receive Ressource Error Register +#define AT91C_EMACB_SA4H (AT91C_CAST(AT91C_REG *) 0xFFFBC0B4) // (EMACB) Specific Address 4 Top, Last 2 bytes +#define AT91C_EMACB_TPQ (AT91C_CAST(AT91C_REG *) 0xFFFBC0BC) // (EMACB) Transmit Pause Quantum Register +#define AT91C_EMACB_RJA (AT91C_CAST(AT91C_REG *) 0xFFFBC07C) // (EMACB) Receive Jabbers Register +#define AT91C_EMACB_SA2H (AT91C_CAST(AT91C_REG *) 0xFFFBC0A4) // (EMACB) Specific Address 2 Top, Last 2 bytes +#define AT91C_EMACB_TPF (AT91C_CAST(AT91C_REG *) 0xFFFBC08C) // (EMACB) Transmitted Pause Frames Register +#define AT91C_EMACB_ROV (AT91C_CAST(AT91C_REG *) 0xFFFBC070) // (EMACB) Receive Overrun Errors Register +#define AT91C_EMACB_SA4L (AT91C_CAST(AT91C_REG *) 0xFFFBC0B0) // (EMACB) Specific Address 4 Bottom, First 4 bytes +#define AT91C_EMACB_MAN (AT91C_CAST(AT91C_REG *) 0xFFFBC034) // (EMACB) PHY Maintenance Register +#define AT91C_EMACB_TID (AT91C_CAST(AT91C_REG *) 0xFFFBC0B8) // (EMACB) Type ID Checking Register +#define AT91C_EMACB_TBQP (AT91C_CAST(AT91C_REG *) 0xFFFBC01C) // (EMACB) Transmit Buffer Queue Pointer +#define AT91C_EMACB_SA3L (AT91C_CAST(AT91C_REG *) 0xFFFBC0A8) // (EMACB) Specific Address 3 Bottom, First 4 bytes +#define AT91C_EMACB_DTF (AT91C_CAST(AT91C_REG *) 0xFFFBC058) // (EMACB) Deferred Transmission Frame Register +#define AT91C_EMACB_PTR (AT91C_CAST(AT91C_REG *) 0xFFFBC038) // (EMACB) Pause Time Register +#define AT91C_EMACB_CSE (AT91C_CAST(AT91C_REG *) 0xFFFBC068) // (EMACB) Carrier Sense Error Register +#define AT91C_EMACB_ECOL (AT91C_CAST(AT91C_REG *) 0xFFFBC060) // (EMACB) Excessive Collision Register +#define AT91C_EMACB_STE (AT91C_CAST(AT91C_REG *) 0xFFFBC084) // (EMACB) SQE Test Error Register +#define AT91C_EMACB_MCF (AT91C_CAST(AT91C_REG *) 0xFFFBC048) // (EMACB) Multiple Collision Frame Register +#define AT91C_EMACB_IER (AT91C_CAST(AT91C_REG *) 0xFFFBC028) // (EMACB) Interrupt Enable Register +#define AT91C_EMACB_ELE (AT91C_CAST(AT91C_REG *) 0xFFFBC078) // (EMACB) Excessive Length Errors Register +#define AT91C_EMACB_USRIO (AT91C_CAST(AT91C_REG *) 0xFFFBC0C0) // (EMACB) USER Input/Output Register +#define AT91C_EMACB_PFR (AT91C_CAST(AT91C_REG *) 0xFFFBC03C) // (EMACB) Pause Frames received Register +#define AT91C_EMACB_FCSE (AT91C_CAST(AT91C_REG *) 0xFFFBC050) // (EMACB) Frame Check Sequence Error Register +#define AT91C_EMACB_SA1L (AT91C_CAST(AT91C_REG *) 0xFFFBC098) // (EMACB) Specific Address 1 Bottom, First 4 bytes +#define AT91C_EMACB_NCR (AT91C_CAST(AT91C_REG *) 0xFFFBC000) // (EMACB) Network Control Register +#define AT91C_EMACB_HRT (AT91C_CAST(AT91C_REG *) 0xFFFBC094) // (EMACB) Hash Address Top[63:32] +#define AT91C_EMACB_NCFGR (AT91C_CAST(AT91C_REG *) 0xFFFBC004) // (EMACB) Network Configuration Register +#define AT91C_EMACB_SCF (AT91C_CAST(AT91C_REG *) 0xFFFBC044) // (EMACB) Single Collision Frame Register +#define AT91C_EMACB_LCOL (AT91C_CAST(AT91C_REG *) 0xFFFBC05C) // (EMACB) Late Collision Register +#define AT91C_EMACB_SA3H (AT91C_CAST(AT91C_REG *) 0xFFFBC0AC) // (EMACB) Specific Address 3 Top, Last 2 bytes +#define AT91C_EMACB_HRB (AT91C_CAST(AT91C_REG *) 0xFFFBC090) // (EMACB) Hash Address Bottom[31:0] +#define AT91C_EMACB_ISR (AT91C_CAST(AT91C_REG *) 0xFFFBC024) // (EMACB) Interrupt Status Register +#define AT91C_EMACB_IMR (AT91C_CAST(AT91C_REG *) 0xFFFBC030) // (EMACB) Interrupt Mask Register +#define AT91C_EMACB_WOL (AT91C_CAST(AT91C_REG *) 0xFFFBC0C4) // (EMACB) Wake On LAN Register +#define AT91C_EMACB_USF (AT91C_CAST(AT91C_REG *) 0xFFFBC080) // (EMACB) Undersize Frames Register +#define AT91C_EMACB_TSR (AT91C_CAST(AT91C_REG *) 0xFFFBC014) // (EMACB) Transmit Status Register +#define AT91C_EMACB_FRO (AT91C_CAST(AT91C_REG *) 0xFFFBC04C) // (EMACB) Frames Received OK Register +#define AT91C_EMACB_IDR (AT91C_CAST(AT91C_REG *) 0xFFFBC02C) // (EMACB) Interrupt Disable Register +#define AT91C_EMACB_SA1H (AT91C_CAST(AT91C_REG *) 0xFFFBC09C) // (EMACB) Specific Address 1 Top, Last 2 bytes +#define AT91C_EMACB_RLE (AT91C_CAST(AT91C_REG *) 0xFFFBC088) // (EMACB) Receive Length Field Mismatch Register +#define AT91C_EMACB_TUND (AT91C_CAST(AT91C_REG *) 0xFFFBC064) // (EMACB) Transmit Underrun Error Register +#define AT91C_EMACB_RSR (AT91C_CAST(AT91C_REG *) 0xFFFBC020) // (EMACB) Receive Status Register +#define AT91C_EMACB_SA2L (AT91C_CAST(AT91C_REG *) 0xFFFBC0A0) // (EMACB) Specific Address 2 Bottom, First 4 bytes +#define AT91C_EMACB_FTO (AT91C_CAST(AT91C_REG *) 0xFFFBC040) // (EMACB) Frames Transmitted OK Register +#define AT91C_EMACB_RSE (AT91C_CAST(AT91C_REG *) 0xFFFBC074) // (EMACB) Receive Symbol Errors Register +#define AT91C_EMACB_NSR (AT91C_CAST(AT91C_REG *) 0xFFFBC008) // (EMACB) Network Status Register +#define AT91C_EMACB_RBQP (AT91C_CAST(AT91C_REG *) 0xFFFBC018) // (EMACB) Receive Buffer Queue Pointer +#define AT91C_EMACB_REV (AT91C_CAST(AT91C_REG *) 0xFFFBC0FC) // (EMACB) Revision Register +// ========== Register definition for ISI peripheral ========== +#define AT91C_ISI_DMACHDR (AT91C_CAST(AT91C_REG *) 0xFFFB403C) // (ISI) DMA Channel Disable Register +#define AT91C_ISI_IMR (AT91C_CAST(AT91C_REG *) 0xFFFB4034) // (ISI) Interrupt Mask Register +#define AT91C_ISI_R2YSET1 (AT91C_CAST(AT91C_REG *) 0xFFFB401C) // (ISI) Color Space Conversion RGB to YCrCb Register +#define AT91C_ISI_PDECF (AT91C_CAST(AT91C_REG *) 0xFFFB400C) // (ISI) Preview Decimation Factor Register +#define AT91C_ISI_CFG2 (AT91C_CAST(AT91C_REG *) 0xFFFB4004) // (ISI) Configuration Register 2 +#define AT91C_ISI_DMACCTRL (AT91C_CAST(AT91C_REG *) 0xFFFB4054) // (ISI) DMA Codec Control Register +#define AT91C_ISI_CTRL (AT91C_CAST(AT91C_REG *) 0xFFFB4024) // (ISI) Control Register +#define AT91C_ISI_Y2RSET0 (AT91C_CAST(AT91C_REG *) 0xFFFB4010) // (ISI) Color Space Conversion YCrCb to RGB Register +#define AT91C_ISI_WPSR (AT91C_CAST(AT91C_REG *) 0xFFFB40E8) // (ISI) Write Protection Status Register +#define AT91C_ISI_DMACHER (AT91C_CAST(AT91C_REG *) 0xFFFB4038) // (ISI) DMA Channel Enable Register +#define AT91C_ISI_DMACHSR (AT91C_CAST(AT91C_REG *) 0xFFFB4040) // (ISI) DMA Channel Status Register +#define AT91C_ISI_IDR (AT91C_CAST(AT91C_REG *) 0xFFFB4030) // (ISI) Interrupt Disable Register +#define AT91C_ISI_VER (AT91C_CAST(AT91C_REG *) 0xFFFB40FC) // (ISI) Version Register +#define AT91C_ISI_Y2RSET1 (AT91C_CAST(AT91C_REG *) 0xFFFB4014) // (ISI) Color Space Conversion YCrCb to RGB Register +#define AT91C_ISI_R2YSET2 (AT91C_CAST(AT91C_REG *) 0xFFFB4020) // (ISI) Color Space Conversion RGB to YCrCb Register +#define AT91C_ISI_SR (AT91C_CAST(AT91C_REG *) 0xFFFB4028) // (ISI) Status Register +#define AT91C_ISI_DMACDSCR (AT91C_CAST(AT91C_REG *) 0xFFFB4058) // (ISI) DMA Codec Descriptor Address Register +#define AT91C_ISI_IER (AT91C_CAST(AT91C_REG *) 0xFFFB402C) // (ISI) Interrupt Enable Register +#define AT91C_ISI_WPCR (AT91C_CAST(AT91C_REG *) 0xFFFB40E4) // (ISI) Write Protection Control Register +#define AT91C_ISI_DMACADDR (AT91C_CAST(AT91C_REG *) 0xFFFB4050) // (ISI) DMA Codec Base Address Register +#define AT91C_ISI_CFG1 (AT91C_CAST(AT91C_REG *) 0xFFFB4000) // (ISI) Configuration Register 1 +#define AT91C_ISI_R2YSET0 (AT91C_CAST(AT91C_REG *) 0xFFFB4018) // (ISI) Color Space Conversion RGB to YCrCb Register +#define AT91C_ISI_PSIZE (AT91C_CAST(AT91C_REG *) 0xFFFB4008) // (ISI) Preview Size Register +#define AT91C_ISI_DMAPDSCR (AT91C_CAST(AT91C_REG *) 0xFFFB404C) // (ISI) DMA Preview Descriptor Address Register +#define AT91C_ISI_DMAPADDR (AT91C_CAST(AT91C_REG *) 0xFFFB4044) // (ISI) DMA Preview Base Address Register +#define AT91C_ISI_DMAPCTRL (AT91C_CAST(AT91C_REG *) 0xFFFB4048) // (ISI) DMA Preview Control Register +// ========== Register definition for UHPHS_OHCI peripheral ========== +#define AT91C_OHCI_HcRhPortStatus (AT91C_CAST(AT91C_REG *) 0x00700054) // (UHPHS_OHCI) Root Hub Port Status Register +#define AT91C_OHCI_HcFmRemaining (AT91C_CAST(AT91C_REG *) 0x00700038) // (UHPHS_OHCI) Bit time remaining in the current Frame +#define AT91C_OHCI_HcInterruptEnable (AT91C_CAST(AT91C_REG *) 0x00700010) // (UHPHS_OHCI) Interrupt Enable Register +#define AT91C_OHCI_HcControl (AT91C_CAST(AT91C_REG *) 0x00700004) // (UHPHS_OHCI) Operating modes for the Host Controller +#define AT91C_OHCI_HcPeriodicStart (AT91C_CAST(AT91C_REG *) 0x00700040) // (UHPHS_OHCI) Periodic Start +#define AT91C_OHCI_HcInterruptStatus (AT91C_CAST(AT91C_REG *) 0x0070000C) // (UHPHS_OHCI) Interrupt Status Register +#define AT91C_OHCI_HcRhDescriptorB (AT91C_CAST(AT91C_REG *) 0x0070004C) // (UHPHS_OHCI) Root Hub characteristics B +#define AT91C_OHCI_HcInterruptDisable (AT91C_CAST(AT91C_REG *) 0x00700014) // (UHPHS_OHCI) Interrupt Disable Register +#define AT91C_OHCI_HcPeriodCurrentED (AT91C_CAST(AT91C_REG *) 0x0070001C) // (UHPHS_OHCI) Current Isochronous or Interrupt Endpoint Descriptor +#define AT91C_OHCI_HcRhDescriptorA (AT91C_CAST(AT91C_REG *) 0x00700048) // (UHPHS_OHCI) Root Hub characteristics A +#define AT91C_OHCI_HcRhStatus (AT91C_CAST(AT91C_REG *) 0x00700050) // (UHPHS_OHCI) Root Hub Status register +#define AT91C_OHCI_HcBulkCurrentED (AT91C_CAST(AT91C_REG *) 0x0070002C) // (UHPHS_OHCI) Current endpoint of the Bulk list +#define AT91C_OHCI_HcControlHeadED (AT91C_CAST(AT91C_REG *) 0x00700020) // (UHPHS_OHCI) First Endpoint Descriptor of the Control list +#define AT91C_OHCI_HcLSThreshold (AT91C_CAST(AT91C_REG *) 0x00700044) // (UHPHS_OHCI) LS Threshold +#define AT91C_OHCI_HcRevision (AT91C_CAST(AT91C_REG *) 0x00700000) // (UHPHS_OHCI) Revision +#define AT91C_OHCI_HcBulkDoneHead (AT91C_CAST(AT91C_REG *) 0x00700030) // (UHPHS_OHCI) Last completed transfer descriptor +#define AT91C_OHCI_HcFmNumber (AT91C_CAST(AT91C_REG *) 0x0070003C) // (UHPHS_OHCI) Frame number +#define AT91C_OHCI_HcFmInterval (AT91C_CAST(AT91C_REG *) 0x00700034) // (UHPHS_OHCI) Bit time between 2 consecutive SOFs +#define AT91C_OHCI_HcBulkHeadED (AT91C_CAST(AT91C_REG *) 0x00700028) // (UHPHS_OHCI) First endpoint register of the Bulk list +#define AT91C_OHCI_HcHCCA (AT91C_CAST(AT91C_REG *) 0x00700018) // (UHPHS_OHCI) Pointer to the Host Controller Communication Area +#define AT91C_OHCI_HcCommandStatus (AT91C_CAST(AT91C_REG *) 0x00700008) // (UHPHS_OHCI) Command & status Register +#define AT91C_OHCI_HcControlCurrentED (AT91C_CAST(AT91C_REG *) 0x00700024) // (UHPHS_OHCI) Endpoint Control and Status Register +// ========== Register definition for UHPHS_EHCI peripheral ========== +#define AT91C_EHCI_USBSTS (AT91C_CAST(AT91C_REG *) 0x00800014) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG03 (AT91C_CAST(AT91C_REG *) 0x0080009C) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG00 (AT91C_CAST(AT91C_REG *) 0x00800090) // (UHPHS_EHCI) +#define AT91C_EHCI_HCSPPORTROUTE (AT91C_CAST(AT91C_REG *) 0x0080000C) // (UHPHS_EHCI) +#define AT91C_EHCI_FRINDEX (AT91C_CAST(AT91C_REG *) 0x0080001C) // (UHPHS_EHCI) +#define AT91C_EHCI_CONFIGFLAG (AT91C_CAST(AT91C_REG *) 0x00800050) // (UHPHS_EHCI) +#define AT91C_EHCI_HCCPARAMS (AT91C_CAST(AT91C_REG *) 0x00800008) // (UHPHS_EHCI) +#define AT91C_EHCI_USBINTR (AT91C_CAST(AT91C_REG *) 0x00800018) // (UHPHS_EHCI) +#define AT91C_EHCI_PORTSC (AT91C_CAST(AT91C_REG *) 0x00800054) // (UHPHS_EHCI) +#define AT91C_EHCI_CTRLDSSEGMENT (AT91C_CAST(AT91C_REG *) 0x00800020) // (UHPHS_EHCI) +#define AT91C_EHCI_VERSION (AT91C_CAST(AT91C_REG *) 0x00800000) // (UHPHS_EHCI) +#define AT91C_EHCI_USBCMD (AT91C_CAST(AT91C_REG *) 0x00800010) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG04 (AT91C_CAST(AT91C_REG *) 0x008000A0) // (UHPHS_EHCI) +#define AT91C_EHCI_PERIODICLISTBASE (AT91C_CAST(AT91C_REG *) 0x00800024) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG01 (AT91C_CAST(AT91C_REG *) 0x00800094) // (UHPHS_EHCI) +#define AT91C_EHCI_HCSPARAMS (AT91C_CAST(AT91C_REG *) 0x00800004) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG05 (AT91C_CAST(AT91C_REG *) 0x008000A4) // (UHPHS_EHCI) +#define AT91C_EHCI_ASYNCLISTADDR (AT91C_CAST(AT91C_REG *) 0x00800028) // (UHPHS_EHCI) +#define AT91C_EHCI_INSNREG02 (AT91C_CAST(AT91C_REG *) 0x00800098) // (UHPHS_EHCI) +// ========== Register definition for TRNG peripheral ========== +#define AT91C_TRNG_IDR (AT91C_CAST(AT91C_REG *) 0xFFFCC014) // (TRNG) Interrupt Disable Register +#define AT91C_TRNG_IER (AT91C_CAST(AT91C_REG *) 0xFFFCC010) // (TRNG) Interrupt Enable Register +#define AT91C_TRNG_VERSION (AT91C_CAST(AT91C_REG *) 0xFFFCC0FC) // (TRNG) TRNG Version Register +#define AT91C_TRNG_ISR (AT91C_CAST(AT91C_REG *) 0xFFFCC01C) // (TRNG) Interrupt Status Register +#define AT91C_TRNG_CR (AT91C_CAST(AT91C_REG *) 0xFFFCC000) // (TRNG) Control Register +#define AT91C_TRNG_ODATA (AT91C_CAST(AT91C_REG *) 0xFFFCC050) // (TRNG) Output Data Register +#define AT91C_TRNG_IMR (AT91C_CAST(AT91C_REG *) 0xFFFCC018) // (TRNG) Interrupt Mask Register + +// ***************************************************************************** +// PIO DEFINITIONS FOR AT91SAM9G45 +// ***************************************************************************** +#define AT91C_PIO_PA0 (1 << 0) // Pin Controlled by PA0 +#define AT91C_PA0_MCI0_CK (AT91C_PIO_PA0) // +#define AT91C_PA0_TCLK3 (AT91C_PIO_PA0) // +#define AT91C_PIO_PA1 (1 << 1) // Pin Controlled by PA1 +#define AT91C_PA1_MCI0_CDA (AT91C_PIO_PA1) // +#define AT91C_PA1_TIOA3 (AT91C_PIO_PA1) // +#define AT91C_PIO_PA10 (1 << 10) // Pin Controlled by PA10 +#define AT91C_PA10_ETX0 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 0 +#define AT91C_PIO_PA11 (1 << 11) // Pin Controlled by PA11 +#define AT91C_PA11_ETX1 (AT91C_PIO_PA11) // Ethernet MAC Transmit Data 1 +#define AT91C_PIO_PA12 (1 << 12) // Pin Controlled by PA12 +#define AT91C_PA12_ERX0 (AT91C_PIO_PA12) // Ethernet MAC Receive Data 0 +#define AT91C_PIO_PA13 (1 << 13) // Pin Controlled by PA13 +#define AT91C_PA13_ERX1 (AT91C_PIO_PA13) // Ethernet MAC Receive Data 1 +#define AT91C_PIO_PA14 (1 << 14) // Pin Controlled by PA14 +#define AT91C_PA14_ETXEN (AT91C_PIO_PA14) // Ethernet MAC Transmit Enable +#define AT91C_PIO_PA15 (1 << 15) // Pin Controlled by PA15 +#define AT91C_PA15_ERXDV (AT91C_PIO_PA15) // Ethernet MAC Receive Data Valid +#define AT91C_PIO_PA16 (1 << 16) // Pin Controlled by PA16 +#define AT91C_PA16_ERXER (AT91C_PIO_PA16) // Ethernet MAC Receive Error +#define AT91C_PIO_PA17 (1 << 17) // Pin Controlled by PA17 +#define AT91C_PA17_ETXCK_EREFCK (AT91C_PIO_PA17) // Ethernet MAC Transmit Clock/Reference Clock +#define AT91C_PIO_PA18 (1 << 18) // Pin Controlled by PA18 +#define AT91C_PA18_EMDC (AT91C_PIO_PA18) // Ethernet MAC Management Data Clock +#define AT91C_PIO_PA19 (1 << 19) // Pin Controlled by PA19 +#define AT91C_PA19_EMDIO (AT91C_PIO_PA19) // Ethernet MAC Management Data Input/Output +#define AT91C_PIO_PA2 (1 << 2) // Pin Controlled by PA2 +#define AT91C_PA2_MCI0_DA0 (AT91C_PIO_PA2) // +#define AT91C_PA2_TIOB3 (AT91C_PIO_PA2) // +#define AT91C_PIO_PA20 (1 << 20) // Pin Controlled by PA20 +#define AT91C_PA20_TWD0 (AT91C_PIO_PA20) // TWI Two-wire Serial Data +#define AT91C_PIO_PA21 (1 << 21) // Pin Controlled by PA21 +#define AT91C_PA21_TWCK0 (AT91C_PIO_PA21) // TWI Two-wire Serial Clock +#define AT91C_PIO_PA22 (1 << 22) // Pin Controlled by PA22 +#define AT91C_PA22_MCI1_CDA (AT91C_PIO_PA22) // +#define AT91C_PA22_SCK3 (AT91C_PIO_PA22) // +#define AT91C_PIO_PA23 (1 << 23) // Pin Controlled by PA23 +#define AT91C_PA23_MCI1_DA0 (AT91C_PIO_PA23) // +#define AT91C_PA23_RTS3 (AT91C_PIO_PA23) // +#define AT91C_PIO_PA24 (1 << 24) // Pin Controlled by PA24 +#define AT91C_PA24_MCI1_DA1 (AT91C_PIO_PA24) // +#define AT91C_PA24_CTS3 (AT91C_PIO_PA24) // +#define AT91C_PIO_PA25 (1 << 25) // Pin Controlled by PA25 +#define AT91C_PA25_MCI1_DA2 (AT91C_PIO_PA25) // +#define AT91C_PA25_PWM3 (AT91C_PIO_PA25) // +#define AT91C_PIO_PA26 (1 << 26) // Pin Controlled by PA26 +#define AT91C_PA26_MCI1_DA3 (AT91C_PIO_PA26) // +#define AT91C_PA26_TIOB2 (AT91C_PIO_PA26) // +#define AT91C_PIO_PA27 (1 << 27) // Pin Controlled by PA27 +#define AT91C_PA27_MCI1_DA4 (AT91C_PIO_PA27) // +#define AT91C_PA27_ETXER (AT91C_PIO_PA27) // Ethernet MAC Transmikt Coding Error +#define AT91C_PIO_PA28 (1 << 28) // Pin Controlled by PA28 +#define AT91C_PA28_MCI1_DA5 (AT91C_PIO_PA28) // +#define AT91C_PA28_ERXCK (AT91C_PIO_PA28) // Ethernet MAC Receive Clock +#define AT91C_PIO_PA29 (1 << 29) // Pin Controlled by PA29 +#define AT91C_PA29_MCI1_DA6 (AT91C_PIO_PA29) // +#define AT91C_PA29_ECRS (AT91C_PIO_PA29) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid +#define AT91C_PIO_PA3 (1 << 3) // Pin Controlled by PA3 +#define AT91C_PA3_MCI0_DA1 (AT91C_PIO_PA3) // +#define AT91C_PA3_TCLK4 (AT91C_PIO_PA3) // +#define AT91C_PIO_PA30 (1 << 30) // Pin Controlled by PA30 +#define AT91C_PA30_MCI1_DA7 (AT91C_PIO_PA30) // +#define AT91C_PA30_ECOL (AT91C_PIO_PA30) // Ethernet MAC Collision Detected +#define AT91C_PIO_PA31 (1 << 31) // Pin Controlled by PA31 +#define AT91C_PA31_MCI1_CK (AT91C_PIO_PA31) // +#define AT91C_PA31_PCK0 (AT91C_PIO_PA31) // +#define AT91C_PIO_PA4 (1 << 4) // Pin Controlled by PA4 +#define AT91C_PA4_MCI0_DA2 (AT91C_PIO_PA4) // +#define AT91C_PA4_TIOA4 (AT91C_PIO_PA4) // +#define AT91C_PIO_PA5 (1 << 5) // Pin Controlled by PA5 +#define AT91C_PA5_MCI0_DA3 (AT91C_PIO_PA5) // +#define AT91C_PA5_TIOB4 (AT91C_PIO_PA5) // +#define AT91C_PIO_PA6 (1 << 6) // Pin Controlled by PA6 +#define AT91C_PA6_MCI0_DA4 (AT91C_PIO_PA6) // +#define AT91C_PA6_ETX2 (AT91C_PIO_PA6) // Ethernet MAC Transmit Data 2 +#define AT91C_PIO_PA7 (1 << 7) // Pin Controlled by PA7 +#define AT91C_PA7_MCI0_DA5 (AT91C_PIO_PA7) // +#define AT91C_PA7_ETX3 (AT91C_PIO_PA7) // Ethernet MAC Transmit Data 3 +#define AT91C_PIO_PA8 (1 << 8) // Pin Controlled by PA8 +#define AT91C_PA8_MCI0_DA6 (AT91C_PIO_PA8) // +#define AT91C_PA8_ERX2 (AT91C_PIO_PA8) // Ethernet MAC Receive Data 2 +#define AT91C_PIO_PA9 (1 << 9) // Pin Controlled by PA9 +#define AT91C_PA9_MCI0_DA7 (AT91C_PIO_PA9) // +#define AT91C_PA9_ERX3 (AT91C_PIO_PA9) // Ethernet MAC Receive Data 3 +#define AT91C_PIO_PB0 (1 << 0) // Pin Controlled by PB0 +#define AT91C_PB0_SPI0_MISO (AT91C_PIO_PB0) // SPI 0 Master In Slave +#define AT91C_PIO_PB1 (1 << 1) // Pin Controlled by PB1 +#define AT91C_PB1_SPI0_MOSI (AT91C_PIO_PB1) // SPI 0 Master Out Slave +#define AT91C_PIO_PB10 (1 << 10) // Pin Controlled by PB10 +#define AT91C_PB10_TWD1 (AT91C_PIO_PB10) // +#define AT91C_PB10_ISI_D10 (AT91C_PIO_PB10) // +#define AT91C_PIO_PB11 (1 << 11) // Pin Controlled by PB11 +#define AT91C_PB11_TWCK1 (AT91C_PIO_PB11) // +#define AT91C_PB11_ISI_D11 (AT91C_PIO_PB11) // +#define AT91C_PIO_PB12 (1 << 12) // Pin Controlled by PB12 +#define AT91C_PB12_DRXD (AT91C_PIO_PB12) // +#define AT91C_PIO_PB13 (1 << 13) // Pin Controlled by PB13 +#define AT91C_PB13_DTXD (AT91C_PIO_PB13) // +#define AT91C_PIO_PB14 (1 << 14) // Pin Controlled by PB14 +#define AT91C_PB14_SPI1_MISO (AT91C_PIO_PB14) // +#define AT91C_PIO_PB15 (1 << 15) // Pin Controlled by PB15 +#define AT91C_PB15_SPI1_MOSI (AT91C_PIO_PB15) // +#define AT91C_PB15_CTS0 (AT91C_PIO_PB15) // +#define AT91C_PIO_PB16 (1 << 16) // Pin Controlled by PB16 +#define AT91C_PB16_SPI1_SPCK (AT91C_PIO_PB16) // +#define AT91C_PB16_SCK0 (AT91C_PIO_PB16) // +#define AT91C_PIO_PB17 (1 << 17) // Pin Controlled by PB17 +#define AT91C_PB17_SPI1_NPCS0 (AT91C_PIO_PB17) // +#define AT91C_PB17_RTS0 (AT91C_PIO_PB17) // +#define AT91C_PIO_PB18 (1 << 18) // Pin Controlled by PB18 +#define AT91C_PB18_RXD0 (AT91C_PIO_PB18) // +#define AT91C_PB18_SPI0_NPCS1 (AT91C_PIO_PB18) // +#define AT91C_PIO_PB19 (1 << 19) // Pin Controlled by PB19 +#define AT91C_PB19_TXD0 (AT91C_PIO_PB19) // +#define AT91C_PB19_SPI0_NPCS2 (AT91C_PIO_PB19) // +#define AT91C_PIO_PB2 (1 << 2) // Pin Controlled by PB2 +#define AT91C_PB2_SPI0_SPCK (AT91C_PIO_PB2) // SPI 0 Serial Clock +#define AT91C_PIO_PB20 (1 << 20) // Pin Controlled by PB20 +#define AT91C_PB20_ISI_D0 (AT91C_PIO_PB20) // +#define AT91C_PIO_PB21 (1 << 21) // Pin Controlled by PB21 +#define AT91C_PB21_ISI_D1 (AT91C_PIO_PB21) // +#define AT91C_PIO_PB22 (1 << 22) // Pin Controlled by PB22 +#define AT91C_PB22_ISI_D2 (AT91C_PIO_PB22) // +#define AT91C_PIO_PB23 (1 << 23) // Pin Controlled by PB23 +#define AT91C_PB23_ISI_D3 (AT91C_PIO_PB23) // +#define AT91C_PIO_PB24 (1 << 24) // Pin Controlled by PB24 +#define AT91C_PB24_ISI_D4 (AT91C_PIO_PB24) // +#define AT91C_PIO_PB25 (1 << 25) // Pin Controlled by PB25 +#define AT91C_PB25_ISI_D5 (AT91C_PIO_PB25) // +#define AT91C_PIO_PB26 (1 << 26) // Pin Controlled by PB26 +#define AT91C_PB26_ISI_D6 (AT91C_PIO_PB26) // +#define AT91C_PIO_PB27 (1 << 27) // Pin Controlled by PB27 +#define AT91C_PB27_ISI_D7 (AT91C_PIO_PB27) // +#define AT91C_PIO_PB28 (1 << 28) // Pin Controlled by PB28 +#define AT91C_PB28_ISI_PCK (AT91C_PIO_PB28) // +#define AT91C_PIO_PB29 (1 << 29) // Pin Controlled by PB29 +#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) // +#define AT91C_PIO_PB3 (1 << 3) // Pin Controlled by PB3 +#define AT91C_PB3_SPI0_NPCS0 (AT91C_PIO_PB3) // SPI 0 Peripheral Chip Select 0 +#define AT91C_PIO_PB30 (1 << 30) // Pin Controlled by PB30 +#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) // +#define AT91C_PIO_PB31 (1 << 31) // Pin Controlled by PB31 +#define AT91C_PB31_ (AT91C_PIO_PB31) // +#define AT91C_PB31_PCK1 (AT91C_PIO_PB31) // +#define AT91C_PIO_PB4 (1 << 4) // Pin Controlled by PB4 +#define AT91C_PB4_TXD1 (AT91C_PIO_PB4) // USART 1 Transmit Data +#define AT91C_PIO_PB5 (1 << 5) // Pin Controlled by PB5 +#define AT91C_PB5_RXD1 (AT91C_PIO_PB5) // USART 1 Receive Data +#define AT91C_PIO_PB6 (1 << 6) // Pin Controlled by PB6 +#define AT91C_PB6_TXD2 (AT91C_PIO_PB6) // USART 2 Transmit Data +#define AT91C_PIO_PB7 (1 << 7) // Pin Controlled by PB7 +#define AT91C_PB7_RXD2 (AT91C_PIO_PB7) // USART 2 Receive Data +#define AT91C_PIO_PB8 (1 << 8) // Pin Controlled by PB8 +#define AT91C_PB8_TXD3 (AT91C_PIO_PB8) // USART 3 Transmit Data +#define AT91C_PB8_ISI_D8 (AT91C_PIO_PB8) // +#define AT91C_PIO_PB9 (1 << 9) // Pin Controlled by PB9 +#define AT91C_PB9_RXD3 (AT91C_PIO_PB9) // USART 3 Receive Data +#define AT91C_PB9_ISI_D9 (AT91C_PIO_PB9) // +#define AT91C_PIO_PC0 (1 << 0) // Pin Controlled by PC0 +#define AT91C_PC0_DQM2 (AT91C_PIO_PC0) // DQM2 +#define AT91C_PIO_PC1 (1 << 1) // Pin Controlled by PC1 +#define AT91C_PC1_DQM3 (AT91C_PIO_PC1) // DQM3 +#define AT91C_PIO_PC10 (1 << 10) // Pin Controlled by PC10 +#define AT91C_PC10_NCS4_CFCS0 (AT91C_PIO_PC10) // +#define AT91C_PC10_TCLK2 (AT91C_PIO_PC10) // +#define AT91C_PIO_PC11 (1 << 11) // Pin Controlled by PC11 +#define AT91C_PC11_NCS5_CFCS1 (AT91C_PIO_PC11) // +#define AT91C_PC11_CTS2 (AT91C_PIO_PC11) // +#define AT91C_PIO_PC12 (1 << 12) // Pin Controlled by PC12 +#define AT91C_PC12_A25_CFRNW (AT91C_PIO_PC12) // +#define AT91C_PIO_PC13 (1 << 13) // Pin Controlled by PC13 +#define AT91C_PC13_NCS2 (AT91C_PIO_PC13) // +#define AT91C_PIO_PC14 (1 << 14) // Pin Controlled by PC14 +#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) // +#define AT91C_PIO_PC15 (1 << 15) // Pin Controlled by PC15 +#define AT91C_PC15_NWAIT (AT91C_PIO_PC15) // +#define AT91C_PIO_PC16 (1 << 16) // Pin Controlled by PC16 +#define AT91C_PC16_D16 (AT91C_PIO_PC16) // +#define AT91C_PIO_PC17 (1 << 17) // Pin Controlled by PC17 +#define AT91C_PC17_D17 (AT91C_PIO_PC17) // +#define AT91C_PIO_PC18 (1 << 18) // Pin Controlled by PC18 +#define AT91C_PC18_D18 (AT91C_PIO_PC18) // +#define AT91C_PIO_PC19 (1 << 19) // Pin Controlled by PC19 +#define AT91C_PC19_D19 (AT91C_PIO_PC19) // +#define AT91C_PIO_PC2 (1 << 2) // Pin Controlled by PC2 +#define AT91C_PC2_A19 (AT91C_PIO_PC2) // +#define AT91C_PIO_PC20 (1 << 20) // Pin Controlled by PC20 +#define AT91C_PC20_D20 (AT91C_PIO_PC20) // +#define AT91C_PIO_PC21 (1 << 21) // Pin Controlled by PC21 +#define AT91C_PC21_D21 (AT91C_PIO_PC21) // +#define AT91C_PIO_PC22 (1 << 22) // Pin Controlled by PC22 +#define AT91C_PC22_D22 (AT91C_PIO_PC22) // +#define AT91C_PIO_PC23 (1 << 23) // Pin Controlled by PC23 +#define AT91C_PC23_D23 (AT91C_PIO_PC23) // +#define AT91C_PIO_PC24 (1 << 24) // Pin Controlled by PC24 +#define AT91C_PC24_D24 (AT91C_PIO_PC24) // +#define AT91C_PIO_PC25 (1 << 25) // Pin Controlled by PC25 +#define AT91C_PC25_D25 (AT91C_PIO_PC25) // +#define AT91C_PIO_PC26 (1 << 26) // Pin Controlled by PC26 +#define AT91C_PC26_D26 (AT91C_PIO_PC26) // +#define AT91C_PIO_PC27 (1 << 27) // Pin Controlled by PC27 +#define AT91C_PC27_D27 (AT91C_PIO_PC27) // +#define AT91C_PIO_PC28 (1 << 28) // Pin Controlled by PC28 +#define AT91C_PC28_D28 (AT91C_PIO_PC28) // +#define AT91C_PIO_PC29 (1 << 29) // Pin Controlled by PC29 +#define AT91C_PC29_D29 (AT91C_PIO_PC29) // +#define AT91C_PIO_PC3 (1 << 3) // Pin Controlled by PC3 +#define AT91C_PC3_A20 (AT91C_PIO_PC3) // +#define AT91C_PIO_PC30 (1 << 30) // Pin Controlled by PC30 +#define AT91C_PC30_D30 (AT91C_PIO_PC30) // +#define AT91C_PIO_PC31 (1 << 31) // Pin Controlled by PC31 +#define AT91C_PC31_D31 (AT91C_PIO_PC31) // +#define AT91C_PIO_PC4 (1 << 4) // Pin Controlled by PC4 +#define AT91C_PC4_A21_NANDALE (AT91C_PIO_PC4) // +#define AT91C_PIO_PC5 (1 << 5) // Pin Controlled by PC5 +#define AT91C_PC5_A22_NANDCLE (AT91C_PIO_PC5) // +#define AT91C_PIO_PC6 (1 << 6) // Pin Controlled by PC6 +#define AT91C_PC6_A23 (AT91C_PIO_PC6) // +#define AT91C_PIO_PC7 (1 << 7) // Pin Controlled by PC7 +#define AT91C_PC7_A24 (AT91C_PIO_PC7) // +#define AT91C_PIO_PC8 (1 << 8) // Pin Controlled by PC8 +#define AT91C_PC8_CFCE1 (AT91C_PIO_PC8) // +#define AT91C_PIO_PC9 (1 << 9) // Pin Controlled by PC9 +#define AT91C_PC9_CFCE2 (AT91C_PIO_PC9) // +#define AT91C_PC9_RTS2 (AT91C_PIO_PC9) // +#define AT91C_PIO_PD0 (1 << 0) // Pin Controlled by PD0 +#define AT91C_PD0_TK0 (AT91C_PIO_PD0) // +#define AT91C_PD0_PWM3 (AT91C_PIO_PD0) // +#define AT91C_PIO_PD1 (1 << 1) // Pin Controlled by PD1 +#define AT91C_PD1_TF0 (AT91C_PIO_PD1) // +#define AT91C_PIO_PD10 (1 << 10) // Pin Controlled by PD10 +#define AT91C_PD10_TD1 (AT91C_PIO_PD10) // +#define AT91C_PIO_PD11 (1 << 11) // Pin Controlled by PD11 +#define AT91C_PD11_RD1 (AT91C_PIO_PD11) // +#define AT91C_PIO_PD12 (1 << 12) // Pin Controlled by PD12 +#define AT91C_PD12_TK1 (AT91C_PIO_PD12) // +#define AT91C_PD12_PCK0 (AT91C_PIO_PD12) // +#define AT91C_PIO_PD13 (1 << 13) // Pin Controlled by PD13 +#define AT91C_PD13_RK1 (AT91C_PIO_PD13) // +#define AT91C_PIO_PD14 (1 << 14) // Pin Controlled by PD14 +#define AT91C_PD14_TF1 (AT91C_PIO_PD14) // +#define AT91C_PIO_PD15 (1 << 15) // Pin Controlled by PD15 +#define AT91C_PD15_RF1 (AT91C_PIO_PD15) // +#define AT91C_PIO_PD16 (1 << 16) // Pin Controlled by PD16 +#define AT91C_PD16_RTS1 (AT91C_PIO_PD16) // +#define AT91C_PIO_PD17 (1 << 17) // Pin Controlled by PD17 +#define AT91C_PD17_CTS1 (AT91C_PIO_PD17) // +#define AT91C_PIO_PD18 (1 << 18) // Pin Controlled by PD18 +#define AT91C_PD18_SPI1_NPCS2 (AT91C_PIO_PD18) // +#define AT91C_PD18_IRQ (AT91C_PIO_PD18) // +#define AT91C_PIO_PD19 (1 << 19) // Pin Controlled by PD19 +#define AT91C_PD19_SPI1_NPCS3 (AT91C_PIO_PD19) // +#define AT91C_PD19_FIQ (AT91C_PIO_PD19) // +#define AT91C_PIO_PD2 (1 << 2) // Pin Controlled by PD2 +#define AT91C_PD2_TD0 (AT91C_PIO_PD2) // +#define AT91C_PIO_PD20 (1 << 20) // Pin Controlled by PD20 +#define AT91C_PD20_TIOA0 (AT91C_PIO_PD20) // +#define AT91C_PIO_PD21 (1 << 21) // Pin Controlled by PD21 +#define AT91C_PD21_TIOA1 (AT91C_PIO_PD21) // +#define AT91C_PIO_PD22 (1 << 22) // Pin Controlled by PD22 +#define AT91C_PD22_TIOA2 (AT91C_PIO_PD22) // +#define AT91C_PIO_PD23 (1 << 23) // Pin Controlled by PD23 +#define AT91C_PD23_TCLK0 (AT91C_PIO_PD23) // +#define AT91C_PIO_PD24 (1 << 24) // Pin Controlled by PD24 +#define AT91C_PD24_SPI0_NPCS1 (AT91C_PIO_PD24) // +#define AT91C_PD24_PWM0 (AT91C_PIO_PD24) // +#define AT91C_PIO_PD25 (1 << 25) // Pin Controlled by PD25 +#define AT91C_PD25_SPI0_NPCS2 (AT91C_PIO_PD25) // +#define AT91C_PD25_PWM1 (AT91C_PIO_PD25) // +#define AT91C_PIO_PD26 (1 << 26) // Pin Controlled by PD26 +#define AT91C_PD26_PCK0 (AT91C_PIO_PD26) // +#define AT91C_PD26_PWM2 (AT91C_PIO_PD26) // +#define AT91C_PIO_PD27 (1 << 27) // Pin Controlled by PD27 +#define AT91C_PD27_PCK1 (AT91C_PIO_PD27) // +#define AT91C_PD27_SPI0_NPCS3 (AT91C_PIO_PD27) // +#define AT91C_PIO_PD28 (1 << 28) // Pin Controlled by PD28 +#define AT91C_PD28_TSADTRG (AT91C_PIO_PD28) // +#define AT91C_PD28_SPI1_NPCS1 (AT91C_PIO_PD28) // +#define AT91C_PIO_PD29 (1 << 29) // Pin Controlled by PD29 +#define AT91C_PD29_TCLK1 (AT91C_PIO_PD29) // +#define AT91C_PD29_SCK1 (AT91C_PIO_PD29) // +#define AT91C_PIO_PD3 (1 << 3) // Pin Controlled by PD3 +#define AT91C_PD3_RD0 (AT91C_PIO_PD3) // +#define AT91C_PIO_PD30 (1 << 30) // Pin Controlled by PD30 +#define AT91C_PD30_TIOB0 (AT91C_PIO_PD30) // +#define AT91C_PD30_SCK2 (AT91C_PIO_PD30) // +#define AT91C_PIO_PD31 (1 << 31) // Pin Controlled by PD31 +#define AT91C_PD31_TIOB1 (AT91C_PIO_PD31) // +#define AT91C_PD31_PWM1 (AT91C_PIO_PD31) // +#define AT91C_PIO_PD4 (1 << 4) // Pin Controlled by PD4 +#define AT91C_PD4_RK0 (AT91C_PIO_PD4) // +#define AT91C_PIO_PD5 (1 << 5) // Pin Controlled by PD5 +#define AT91C_PD5_RF0 (AT91C_PIO_PD5) // +#define AT91C_PIO_PD6 (1 << 6) // Pin Controlled by PD6 +#define AT91C_PD6_AC97RX (AT91C_PIO_PD6) // +#define AT91C_PIO_PD7 (1 << 7) // Pin Controlled by PD7 +#define AT91C_PD7_AC97TX (AT91C_PIO_PD7) // +#define AT91C_PD7_TIOA5 (AT91C_PIO_PD7) // +#define AT91C_PIO_PD8 (1 << 8) // Pin Controlled by PD8 +#define AT91C_PD8_AC97FS (AT91C_PIO_PD8) // +#define AT91C_PD8_TIOB5 (AT91C_PIO_PD8) // +#define AT91C_PIO_PD9 (1 << 9) // Pin Controlled by PD9 +#define AT91C_PD9_AC97CK (AT91C_PIO_PD9) // +#define AT91C_PD9_TCLK5 (AT91C_PIO_PD9) // +#define AT91C_PIO_PE0 (1 << 0) // Pin Controlled by PE0 +#define AT91C_PE0_LCDPWR (AT91C_PIO_PE0) // +#define AT91C_PE0_PCK0 (AT91C_PIO_PE0) // +#define AT91C_PIO_PE1 (1 << 1) // Pin Controlled by PE1 +#define AT91C_PE1_LCDMOD (AT91C_PIO_PE1) // +#define AT91C_PIO_PE10 (1 << 10) // Pin Controlled by PE10 +#define AT91C_PE10_LCDD3 (AT91C_PIO_PE10) // +#define AT91C_PE10_LCDD5 (AT91C_PIO_PE10) // +#define AT91C_PIO_PE11 (1 << 11) // Pin Controlled by PE11 +#define AT91C_PE11_LCDD4 (AT91C_PIO_PE11) // +#define AT91C_PE11_LCDD6 (AT91C_PIO_PE11) // +#define AT91C_PIO_PE12 (1 << 12) // Pin Controlled by PE12 +#define AT91C_PE12_LCDD5 (AT91C_PIO_PE12) // +#define AT91C_PE12_LCDD7 (AT91C_PIO_PE12) // +#define AT91C_PIO_PE13 (1 << 13) // Pin Controlled by PE13 +#define AT91C_PE13_LCDD6 (AT91C_PIO_PE13) // +#define AT91C_PE13_LCDD10 (AT91C_PIO_PE13) // +#define AT91C_PIO_PE14 (1 << 14) // Pin Controlled by PE14 +#define AT91C_PE14_LCDD7 (AT91C_PIO_PE14) // +#define AT91C_PE14_LCDD11 (AT91C_PIO_PE14) // +#define AT91C_PIO_PE15 (1 << 15) // Pin Controlled by PE15 +#define AT91C_PE15_LCDD8 (AT91C_PIO_PE15) // +#define AT91C_PE15_LCDD12 (AT91C_PIO_PE15) // +#define AT91C_PIO_PE16 (1 << 16) // Pin Controlled by PE16 +#define AT91C_PE16_LCDD9 (AT91C_PIO_PE16) // +#define AT91C_PE16_LCDD13 (AT91C_PIO_PE16) // +#define AT91C_PIO_PE17 (1 << 17) // Pin Controlled by PE17 +#define AT91C_PE17_LCDD10 (AT91C_PIO_PE17) // +#define AT91C_PE17_LCDD14 (AT91C_PIO_PE17) // +#define AT91C_PIO_PE18 (1 << 18) // Pin Controlled by PE18 +#define AT91C_PE18_LCDD11 (AT91C_PIO_PE18) // +#define AT91C_PE18_LCDD15 (AT91C_PIO_PE18) // +#define AT91C_PIO_PE19 (1 << 19) // Pin Controlled by PE19 +#define AT91C_PE19_LCDD12 (AT91C_PIO_PE19) // +#define AT91C_PE19_LCDD18 (AT91C_PIO_PE19) // +#define AT91C_PIO_PE2 (1 << 2) // Pin Controlled by PE2 +#define AT91C_PE2_LCDCC (AT91C_PIO_PE2) // +#define AT91C_PIO_PE20 (1 << 20) // Pin Controlled by PE20 +#define AT91C_PE20_LCDD13 (AT91C_PIO_PE20) // +#define AT91C_PE20_LCDD19 (AT91C_PIO_PE20) // +#define AT91C_PIO_PE21 (1 << 21) // Pin Controlled by PE21 +#define AT91C_PE21_LCDD14 (AT91C_PIO_PE21) // +#define AT91C_PE21_LCDD20 (AT91C_PIO_PE21) // +#define AT91C_PIO_PE22 (1 << 22) // Pin Controlled by PE22 +#define AT91C_PE22_LCDD15 (AT91C_PIO_PE22) // +#define AT91C_PE22_LCDD21 (AT91C_PIO_PE22) // +#define AT91C_PIO_PE23 (1 << 23) // Pin Controlled by PE23 +#define AT91C_PE23_LCDD16 (AT91C_PIO_PE23) // +#define AT91C_PE23_LCDD22 (AT91C_PIO_PE23) // +#define AT91C_PIO_PE24 (1 << 24) // Pin Controlled by PE24 +#define AT91C_PE24_LCDD17 (AT91C_PIO_PE24) // +#define AT91C_PE24_LCDD23 (AT91C_PIO_PE24) // +#define AT91C_PIO_PE25 (1 << 25) // Pin Controlled by PE25 +#define AT91C_PE25_LCDD18 (AT91C_PIO_PE25) // +#define AT91C_PIO_PE26 (1 << 26) // Pin Controlled by PE26 +#define AT91C_PE26_LCDD19 (AT91C_PIO_PE26) // +#define AT91C_PIO_PE27 (1 << 27) // Pin Controlled by PE27 +#define AT91C_PE27_LCDD20 (AT91C_PIO_PE27) // +#define AT91C_PIO_PE28 (1 << 28) // Pin Controlled by PE28 +#define AT91C_PE28_LCDD21 (AT91C_PIO_PE28) // +#define AT91C_PIO_PE29 (1 << 29) // Pin Controlled by PE29 +#define AT91C_PE29_LCDD22 (AT91C_PIO_PE29) // +#define AT91C_PIO_PE3 (1 << 3) // Pin Controlled by PE3 +#define AT91C_PE3_LCDVSYNC (AT91C_PIO_PE3) // +#define AT91C_PIO_PE30 (1 << 30) // Pin Controlled by PE30 +#define AT91C_PE30_LCDD23 (AT91C_PIO_PE30) // +#define AT91C_PIO_PE31 (1 << 31) // Pin Controlled by PE31 +#define AT91C_PE31_PWM2 (AT91C_PIO_PE31) // +#define AT91C_PE31_PCK1 (AT91C_PIO_PE31) // +#define AT91C_PIO_PE4 (1 << 4) // Pin Controlled by PE4 +#define AT91C_PE4_LCDHSYNC (AT91C_PIO_PE4) // +#define AT91C_PIO_PE5 (1 << 5) // Pin Controlled by PE5 +#define AT91C_PE5_LCDDOTCK (AT91C_PIO_PE5) // +#define AT91C_PIO_PE6 (1 << 6) // Pin Controlled by PE6 +#define AT91C_PE6_LCDDEN (AT91C_PIO_PE6) // +#define AT91C_PIO_PE7 (1 << 7) // Pin Controlled by PE7 +#define AT91C_PE7_LCDD0 (AT91C_PIO_PE7) // +#define AT91C_PE7_LCDD2 (AT91C_PIO_PE7) // +#define AT91C_PIO_PE8 (1 << 8) // Pin Controlled by PE8 +#define AT91C_PE8_LCDD1 (AT91C_PIO_PE8) // +#define AT91C_PE8_LCDD3 (AT91C_PIO_PE8) // +#define AT91C_PIO_PE9 (1 << 9) // Pin Controlled by PE9 +#define AT91C_PE9_LCDD2 (AT91C_PIO_PE9) // +#define AT91C_PE9_LCDD4 (AT91C_PIO_PE9) // + +// ***************************************************************************** +// PERIPHERAL ID DEFINITIONS FOR AT91SAM9G45 +// ***************************************************************************** +#define AT91C_ID_FIQ ( 0) // Advanced Interrupt Controller (FIQ) +#define AT91C_ID_SYS ( 1) // System Controller +#define AT91C_ID_PIOA ( 2) // Parallel IO Controller A +#define AT91C_ID_PIOB ( 3) // Parallel IO Controller B +#define AT91C_ID_PIOC ( 4) // Parallel IO Controller C +#define AT91C_ID_PIOD_E ( 5) // Parallel IO Controller D and E +#define AT91C_ID_TRNG ( 6) // True Random Number Generator +#define AT91C_ID_US0 ( 7) // USART 0 +#define AT91C_ID_US1 ( 8) // USART 1 +#define AT91C_ID_US2 ( 9) // USART 2 +#define AT91C_ID_US3 (10) // USART 2 +#define AT91C_ID_MCI0 (11) // Multimedia Card Interface 0 +#define AT91C_ID_TWI0 (12) // TWI 0 +#define AT91C_ID_TWI1 (13) // TWI 1 +#define AT91C_ID_SPI0 (14) // Serial Peripheral Interface +#define AT91C_ID_SPI1 (15) // Serial Peripheral Interface +#define AT91C_ID_SSC0 (16) // Serial Synchronous Controller 0 +#define AT91C_ID_SSC1 (17) // Serial Synchronous Controller 1 +#define AT91C_ID_TC (18) // Timer Counter 0, 1, 2, 3, 4, 5 +#define AT91C_ID_PWMC (19) // Pulse Width Modulation Controller +#define AT91C_ID_TSADC (20) // Touch Screen Controller +#define AT91C_ID_HDMA (21) // HDMA +#define AT91C_ID_UHPHS (22) // USB Host High Speed +#define AT91C_ID_LCDC (23) // LCD Controller +#define AT91C_ID_AC97C (24) // AC97 Controller +#define AT91C_ID_EMAC (25) // Ethernet MAC +#define AT91C_ID_ISI (26) // Image Sensor Interface +#define AT91C_ID_UDPHS (27) // USB Device HS +#define AT91C_ID_MCI1 (29) // Multimedia Card Interface 1 +#define AT91C_ID_VDEC (30) // Video Decoder +#define AT91C_ID_IRQ0 (31) // Advanced Interrupt Controller (IRQ0) +#define AT91C_ALL_INT (0xEFFFFFFF) // ALL VALID INTERRUPTS + +// ***************************************************************************** +// BASE ADDRESS DEFINITIONS FOR AT91SAM9G45 +// ***************************************************************************** +#define AT91C_BASE_SFR (AT91C_CAST(AT91PS_SFR) 0xFFF74000) // (SFR) Base Address +#define AT91C_BASE_SYS (AT91C_CAST(AT91PS_SYS) 0xFFFFC000) // (SYS) Base Address +#define AT91C_BASE_EBI (AT91C_CAST(AT91PS_EBI) 0xFFFFE200) // (EBI) Base Address +#define AT91C_BASE_DDR2CP1 (AT91C_CAST(AT91PS_HDDRSDRC2) 0xFFFFE400) // (DDR2CP1) Base Address +#define AT91C_BASE_DDR2C (AT91C_CAST(AT91PS_HDDRSDRC2) 0xFFFFE600) // (DDR2C) Base Address +#define AT91C_BASE_SMC (AT91C_CAST(AT91PS_SMC) 0xFFFFE800) // (SMC) Base Address +#define AT91C_BASE_MATRIX (AT91C_CAST(AT91PS_MATRIX) 0xFFFFEA00) // (MATRIX) Base Address +#define AT91C_BASE_AIC (AT91C_CAST(AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address +#define AT91C_BASE_PDC_DBGU (AT91C_CAST(AT91PS_PDC) 0xFFFFEF00) // (PDC_DBGU) Base Address +#define AT91C_BASE_DBGU (AT91C_CAST(AT91PS_DBGU) 0xFFFFEE00) // (DBGU) Base Address +#define AT91C_BASE_PIOA (AT91C_CAST(AT91PS_PIO) 0xFFFFF200) // (PIOA) Base Address +#define AT91C_BASE_PIOB (AT91C_CAST(AT91PS_PIO) 0xFFFFF400) // (PIOB) Base Address +#define AT91C_BASE_PIOC (AT91C_CAST(AT91PS_PIO) 0xFFFFF600) // (PIOC) Base Address +#define AT91C_BASE_PIOD (AT91C_CAST(AT91PS_PIO) 0xFFFFF800) // (PIOD) Base Address +#define AT91C_BASE_PIOE (AT91C_CAST(AT91PS_PIO) 0xFFFFFA00) // (PIOE) Base Address +#define AT91C_BASE_PMC (AT91C_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address +#define AT91C_BASE_CKGR (AT91C_CAST(AT91PS_CKGR) 0xFFFFFC1C) // (CKGR) Base Address +#define AT91C_BASE_RSTC (AT91C_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address +#define AT91C_BASE_SHDWC (AT91C_CAST(AT91PS_SHDWC) 0xFFFFFD10) // (SHDWC) Base Address +#define AT91C_BASE_RTTC (AT91C_CAST(AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address +#define AT91C_BASE_PITC (AT91C_CAST(AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address +#define AT91C_BASE_WDTC (AT91C_CAST(AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address +#define AT91C_BASE_RTC (AT91C_CAST(AT91PS_RTC) 0xFFFFFDB0) // (RTC) Base Address +#define AT91C_BASE_TC0 (AT91C_CAST(AT91PS_TC) 0xFFF7C000) // (TC0) Base Address +#define AT91C_BASE_TC1 (AT91C_CAST(AT91PS_TC) 0xFFF7C040) // (TC1) Base Address +#define AT91C_BASE_TC2 (AT91C_CAST(AT91PS_TC) 0xFFF7C080) // (TC2) Base Address +#define AT91C_BASE_TC3 (AT91C_CAST(AT91PS_TC) 0xFFFD4000) // (TC3) Base Address +#define AT91C_BASE_TC4 (AT91C_CAST(AT91PS_TC) 0xFFFD4040) // (TC4) Base Address +#define AT91C_BASE_TC5 (AT91C_CAST(AT91PS_TC) 0xFFFD4080) // (TC5) Base Address +#define AT91C_BASE_TCB0 (AT91C_CAST(AT91PS_TCB) 0xFFF7C000) // (TCB0) Base Address +#define AT91C_BASE_TCB1 (AT91C_CAST(AT91PS_TCB) 0xFFFD4000) // (TCB1) Base Address +#define AT91C_BASE_MCI0 (AT91C_CAST(AT91PS_MCI) 0xFFF80000) // (MCI0) Base Address +#define AT91C_BASE_MCI1 (AT91C_CAST(AT91PS_MCI) 0xFFFD0000) // (MCI1) Base Address +#define AT91C_BASE_TWI0 (AT91C_CAST(AT91PS_TWI) 0xFFF84000) // (TWI0) Base Address +#define AT91C_BASE_TWI1 (AT91C_CAST(AT91PS_TWI) 0xFFF88000) // (TWI1) Base Address +#define AT91C_BASE_PDC_US0 (AT91C_CAST(AT91PS_PDC) 0xFFF8C100) // (PDC_US0) Base Address +#define AT91C_BASE_US0 (AT91C_CAST(AT91PS_USART) 0xFFF8C000) // (US0) Base Address +#define AT91C_BASE_PDC_US1 (AT91C_CAST(AT91PS_PDC) 0xFFF90100) // (PDC_US1) Base Address +#define AT91C_BASE_US1 (AT91C_CAST(AT91PS_USART) 0xFFF90000) // (US1) Base Address +#define AT91C_BASE_PDC_US2 (AT91C_CAST(AT91PS_PDC) 0xFFF94100) // (PDC_US2) Base Address +#define AT91C_BASE_US2 (AT91C_CAST(AT91PS_USART) 0xFFF94000) // (US2) Base Address +#define AT91C_BASE_PDC_US3 (AT91C_CAST(AT91PS_PDC) 0xFFF98100) // (PDC_US3) Base Address +#define AT91C_BASE_US3 (AT91C_CAST(AT91PS_USART) 0xFFF98000) // (US3) Base Address +#define AT91C_BASE_PDC_SSC0 (AT91C_CAST(AT91PS_PDC) 0xFFF9C100) // (PDC_SSC0) Base Address +#define AT91C_BASE_SSC0 (AT91C_CAST(AT91PS_SSC) 0xFFF9C000) // (SSC0) Base Address +#define AT91C_BASE_PDC_SSC1 (AT91C_CAST(AT91PS_PDC) 0xFFFA0100) // (PDC_SSC1) Base Address +#define AT91C_BASE_SSC1 (AT91C_CAST(AT91PS_SSC) 0xFFFA0000) // (SSC1) Base Address +#define AT91C_BASE_PWMC_CH0 (AT91C_CAST(AT91PS_PWMC_CH) 0xFFFB8200) // (PWMC_CH0) Base Address +#define AT91C_BASE_PWMC_CH1 (AT91C_CAST(AT91PS_PWMC_CH) 0xFFFB8220) // (PWMC_CH1) Base Address +#define AT91C_BASE_PWMC_CH2 (AT91C_CAST(AT91PS_PWMC_CH) 0xFFFB8240) // (PWMC_CH2) Base Address +#define AT91C_BASE_PWMC_CH3 (AT91C_CAST(AT91PS_PWMC_CH) 0xFFFB8260) // (PWMC_CH3) Base Address +#define AT91C_BASE_PWMC (AT91C_CAST(AT91PS_PWMC) 0xFFFB8000) // (PWMC) Base Address +#define AT91C_BASE_PDC_SPI0 (AT91C_CAST(AT91PS_PDC) 0xFFFA4100) // (PDC_SPI0) Base Address +#define AT91C_BASE_PDC_SPI1 (AT91C_CAST(AT91PS_PDC) 0xFFFA8100) // (PDC_SPI1) Base Address +#define AT91C_BASE_SPI0 (AT91C_CAST(AT91PS_SPI) 0xFFFA4000) // (SPI0) Base Address +#define AT91C_BASE_SPI1 (AT91C_CAST(AT91PS_SPI) 0xFFFA8000) // (SPI1) Base Address +#define AT91C_BASE_PDC_TSADC (AT91C_CAST(AT91PS_PDC) 0xFFFB0100) // (PDC_TSADC) Base Address +#define AT91C_BASE_TSADC (AT91C_CAST(AT91PS_TSADC) 0xFFFB0000) // (TSADC) Base Address +#define AT91C_BASE_UDPHS_EPTFIFO (AT91C_CAST(AT91PS_UDPHS_EPTFIFO) 0x00600000) // (UDPHS_EPTFIFO) Base Address +#define AT91C_BASE_UDPHS_EPT_0 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF78100) // (UDPHS_EPT_0) Base Address +#define AT91C_BASE_UDPHS_EPT_1 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF78120) // (UDPHS_EPT_1) Base Address +#define AT91C_BASE_UDPHS_EPT_2 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF78140) // (UDPHS_EPT_2) Base Address +#define AT91C_BASE_UDPHS_EPT_3 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF78160) // (UDPHS_EPT_3) Base Address +#define AT91C_BASE_UDPHS_EPT_4 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF78180) // (UDPHS_EPT_4) Base Address +#define AT91C_BASE_UDPHS_EPT_5 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF781A0) // (UDPHS_EPT_5) Base Address +#define AT91C_BASE_UDPHS_EPT_6 (AT91C_CAST(AT91PS_UDPHS_EPT) 0xFFF781C0) // (UDPHS_EPT_6) Base Address +#define AT91C_BASE_UDPHS_DMA_1 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78310) // (UDPHS_DMA_1) Base Address +#define AT91C_BASE_UDPHS_DMA_2 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78320) // (UDPHS_DMA_2) Base Address +#define AT91C_BASE_UDPHS_DMA_3 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78330) // (UDPHS_DMA_3) Base Address +#define AT91C_BASE_UDPHS_DMA_4 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78340) // (UDPHS_DMA_4) Base Address +#define AT91C_BASE_UDPHS_DMA_5 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78350) // (UDPHS_DMA_5) Base Address +#define AT91C_BASE_UDPHS_DMA_6 (AT91C_CAST(AT91PS_UDPHS_DMA) 0xFFF78360) // (UDPHS_DMA_6) Base Address +#define AT91C_BASE_UDPHS (AT91C_CAST(AT91PS_UDPHS) 0xFFF78000) // (UDPHS) Base Address +#define AT91C_BASE_PDC_AC97C (AT91C_CAST(AT91PS_PDC) 0xFFFAC100) // (PDC_AC97C) Base Address +#define AT91C_BASE_AC97C (AT91C_CAST(AT91PS_AC97C) 0xFFFAC000) // (AC97C) Base Address +#define AT91C_BASE_LCDC (AT91C_CAST(AT91PS_LCDC) 0x00500000) // (LCDC) Base Address +#define AT91C_BASE_LCDC_16B_TFT (AT91C_CAST(AT91PS_LCDC) 0x00500000) // (LCDC_16B_TFT) Base Address +#define AT91C_BASE_HDMA_CH_0 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFEC3C) // (HDMA_CH_0) Base Address +#define AT91C_BASE_HDMA_CH_1 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFEC64) // (HDMA_CH_1) Base Address +#define AT91C_BASE_HDMA_CH_2 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFEC8C) // (HDMA_CH_2) Base Address +#define AT91C_BASE_HDMA_CH_3 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFECB4) // (HDMA_CH_3) Base Address +#define AT91C_BASE_HDMA_CH_4 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFECDC) // (HDMA_CH_4) Base Address +#define AT91C_BASE_HDMA_CH_5 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFED04) // (HDMA_CH_5) Base Address +#define AT91C_BASE_HDMA_CH_6 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFED2C) // (HDMA_CH_6) Base Address +#define AT91C_BASE_HDMA_CH_7 (AT91C_CAST(AT91PS_HDMA_CH) 0xFFFFED54) // (HDMA_CH_7) Base Address +#define AT91C_BASE_HDMA (AT91C_CAST(AT91PS_HDMA) 0xFFFFEC00) // (HDMA) Base Address +#define AT91C_BASE_HECC (AT91C_CAST(AT91PS_ECC) 0xFFFFE200) // (HECC) Base Address +#define AT91C_BASE_EMACB (AT91C_CAST(AT91PS_EMAC) 0xFFFBC000) // (EMACB) Base Address +#define AT91C_BASE_ISI (AT91C_CAST(AT91PS_ISI) 0xFFFB4000) // (ISI) Base Address +#define AT91C_BASE_UHPHS_OHCI (AT91C_CAST(AT91PS_UHPHS_OHCI) 0x00700000) // (UHPHS_OHCI) Base Address +#define AT91C_BASE_UHPHS_EHCI (AT91C_CAST(AT91PS_UHPHS_EHCI) 0x00800000) // (UHPHS_EHCI) Base Address +#define AT91C_BASE_TRNG (AT91C_CAST(AT91PS_TRNG) 0xFFFCC000) // (TRNG) Base Address + +// ***************************************************************************** +// MEMORY MAPPING DEFINITIONS FOR AT91SAM9G45 +// ***************************************************************************** +// ITCM +#define AT91C_ITCM (0x00100000) // Maximum ITCM Area base address +// DTCM +#define AT91C_DTCM (0x00200000) // Maximum DTCM Area base address +// IRAM +#define AT91C_IRAM (0x00300000) // Maximum Internal SRAM base address +#define AT91C_IRAM_SIZE (0x00010000) // Maximum Internal SRAM size in byte (64 Kbytes) +// IRAM_MIN +#define AT91C_IRAM_MIN (0x00300000) // Minimum Internal RAM base address +#define AT91C_IRAM_MIN_SIZE (0x00004000) // Minimum Internal RAM size in byte (16 Kbytes) +// IROM +#define AT91C_IROM (0x00400000) // Internal ROM base address +#define AT91C_IROM_SIZE (0x00010000) // Internal ROM size in byte (64 Kbytes) +// EBI_CS0 +#define AT91C_EBI_CS0 (0x10000000) // EBI Chip Select 0 base address +#define AT91C_EBI_CS0_SIZE (0x10000000) // EBI Chip Select 0 size in byte (262144 Kbytes) +// EBI_CS1 +#define AT91C_EBI_CS1 (0x20000000) // EBI Chip Select 1 base address +#define AT91C_EBI_CS1_SIZE (0x10000000) // EBI Chip Select 1 size in byte (262144 Kbytes) +// EBI_SDRAM +#define AT91C_EBI_SDRAM (0x20000000) // SDRAM on EBI Chip Select 1 base address +#define AT91C_EBI_SDRAM_SIZE (0x10000000) // SDRAM on EBI Chip Select 1 size in byte (262144 Kbytes) +// EBI_SDRAM_16BIT +#define AT91C_EBI_SDRAM_16BIT (0x20000000) // SDRAM on EBI Chip Select 1 base address +#define AT91C_EBI_SDRAM_16BIT_SIZE (0x02000000) // SDRAM on EBI Chip Select 1 size in byte (32768 Kbytes) +// EBI_SDRAM_32BIT +#define AT91C_EBI_SDRAM_32BIT (0x20000000) // SDRAM on EBI Chip Select 1 base address +#define AT91C_EBI_SDRAM_32BIT_SIZE (0x04000000) // SDRAM on EBI Chip Select 1 size in byte (65536 Kbytes) +// EBI_CS2 +#define AT91C_EBI_CS2 (0x30000000) // EBI Chip Select 2 base address +#define AT91C_EBI_CS2_SIZE (0x10000000) // EBI Chip Select 2 size in byte (262144 Kbytes) +// EBI_CS3 +#define AT91C_EBI_CS3 (0x40000000) // EBI Chip Select 3 base address +#define AT91C_EBI_CS3_SIZE (0x10000000) // EBI Chip Select 3 size in byte (262144 Kbytes) +// EBI_SM +#define AT91C_EBI_SM (0x40000000) // NANDFLASH on EBI Chip Select 3 base address +#define AT91C_EBI_SM_SIZE (0x10000000) // NANDFLASH on EBI Chip Select 3 size in byte (262144 Kbytes) +// EBI_CS4 +#define AT91C_EBI_CS4 (0x50000000) // EBI Chip Select 4 base address +#define AT91C_EBI_CS4_SIZE (0x10000000) // EBI Chip Select 4 size in byte (262144 Kbytes) +// EBI_CF0 +#define AT91C_EBI_CF0 (0x50000000) // CompactFlash 0 on EBI Chip Select 4 base address +#define AT91C_EBI_CF0_SIZE (0x10000000) // CompactFlash 0 on EBI Chip Select 4 size in byte (262144 Kbytes) +// EBI_CS5 +#define AT91C_EBI_CS5 (0x60000000) // EBI Chip Select 5 base address +#define AT91C_EBI_CS5_SIZE (0x10000000) // EBI Chip Select 5 size in byte (262144 Kbytes) +// EBI_CF1 +#define AT91C_EBI_CF1 (0x60000000) // CompactFlash 1 on EBIChip Select 5 base address +#define AT91C_EBI_CF1_SIZE (0x10000000) // CompactFlash 1 on EBIChip Select 5 size in byte (262144 Kbytes) +// DDR2 +#define AT91C_DDR2 (0x70000000) // DDR2/LPDDR space base address +#define AT91C_DDR2_SIZE (0x10000000) // DDR2/LPDDR space size in byte (262144 Kbytes) + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "io.h" +#include "irq.h" +#include "gpio.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +extern struct clk *clk_get(const char *id); +extern rt_uint32_t clk_get_rate(struct clk *clk); +extern void rt_hw_clock_init(void); + +#define AT91C_SLOW_CLOCK 32768 /* slow clock */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/at91sam9g45/platform/gpio.h b/bsp/at91sam9g45/platform/gpio.h new file mode 100644 index 0000000000..f0c53b5271 --- /dev/null +++ b/bsp/at91sam9g45/platform/gpio.h @@ -0,0 +1,208 @@ +/* + * File : gpio.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + */ + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#include + +#define PIN_BASE AIC_IRQS + +#define MAX_GPIO_BANKS 5 + +#define PIN_IRQS (MAX_GPIO_BANKS*32) + +/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ + +#define AT91C_PIN_PA0 (PIN_BASE + 0x00 + 0) +#define AT91C_PIN_PA1 (PIN_BASE + 0x00 + 1) +#define AT91C_PIN_PA2 (PIN_BASE + 0x00 + 2) +#define AT91C_PIN_PA3 (PIN_BASE + 0x00 + 3) +#define AT91C_PIN_PA4 (PIN_BASE + 0x00 + 4) +#define AT91C_PIN_PA5 (PIN_BASE + 0x00 + 5) +#define AT91C_PIN_PA6 (PIN_BASE + 0x00 + 6) +#define AT91C_PIN_PA7 (PIN_BASE + 0x00 + 7) +#define AT91C_PIN_PA8 (PIN_BASE + 0x00 + 8) +#define AT91C_PIN_PA9 (PIN_BASE + 0x00 + 9) +#define AT91C_PIN_PA10 (PIN_BASE + 0x00 + 10) +#define AT91C_PIN_PA11 (PIN_BASE + 0x00 + 11) +#define AT91C_PIN_PA12 (PIN_BASE + 0x00 + 12) +#define AT91C_PIN_PA13 (PIN_BASE + 0x00 + 13) +#define AT91C_PIN_PA14 (PIN_BASE + 0x00 + 14) +#define AT91C_PIN_PA15 (PIN_BASE + 0x00 + 15) +#define AT91C_PIN_PA16 (PIN_BASE + 0x00 + 16) +#define AT91C_PIN_PA17 (PIN_BASE + 0x00 + 17) +#define AT91C_PIN_PA18 (PIN_BASE + 0x00 + 18) +#define AT91C_PIN_PA19 (PIN_BASE + 0x00 + 19) +#define AT91C_PIN_PA20 (PIN_BASE + 0x00 + 20) +#define AT91C_PIN_PA21 (PIN_BASE + 0x00 + 21) +#define AT91C_PIN_PA22 (PIN_BASE + 0x00 + 22) +#define AT91C_PIN_PA23 (PIN_BASE + 0x00 + 23) +#define AT91C_PIN_PA24 (PIN_BASE + 0x00 + 24) +#define AT91C_PIN_PA25 (PIN_BASE + 0x00 + 25) +#define AT91C_PIN_PA26 (PIN_BASE + 0x00 + 26) +#define AT91C_PIN_PA27 (PIN_BASE + 0x00 + 27) +#define AT91C_PIN_PA28 (PIN_BASE + 0x00 + 28) +#define AT91C_PIN_PA29 (PIN_BASE + 0x00 + 29) +#define AT91C_PIN_PA30 (PIN_BASE + 0x00 + 30) +#define AT91C_PIN_PA31 (PIN_BASE + 0x00 + 31) + +#define AT91C_PIN_PB0 (PIN_BASE + 0x20 + 0) +#define AT91C_PIN_PB1 (PIN_BASE + 0x20 + 1) +#define AT91C_PIN_PB2 (PIN_BASE + 0x20 + 2) +#define AT91C_PIN_PB3 (PIN_BASE + 0x20 + 3) +#define AT91C_PIN_PB4 (PIN_BASE + 0x20 + 4) +#define AT91C_PIN_PB5 (PIN_BASE + 0x20 + 5) +#define AT91C_PIN_PB6 (PIN_BASE + 0x20 + 6) +#define AT91C_PIN_PB7 (PIN_BASE + 0x20 + 7) +#define AT91C_PIN_PB8 (PIN_BASE + 0x20 + 8) +#define AT91C_PIN_PB9 (PIN_BASE + 0x20 + 9) +#define AT91C_PIN_PB10 (PIN_BASE + 0x20 + 10) +#define AT91C_PIN_PB11 (PIN_BASE + 0x20 + 11) +#define AT91C_PIN_PB12 (PIN_BASE + 0x20 + 12) +#define AT91C_PIN_PB13 (PIN_BASE + 0x20 + 13) +#define AT91C_PIN_PB14 (PIN_BASE + 0x20 + 14) +#define AT91C_PIN_PB15 (PIN_BASE + 0x20 + 15) +#define AT91C_PIN_PB16 (PIN_BASE + 0x20 + 16) +#define AT91C_PIN_PB17 (PIN_BASE + 0x20 + 17) +#define AT91C_PIN_PB18 (PIN_BASE + 0x20 + 18) +#define AT91C_PIN_PB19 (PIN_BASE + 0x20 + 19) +#define AT91C_PIN_PB20 (PIN_BASE + 0x20 + 20) +#define AT91C_PIN_PB21 (PIN_BASE + 0x20 + 21) +#define AT91C_PIN_PB22 (PIN_BASE + 0x20 + 22) +#define AT91C_PIN_PB23 (PIN_BASE + 0x20 + 23) +#define AT91C_PIN_PB24 (PIN_BASE + 0x20 + 24) +#define AT91C_PIN_PB25 (PIN_BASE + 0x20 + 25) +#define AT91C_PIN_PB26 (PIN_BASE + 0x20 + 26) +#define AT91C_PIN_PB27 (PIN_BASE + 0x20 + 27) +#define AT91C_PIN_PB28 (PIN_BASE + 0x20 + 28) +#define AT91C_PIN_PB29 (PIN_BASE + 0x20 + 29) +#define AT91C_PIN_PB30 (PIN_BASE + 0x20 + 30) +#define AT91C_PIN_PB31 (PIN_BASE + 0x20 + 31) + +#define AT91C_PIN_PC0 (PIN_BASE + 0x40 + 0) +#define AT91C_PIN_PC1 (PIN_BASE + 0x40 + 1) +#define AT91C_PIN_PC2 (PIN_BASE + 0x40 + 2) +#define AT91C_PIN_PC3 (PIN_BASE + 0x40 + 3) +#define AT91C_PIN_PC4 (PIN_BASE + 0x40 + 4) +#define AT91C_PIN_PC5 (PIN_BASE + 0x40 + 5) +#define AT91C_PIN_PC6 (PIN_BASE + 0x40 + 6) +#define AT91C_PIN_PC7 (PIN_BASE + 0x40 + 7) +#define AT91C_PIN_PC8 (PIN_BASE + 0x40 + 8) +#define AT91C_PIN_PC9 (PIN_BASE + 0x40 + 9) +#define AT91C_PIN_PC10 (PIN_BASE + 0x40 + 10) +#define AT91C_PIN_PC11 (PIN_BASE + 0x40 + 11) +#define AT91C_PIN_PC12 (PIN_BASE + 0x40 + 12) +#define AT91C_PIN_PC13 (PIN_BASE + 0x40 + 13) +#define AT91C_PIN_PC14 (PIN_BASE + 0x40 + 14) +#define AT91C_PIN_PC15 (PIN_BASE + 0x40 + 15) +#define AT91C_PIN_PC16 (PIN_BASE + 0x40 + 16) +#define AT91C_PIN_PC17 (PIN_BASE + 0x40 + 17) +#define AT91C_PIN_PC18 (PIN_BASE + 0x40 + 18) +#define AT91C_PIN_PC19 (PIN_BASE + 0x40 + 19) +#define AT91C_PIN_PC20 (PIN_BASE + 0x40 + 20) +#define AT91C_PIN_PC21 (PIN_BASE + 0x40 + 21) +#define AT91C_PIN_PC22 (PIN_BASE + 0x40 + 22) +#define AT91C_PIN_PC23 (PIN_BASE + 0x40 + 23) +#define AT91C_PIN_PC24 (PIN_BASE + 0x40 + 24) +#define AT91C_PIN_PC25 (PIN_BASE + 0x40 + 25) +#define AT91C_PIN_PC26 (PIN_BASE + 0x40 + 26) +#define AT91C_PIN_PC27 (PIN_BASE + 0x40 + 27) +#define AT91C_PIN_PC28 (PIN_BASE + 0x40 + 28) +#define AT91C_PIN_PC29 (PIN_BASE + 0x40 + 29) +#define AT91C_PIN_PC30 (PIN_BASE + 0x40 + 30) +#define AT91C_PIN_PC31 (PIN_BASE + 0x40 + 31) + +#define AT91C_PIN_PD0 (PIN_BASE + 0x60 + 0) +#define AT91C_PIN_PD1 (PIN_BASE + 0x60 + 1) +#define AT91C_PIN_PD2 (PIN_BASE + 0x60 + 2) +#define AT91C_PIN_PD3 (PIN_BASE + 0x60 + 3) +#define AT91C_PIN_PD4 (PIN_BASE + 0x60 + 4) +#define AT91C_PIN_PD5 (PIN_BASE + 0x60 + 5) +#define AT91C_PIN_PD6 (PIN_BASE + 0x60 + 6) +#define AT91C_PIN_PD7 (PIN_BASE + 0x60 + 7) +#define AT91C_PIN_PD8 (PIN_BASE + 0x60 + 8) +#define AT91C_PIN_PD9 (PIN_BASE + 0x60 + 9) +#define AT91C_PIN_PD10 (PIN_BASE + 0x60 + 10) +#define AT91C_PIN_PD11 (PIN_BASE + 0x60 + 11) +#define AT91C_PIN_PD12 (PIN_BASE + 0x60 + 12) +#define AT91C_PIN_PD13 (PIN_BASE + 0x60 + 13) +#define AT91C_PIN_PD14 (PIN_BASE + 0x60 + 14) +#define AT91C_PIN_PD15 (PIN_BASE + 0x60 + 15) +#define AT91C_PIN_PD16 (PIN_BASE + 0x60 + 16) +#define AT91C_PIN_PD17 (PIN_BASE + 0x60 + 17) +#define AT91C_PIN_PD18 (PIN_BASE + 0x60 + 18) +#define AT91C_PIN_PD19 (PIN_BASE + 0x60 + 19) +#define AT91C_PIN_PD20 (PIN_BASE + 0x60 + 20) +#define AT91C_PIN_PD21 (PIN_BASE + 0x60 + 21) +#define AT91C_PIN_PD22 (PIN_BASE + 0x60 + 22) +#define AT91C_PIN_PD23 (PIN_BASE + 0x60 + 23) +#define AT91C_PIN_PD24 (PIN_BASE + 0x60 + 24) +#define AT91C_PIN_PD25 (PIN_BASE + 0x60 + 25) +#define AT91C_PIN_PD26 (PIN_BASE + 0x60 + 26) +#define AT91C_PIN_PD27 (PIN_BASE + 0x60 + 27) +#define AT91C_PIN_PD28 (PIN_BASE + 0x60 + 28) +#define AT91C_PIN_PD29 (PIN_BASE + 0x60 + 29) +#define AT91C_PIN_PD30 (PIN_BASE + 0x60 + 30) +#define AT91C_PIN_PD31 (PIN_BASE + 0x60 + 31) + +#define AT91C_PIN_PE0 (PIN_BASE + 0x80 + 0) +#define AT91C_PIN_PE1 (PIN_BASE + 0x80 + 1) +#define AT91C_PIN_PE2 (PIN_BASE + 0x80 + 2) +#define AT91C_PIN_PE3 (PIN_BASE + 0x80 + 3) +#define AT91C_PIN_PE4 (PIN_BASE + 0x80 + 4) +#define AT91C_PIN_PE5 (PIN_BASE + 0x80 + 5) +#define AT91C_PIN_PE6 (PIN_BASE + 0x80 + 6) +#define AT91C_PIN_PE7 (PIN_BASE + 0x80 + 7) +#define AT91C_PIN_PE8 (PIN_BASE + 0x80 + 8) +#define AT91C_PIN_PE9 (PIN_BASE + 0x80 + 9) +#define AT91C_PIN_PE10 (PIN_BASE + 0x80 + 10) +#define AT91C_PIN_PE11 (PIN_BASE + 0x80 + 11) +#define AT91C_PIN_PE12 (PIN_BASE + 0x80 + 12) +#define AT91C_PIN_PE13 (PIN_BASE + 0x80 + 13) +#define AT91C_PIN_PE14 (PIN_BASE + 0x80 + 14) +#define AT91C_PIN_PE15 (PIN_BASE + 0x80 + 15) +#define AT91C_PIN_PE16 (PIN_BASE + 0x80 + 16) +#define AT91C_PIN_PE17 (PIN_BASE + 0x80 + 17) +#define AT91C_PIN_PE18 (PIN_BASE + 0x80 + 18) +#define AT91C_PIN_PE19 (PIN_BASE + 0x80 + 19) +#define AT91C_PIN_PE20 (PIN_BASE + 0x80 + 20) +#define AT91C_PIN_PE21 (PIN_BASE + 0x80 + 21) +#define AT91C_PIN_PE22 (PIN_BASE + 0x80 + 22) +#define AT91C_PIN_PE23 (PIN_BASE + 0x80 + 23) +#define AT91C_PIN_PE24 (PIN_BASE + 0x80 + 24) +#define AT91C_PIN_PE25 (PIN_BASE + 0x80 + 25) +#define AT91C_PIN_PE26 (PIN_BASE + 0x80 + 26) +#define AT91C_PIN_PE27 (PIN_BASE + 0x80 + 27) +#define AT91C_PIN_PE28 (PIN_BASE + 0x80 + 28) +#define AT91C_PIN_PE29 (PIN_BASE + 0x80 + 29) +#define AT91C_PIN_PE30 (PIN_BASE + 0x80 + 30) +#define AT91C_PIN_PE31 (PIN_BASE + 0x80 + 31) + +rt_inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio) +{ + return gpio; +} + +#endif diff --git a/bsp/at91sam9g45/platform/interrupt.c b/bsp/at91sam9g45/platform/interrupt.c new file mode 100644 index 0000000000..b19bcb3bde --- /dev/null +++ b/bsp/at91sam9g45/platform/interrupt.c @@ -0,0 +1,453 @@ +/* + * File : interrupt.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + */ + +#include +#include "at91sam9g45.h" +#include "interrupt.h" + +#define AIC_IRQS 32 +#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) + +extern rt_uint32_t rt_interrupt_nest; + +/* exception and interrupt handler table */ +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +rt_uint32_t at91_extern_irq; + +#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static rt_uint32_t at91sam9g45_default_irq_priority[MAX_HANDLERS] = { + 7, /* Advanced Interrupt Controller - FIQ */ + 7, /* System Controller Interrupt */ + 1, /* Parallel I/O Controller A, */ + 1, /* Parallel I/O Controller B */ + 1, /* Parallel I/O Controller C */ + 0, /* Parallel I/O Controller D/E */ + 5, /* True Random Number Generator */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 0, /* USART 2 */ + 2, /* USART 3 */ + 6, /* High Speed Multimedia Card Interface 0 */ + 5, /* Two-Wire Interface 0 */ + 5, /* Two-Wire Interface 1 */ + 5, /* Serial Peripheral Interface */ + 0, /* Serial Peripheral Interface */ + 0, /* Synchronous Serial Controller 0 */ + 0, /* Synchronous Serial Controller 1 */ + 0, /* Timer Counter 0,1,2,3,4,5 */ + 0, /* Pulse Width Modulation Controller */ + 2, /* Touch Screen ADC Controller */ + 3, /* DMA Controller */ + 0, /* USB Host High Speed */ + 5, /* LCD Controller */ + 5, /* AC97 Controller */ + 5, /* Ethernet MAC */ + 0, /* Image Sensor Interface */ + 0, /* USB Device High Speed */ + 0, /* N/A */ + 0, /* High Speed Multimedia Card Interface 1 */ + 0, /* Reserved */ + 0, /* Advanced Interrupt Controller - IRQ */ +}; + +/** + * @addtogroup AT91SAM9G45 + */ +/*@{*/ + +void rt_hw_interrupt_mask(int irq); +void rt_hw_interrupt_umask(int irq); + +rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) +{ + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + return RT_NULL; +} + +rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t bank, void *param) +{ + rt_uint32_t isr, irq_n; + AT91PS_PIO pio; + void *parameter; + + switch (bank) + { + case 0: pio = AT91C_BASE_PIOA; break; + case 1: pio = AT91C_BASE_PIOB; break; + case 2: pio = AT91C_BASE_PIOC; break; + case 3: pio = AT91C_BASE_PIOD; break; + case 4: pio = AT91C_BASE_PIOE; break; + default: return RT_NULL; + } + irq_n = AIC_IRQS + 32*bank; + isr = readl(pio->PIO_ISR); + isr &= readl(pio->PIO_IMR); + while (isr) + { + if (isr & 1) + { + parameter = irq_desc[irq_n].param; + irq_desc[irq_n].handler(irq_n, parameter); + } + isr >>= 1; + irq_n++; + } + + return RT_NULL; +} + +unsigned int SpuriousCount = 0; +static void DefaultSpuriousHandler( void ) +{ + SpuriousCount++; + rt_kprintf("Spurious interrupt %d occured!!!\n", SpuriousCount); + return ; +} + +static void DefaultFiqHandler(void) +{ + rt_kprintf("Unhandled FIQ occured!!!\n"); + while (1); +} + +static void DefaultIrqHandler(void) +{ + rt_kprintf("Unhandled IRQ %d occured!!!\n", AT91C_BASE_AIC->AIC_ISR); + while (1); +} + +/* + * Initialize the AIC interrupt controller. + */ +void at91_aic_init(rt_uint32_t *priority) +{ + rt_uint32_t i; + + /* + * The IVR is used by macro get_irqnr_and_base to read and verify. + * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. + */ + AT91C_BASE_AIC->AIC_SVR[0] = (rt_uint32_t)DefaultFiqHandler; + for (i = 1; i < AIC_IRQS; i++) { + /* Put irq number in Source Vector Register: */ + AT91C_BASE_AIC->AIC_SVR[i] = (rt_uint32_t)DefaultIrqHandler; // no-used + /* Active Low interrupt, with the specified priority */ + AT91C_BASE_AIC->AIC_SMR[i] = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | priority[i]; + //AT91C_AIC_SRCTYPE_FALLING + } + + /* + * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS + * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU + */ + AT91C_BASE_AIC->AIC_SPU = (rt_uint32_t)DefaultSpuriousHandler; + + /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ + for (i = 0; i < 8; i++) + AT91C_BASE_AIC->AIC_EOICR = 0; + + /* No debugging in AIC: Debug (Protect) Control Register */ + AT91C_BASE_AIC->AIC_DCR = 0; + + /* Disable and clear all interrupts initially */ + AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; + AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF; +} + + +static void at91_gpio_irq_init() +{ + int i, idx; + char *name[] = {"PIOA", "PIOB", "PIOC", "PIODE"}; + rt_uint32_t aic_pids[] = { AT91C_ID_PIOA, AT91C_ID_PIOB, AT91C_ID_PIOC, AT91C_ID_PIOD_E }; + + AT91C_BASE_PIOA->PIO_IDR = 0xffffffff; + AT91C_BASE_PIOB->PIO_IDR = 0xffffffff; + AT91C_BASE_PIOC->PIO_IDR = 0xffffffff; + AT91C_BASE_PIOD->PIO_IDR = 0xffffffff; + AT91C_BASE_PIOE->PIO_IDR = 0xffffffff; + + for (i = 0; i < 4; i++) + { + idx = aic_pids[i]; + irq_desc[idx].handler = (rt_isr_handler_t)at91_gpio_irq_handle; + irq_desc[idx].param = RT_NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, name[i]); + irq_desc[idx].counter = 0; +#endif + + rt_hw_interrupt_umask(idx); + } +} + + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + register rt_uint32_t idx; + rt_uint32_t *priority = at91sam9g45_default_irq_priority; + + at91_extern_irq = (1UL << AT91C_ID_IRQ0); + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* init exceptions table */ + for(idx=0; idx < MAX_HANDLERS; idx++) + { + irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[idx].param = RT_NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].counter = 0; +#endif + } + + at91_gpio_irq_init(); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +static void at91_gpio_irq_mask(int irq) +{ + rt_uint32_t pin, bank; + AT91PS_PIO pio; + + bank = (irq - AIC_IRQS)>>5; + + switch (bank) + { + case 0: pio = AT91C_BASE_PIOA; break; + case 1: pio = AT91C_BASE_PIOB; break; + case 2: pio = AT91C_BASE_PIOC; break; + case 3: pio = AT91C_BASE_PIOD; break; + case 4: pio = AT91C_BASE_PIOE; break; + default: return; + } + pin = 1 << ((irq - AIC_IRQS) & 31); + pio->PIO_IDR = pin; +} + +/** + * This function will mask a interrupt. + * @param irq the interrupt number + */ +void rt_hw_interrupt_mask(int irq) +{ + if (irq >= AIC_IRQS) + { + at91_gpio_irq_mask(irq); + } + else + { + /* Disable interrupt on AIC */ + AT91C_BASE_AIC->AIC_IDCR = 1 << irq; + } +} + +static void at91_gpio_irq_umask(int irq) +{ + rt_uint32_t pin, bank; + AT91PS_PIO pio; + + bank = (irq - AIC_IRQS)>>5; + + switch (bank) + { + case 0: pio = AT91C_BASE_PIOA; break; + case 1: pio = AT91C_BASE_PIOB; break; + case 2: pio = AT91C_BASE_PIOC; break; + case 3: pio = AT91C_BASE_PIOD; break; + case 4: pio = AT91C_BASE_PIOE; break; + default: return; + } + pin = 1 << ((irq - AIC_IRQS) & 31); + pio->PIO_IER = pin; +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int irq) +{ + if (irq >= AIC_IRQS) + { + at91_gpio_irq_umask(irq); + } + else + { + /* Enable interrupt on AIC */ + AT91C_BASE_AIC->AIC_IECR = 1 << irq; + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param handler the interrupt service routine to be installed + * @param param the interrupt service function parameter + * @param name the interrupt name + * @return old handler + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + irq_desc[vector].handler = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); + irq_desc[vector].counter = 0; +#endif + } + } + + return old_handler; +} + +/*@}*/ + +/* +static int at91_aic_set_type(unsigned irq, unsigned type) +{ + unsigned int smr, srctype; + + switch (type) { + case AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL: + srctype = AT91C_AIC_SRCTYPE_HIGH; + break; + case AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE: + srctype = AT91C_AIC_SRCTYPE_RISING; + break; + case AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE: + // only supported on external interrupts + if ((irq == AT91C_ID_FIQ) || is_extern_irq(irq)) + srctype = AT91C_AIC_SRCTYPE_LOW; + else + return -1; + break; + case AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED: + // only supported on external interrupts + if ((irq == AT91C_ID_FIQ) || is_extern_irq(irq)) + srctype = AT91C_AIC_SRCTYPE_FALLING; + else + return -1; + break; + default: + return -1; + } + + smr = readl(AT91C_AIC_SMR(irq)) & ~AT91C_AIC_SRCTYPE; + AT91C_BASE_AIC->AIC_SMR[irq] = smr | srctype; + return 0; +} +*/ +rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq) +{ + + //volatile rt_uint32_t irqstat; + rt_uint32_t id; + if (fiq_irq == INT_FIQ) + return 0; + + //IRQ + /* AIC need this dummy read */ + readl(AT91C_AIC_IVR); + /* clear pending register */ + id = readl(AT91C_AIC_ISR); + + return id; +} + +void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id) +{ + /* new FIQ generation */ + if (fiq_irq == INT_FIQ) + return; + + /* new IRQ generation */ + // EIOCR must be write any value after interrupt, + // or else can't response next interrupt + AT91C_BASE_AIC->AIC_EOICR = 0x0; +} + +#ifdef RT_USING_FINSH +#ifdef RT_USING_INTERRUPT_INFO +void list_irq(void) +{ + int irq; + + rt_kprintf("number\tcount\tname\n"); + for (irq = 0; irq < MAX_HANDLERS; irq++) + { + if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default"))) + { + rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name); + } + } +} + +#include +FINSH_FUNCTION_EXPORT(list_irq, list system irq); + +#ifdef FINSH_USING_MSH +int cmd_list_irq(int argc, char** argv) +{ + list_irq(); + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_list_irq, __cmd_list_irq, list system irq.); + +#endif +#endif +#endif + + diff --git a/bsp/at91sam9g45/platform/interrupt.h b/bsp/at91sam9g45/platform/interrupt.h new file mode 100644 index 0000000000..7780e7a3a8 --- /dev/null +++ b/bsp/at91sam9g45/platform/interrupt.h @@ -0,0 +1,31 @@ +/* + * File : interrupt.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, 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 + * 2015-04-14 ArdaFu first version + */ +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + + +#endif diff --git a/bsp/at91sam9g45/platform/io.h b/bsp/at91sam9g45/platform/io.h new file mode 100644 index 0000000000..80919c52cb --- /dev/null +++ b/bsp/at91sam9g45/platform/io.h @@ -0,0 +1,39 @@ +/* + * File : io.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-01-13 weety first version + */ + +#ifndef __ASM_ARCH_IO_H +#define __ASM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xFFFFFFFF + +#define readb(a) (*(volatile unsigned char *)(a)) +#define readw(a) (*(volatile unsigned short *)(a)) +#define readl(a) (*(volatile unsigned int *)(a)) + +#define writeb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define writew(v,a) (*(volatile unsigned short *)(a) = (v)) +#define writel(v,a) (*(volatile unsigned int *)(a) = (v)) + +#endif + diff --git a/bsp/at91sam9g45/platform/irq.h b/bsp/at91sam9g45/platform/irq.h new file mode 100644 index 0000000000..fe1fea41d0 --- /dev/null +++ b/bsp/at91sam9g45/platform/irq.h @@ -0,0 +1,52 @@ +/* + * File : irq.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-01-13 weety first version + */ + +#ifndef __IRQ_H__ +#define __IRQ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * IRQ line status. + * + * Bits 0-7 are reserved + * + * IRQ types + */ +#define IRQ_TYPE_NONE 0x00000000 /* Default, unspecified type */ +#define IRQ_TYPE_EDGE_RISING 0x00000001 /* Edge rising type */ +#define IRQ_TYPE_EDGE_FALLING 0x00000002 /* Edge falling type */ +#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING) +#define IRQ_TYPE_LEVEL_HIGH 0x00000004 /* Level high type */ +#define IRQ_TYPE_LEVEL_LOW 0x00000008 /* Level low type */ +#define IRQ_TYPE_SENSE_MASK 0x0000000f /* Mask of the above */ +#define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/at91sam9g45/platform/reset.c b/bsp/at91sam9g45/platform/reset.c new file mode 100644 index 0000000000..2e7bec1e5d --- /dev/null +++ b/bsp/at91sam9g45/platform/reset.c @@ -0,0 +1,68 @@ +/* + * File : reset.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop 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-01-13 weety modified from mini2440 + */ + +#include +#include +#include "at91sam9g45.h" + +/** + * @addtogroup AT91SAM926X + */ +/*@{*/ + +void machine_reset(void) +{ + AT91C_BASE_RSTC->RSTC_RCR = AT91C_RSTC_KEY | AT91C_RSTC_PROCRST | AT91C_RSTC_PERRST; +} + +void machine_shutdown(void) +{ + AT91C_BASE_SHDWC->SHDWC_SHCR = AT91C_SHDWC_KEY | AT91C_SHDWC_SHDW; +} + +#ifdef RT_USING_FINSH + +#include +FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, reset, restart the system); + +#ifdef FINSH_USING_MSH +int cmd_reset(int argc, char** argv) +{ + rt_hw_cpu_reset(); + return 0; +} + +int cmd_shutdown(int argc, char** argv) +{ + rt_hw_cpu_shutdown(); + return 0; +} + +FINSH_FUNCTION_EXPORT_ALIAS(cmd_reset, __cmd_reset, restart the system.); +FINSH_FUNCTION_EXPORT_ALIAS(cmd_shutdown, __cmd_shutdown, shutdown the system.); + +#endif +#endif + +/*@}*/ diff --git a/bsp/at91sam9g45/platform/rt_low_level_init.c b/bsp/at91sam9g45/platform/rt_low_level_init.c new file mode 100644 index 0000000000..5df468d771 --- /dev/null +++ b/bsp/at91sam9g45/platform/rt_low_level_init.c @@ -0,0 +1,63 @@ +/* + * File : rt_low_level_init.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, 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 + * 2015-04-14 ArdaFu first version + */ + +/* write register a=address, v=value */ +#define write_reg(a,v) (*(volatile unsigned int *)(a) = (v)) +/* Processor Reset */ +#define AT91C_RSTC_PROCRST (1 << 0) +#define AT91C_RSTC_PERRST (1 << 2) +#define AT91C_RSTC_KEY (0xa5 << 24) +#define AT91C_MATRIX_BASE (0XFFFFEE00) +/* Master Remap Control Register */ +#define AT91C_MATRIX_MRCR (AT91C_MATRIX_BASE + 0x100) +/* Remap Command for AHB Master 0 (ARM926EJ-S InSTRuction Master) */ +#define AT91C_MATRIX_RCB0 (1 << 0) +/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91C_MATRIX_RCB1 (1 << 1) + +#define AT91C_AIC_BASE (0XFFFFF000) +/* Interrupt DisaBLe Command Register */ +#define AT91C_AIC_IDCR (AT91C_AIC_BASE + 0x124) +/* Interrupt Clear Command Register */ +#define AT91C_AIC_ICCR (AT91C_AIC_BASE + 0x128) + +#define AT91C_WDT_BASE (0XFFFFFD40) +#define AT91C_WDT_CR (AT91C_WDT_BASE + 0x00) +#define AT91C_WDT_CR_KEY (0xA5000000) +#define AT91C_WDT_CR_WDRSTT (0x00000001) +#define AT91C_WDT_MR (AT91C_WDT_BASE + 0x04) +#define AT91C_WDT_MR_WDDIS (0x00008000) + +void rt_low_level_init(void) +{ + // Mask all IRQs by clearing all bits in the INTMRS + write_reg(AT91C_AIC_IDCR, 0xFFFFFFFF); + write_reg(AT91C_AIC_ICCR, 0xFFFFFFFF); + // Remap internal ram to 0x00000000 Address + write_reg(AT91C_MATRIX_MRCR, AT91C_MATRIX_RCB0 | AT91C_MATRIX_RCB1); + // Disable the watchdog + //write_reg(AT91C_WDT_CR, AT91C_WDT_CR_KEY|AT91C_WDT_CR_WDRSTT); + //write_reg(AT91C_WDT_MR, AT91C_WDT_MR_WDDIS); +} + diff --git a/bsp/at91sam9g45/platform/rt_low_level_init.h b/bsp/at91sam9g45/platform/rt_low_level_init.h new file mode 100644 index 0000000000..86dcfb59dc --- /dev/null +++ b/bsp/at91sam9g45/platform/rt_low_level_init.h @@ -0,0 +1,35 @@ +/* + * File : rt_low_level_init.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, 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-06-04 ArdaFu first version + */ +#ifndef __RT_LOW_LEVEL_INIT_H__ +#define __RT_LOW_LEVEL_INIT_H__ + +/*-------- Stack size of CPU modes -------------------------------------------*/ +#define UND_STK_SIZE 512 +#define SVC_STK_SIZE 4096 +#define ABT_STK_SIZE 512 +#define IRQ_STK_SIZE 1024 +#define FIQ_STK_SIZE 1024 +#define SYS_STK_SIZE 512 +#define Heap_Size 512 +#endif diff --git a/bsp/at91sam9g45/platform/system_clock.c b/bsp/at91sam9g45/platform/system_clock.c new file mode 100644 index 0000000000..59c3c320ab --- /dev/null +++ b/bsp/at91sam9g45/platform/system_clock.c @@ -0,0 +1,270 @@ +/* + * File : clock.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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-01-13 weety first version + */ + +#include +#include "at91sam9g45.h" + +static rt_list_t clocks; + +struct clk { + char name[32]; + rt_uint32_t rate_hz; + struct clk *parent; + rt_list_t node; +}; + +static struct clk clk32k = { + "clk32k", + AT91C_SLOW_CLOCK, + RT_NULL, + {RT_NULL, RT_NULL}, +}; + +static struct clk main_clk = { + "main", + 0, + RT_NULL, + {RT_NULL, RT_NULL}, +}; + +static struct clk plla = { + "plla", + 0, + &main_clk, + {RT_NULL, RT_NULL}, +}; + +static struct clk mck = { + "mck", + 0, + NULL, + {RT_NULL, RT_NULL}, +}; + +static struct clk upllck = { + "upllck", + 480*1000*1000, + &main_clk, + {RT_NULL, RT_NULL}, +}; + +static struct clk *const standard_pmc_clocks[] = { + /* four primary clocks */ + &clk32k, + &main_clk, + &plla, + + /* MCK */ + &mck +}; + +/* clocks cannot be de-registered no refcounting necessary */ +struct clk *clk_get(const char *id) +{ + struct clk *clk; + rt_list_t *list; + + for (list = (&clocks)->next; list != &clocks; list = list->next) + { + clk = (struct clk *)rt_list_entry(list, struct clk, node); + if (rt_strcmp(id, clk->name) == 0) + return clk; + } + + return RT_NULL; +} + +rt_uint32_t clk_get_rate(struct clk *clk) +{ + rt_uint32_t rate; + + for (;;) { + rate = clk->rate_hz; + if (rate || !clk->parent) + break; + clk = clk->parent; + } + return rate; +} + +static void at91_upllck_init(rt_uint32_t main_clock) +{ + // EHCI USB use fixed 480MHz clock +} + +static struct clk *at91_css_to_clk(unsigned long css) +{ + switch (css) { + case AT91C_PMC_CSS_SLOW_CLK: + return &clk32k; + case AT91C_PMC_CSS_MAIN_CLK: + return &main_clk; + case AT91C_PMC_CSS_PLLA_CLK: + return &plla; + case AT91C_PMC_CSS_UPLL_CLK: + return &upllck; + } + + return RT_NULL; +} + +// TODO: how to auto-set register value by OSC and MCK +/* Settings at 400/133MHz */ +// In datasheet, ATMEL says 12MHz main crystal startup time less than 2ms, so we +// configure OSC startup timeout to 64*8/32768=15.6ms, should enough +#define BOARD_OSCOUNT (AT91C_CKGR_OSCOUNT & (64 << 8)) +// MAINCK => Divider(DIVA) => PLLA(MULA, OUTA) => /1/2 Divider(PLLADIV2) => PLLACK +// pls. refer to doc6438G figure 24-6 on pg294. ICPLLA in reg PMC_PLLICPR +// 12MHz / 3 * (199 + 1) = 800MHz +// OUTA/ICPLLA can as ICPLLA:OUTA[1]:OUTA[0] = (800-PLLAOUT(MHz))/50 +// PLLACOUNT field occupy bit[13:8], max value is 0x3F, then about 19.2ms +#define BOARD_CKGR_PLLA (AT91C_CKGR_SRCA | AT91C_CKGR_OUTA_0) +#define BOARD_PLLACOUNT (0x3F << 8) +#define BOARD_MULA (AT91C_CKGR_MULA & (199 << 16)) +#define BOARD_DIVA (AT91C_CKGR_DIVA & 3) +// Clock Source => select(CCS) => Prescaler(PRES) => Master Clock Divider(MDIV) => MCK +// => Processor Clock Divider => PCK +// Master clock can refer to doc6438G figure 25-2 on pg298 +// PLLADIV2=1(div 2, 400MHz), PRES=0(no div, 400MHz), +// MDIV=3(Master Clock divided by 3, 133MHz), CSS=0(still Slow Clock) +#define BOARD_PRESCALER (0x00001300) //400/133MHz + +#define MHz(n) ((n) * 1000 * 1000) +#define OSC_FREQ MHz(12) +#define PLLA_FREQ MHz(800) + +static void at91_plla_init(void) +{ + rt_uint32_t pllar, mckr; + + // Code refer to doc6438G, 25.10 Programming Sequence + /* Initialize main oscillator + ****************************/ + // enable main OSC and wait OSC startup time timeout. + AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); + + /* Initialize PLLA, Set PLL to 800MHz and wait PLL stable */ + pllar = (MHz(800) - PLLA_FREQ) / MHz(50); // please refer to Table 46-15 of doc 6438G + AT91C_BASE_PMC->PMC_PLLICPR = (pllar >> 2) & 1; // ICPLLA + pllar = (pllar & 3) << 14; // OUTA + pllar |= BOARD_DIVA; // PLLA input clock as 4MHz + pllar |= BOARD_MULA; // PLLA output clock as 800MHz + pllar |= BOARD_PLLACOUNT; + pllar |= AT91C_CKGR_SRCA; // I don't known what means, but seems must set it + AT91C_BASE_PMC->PMC_PLLAR = pllar; + + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)); + + /* Wait for the master clock if it was already initialized */ + // make sure Master clock in READY status before operate it + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); + + /* Switch to fast clock + **********************/ + /* setup main clock divisor and prescaler, 400MHz/133MHz, but don't switch */ + mckr = AT91C_BASE_PMC->PMC_MCKR; + if ((mckr & AT91C_PMC_MDIV) != (BOARD_PRESCALER & AT91C_PMC_MDIV)) + { + mckr = (mckr & ~(unsigned int)AT91C_PMC_MDIV) | (BOARD_PRESCALER & AT91C_PMC_MDIV); + AT91C_BASE_PMC->PMC_MCKR = mckr; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); + } + + /* Switch to PLL + prescaler, now Switch to PLLA as source, run on the fly */ + if ((mckr & AT91C_PMC_CSS) != AT91C_PMC_CSS_PLLA_CLK) + { + mckr = (mckr & ~(unsigned int)AT91C_PMC_CSS) | AT91C_PMC_CSS_PLLA_CLK; + AT91C_BASE_PMC->PMC_MCKR = mckr; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); + } + + plla.rate_hz = PLLA_FREQ; +} + +#define false 0 +#define true 1 +int at91_clock_init(rt_uint32_t main_clock) +{ + unsigned tmp, freq, mckr, mdiv; + int i; + + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(AT91C_CKGR_MCFR); + } while (!(tmp & AT91C_CKGR_MAINRDY)); + main_clock = (tmp & AT91C_CKGR_MAINF) * (AT91C_SLOW_CLOCK / 16); + } + main_clk.rate_hz = main_clock; + + at91_plla_init(); + + at91_upllck_init(main_clock); + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(AT91C_PMC_MCKR); + mck.parent = at91_css_to_clk(mckr & AT91C_PMC_CSS); + freq = mck.parent->rate_hz; + freq /= (1 << ((mckr & AT91C_PMC_PRES) >> 2)); /* prescale */ + mdiv = 1 << ((mckr & AT91C_PMC_MDIV) >> 8); + if (mdiv == 8) mdiv = 3; + freq /= mdiv; /* mdiv */ + if (mckr & AT91C_PMC_PLLADIV2) freq /= 2; /* plla_div2 */ + mck.rate_hz = freq; + + /* Register the PMC's standard clocks */ + rt_list_init(&clocks); + for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) + rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node); + + rt_list_insert_after(&clocks, &upllck.node); + + /* MCK and CPU clock are "always on" */ + //clk_enable(&mck); + + /*rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", + freq / 1000000, (unsigned) mck.rate_hz / 1000000, + (unsigned) main_clock / 1000000, + ((unsigned) main_clock % 1000000) / 1000);*///cause blocked + + return 0; +} + +/** + * @brief System Clock Configuration + */ +void rt_hw_clock_init(void) +{ + at91_clock_init(MHz(12)); +} + diff --git a/bsp/at91sam9g45/rtconfig.h b/bsp/at91sam9g45/rtconfig.h new file mode 100644 index 0000000000..5d638ce1c9 --- /dev/null +++ b/bsp/at91sam9g45/rtconfig.h @@ -0,0 +1,159 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_IDEL_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_INTERRUPT_INFO +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "dbgu" + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + +#define RT_USING_CPLUSPLUS + +/* 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_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 16 +#define RT_USING_DFS_DEVFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_USING_PIN + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_PTHREADS + +/* Network */ + +/* Socket abstraction layer */ + + +/* light weight TCP/IP stack */ + + +/* Modbus master and slave stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* sample package */ + +/* samples: kernel and components samples */ + + +/* example package: hello */ + +#define RT_USING_DBGU +#define RT_USING_LED + +#endif diff --git a/bsp/at91sam9g45/rtconfig.py b/bsp/at91sam9g45/rtconfig.py new file mode 100644 index 0000000000..3684b54578 --- /dev/null +++ b/bsp/at91sam9g45/rtconfig.py @@ -0,0 +1,138 @@ +import os +ARCH = 'arm' +CPU = 'arm926' +# toolchains options +CROSS_TOOL = 'gcc' + +#------- toolchains path ------------------------------------------------------- +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'D:\arm-2013.11\bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.2' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +#BUILD = 'debug' +BUILD = 'release' + +CORE = 'arm926ej-s' +MAP_FILE = 'rtthread_at91sam9g45.map' +LINK_FILE = 'link_scripts/at91sam9g45_ram' +TARGET_NAME = 'rtthread.bin' + +#------- GCC settings ---------------------------------------------------------- +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=arm926ej-s' + CFLAGS = DEVICE + AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp' + AFLAGS += ' -Iplatform' + LFLAGS = DEVICE + LFLAGS += ' -Wl,--gc-sections,-cref,-Map=' + MAP_FILE + LFLAGS += ' -T ' + LINK_FILE + '.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' + POST_ACTION += SIZE + ' $TARGET\n' +#------- Keil settings --------------------------------------------------------- +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + EXEC_PATH += '/arm/armcc/bin/' + + DEVICE = ' --cpu=' + CORE + CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870' + AFLAGS = DEVICE + ' -Iplatform' + LFLAGS = DEVICE + ' --strict' + LFLAGS += ' --info sizes --info totals --info unused --info veneers' + LFLAGS += ' --list ' + MAP_FILE + LFLAGS += ' --scatter ' + LINK_FILE + '.scat' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output ' + TARGET_NAME + ' \n' + POST_ACTION += 'fromelf -z $TARGET\n' +#------- IAR settings ---------------------------------------------------------- +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = CORE + + CFLAGS = '--cpu=' + DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + + CFLAGS += ' --endian=little' + CFLAGS += ' -e' + CFLAGS += ' --fpu=none' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = '--cpu '+ DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --fpu none' + AFLAGS += ' -S' + AFLAGS += ' -Iplatform' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = '--config ' + LINK_FILE +'.icf' + LFLAGS += ' --entry __iar_program_start' + LFLAGS += ' --map ' + MAP_FILE + LFLAGS += ' --silent' + + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --silent --bin $TARGET ' + TARGET_NAME diff --git a/bsp/at91sam9g45/template.ewp b/bsp/at91sam9g45/template.ewp new file mode 100644 index 0000000000..5f2fa0e0a9 --- /dev/null +++ b/bsp/at91sam9g45/template.ewp @@ -0,0 +1,1914 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 24 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + + diff --git a/bsp/at91sam9g45/template.eww b/bsp/at91sam9g45/template.eww new file mode 100644 index 0000000000..bd036bb4c9 --- /dev/null +++ b/bsp/at91sam9g45/template.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\template.ewp + + + + + diff --git a/bsp/at91sam9g45/template.uvopt b/bsp/at91sam9g45/template.uvopt new file mode 100644 index 0000000000..2dca5102b8 --- /dev/null +++ b/bsp/at91sam9g45/template.uvopt @@ -0,0 +1,174 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + rtthread + 0x4 + ARM-ADS + + 18432000 + + 1 + 1 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 16 + + + 0 + Datasheet + DATASHTS\ATMEL\AT91SAM9260_DS.PDF + + + 1 + Summary + DATASHTS\ATMEL\AT91SAM9260_DC.PDF + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 5 + + + + + + + + + + .\jlink\at91sam9260.ini + Segger\JLTAgdi.dll + + + + 0 + JLTAgdi + -O558 -J1 -Y1000 -Z1 -FO0 -FD200000 -FC800 -FN0 + + + 0 + UL2ARM + -UV2077N9E -O47 -S0 -C0 -N00("ARM926EJ-S Core") -D00(0792603F) -L00(4) -FO7 -FD300000 -FC1000 -FN1 -FF0AT91SAM9_DF_P1056_CS1 -FS020000000 -FL083BE00) + + + + + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + +
diff --git a/bsp/at91sam9g45/template.uvproj b/bsp/at91sam9g45/template.uvproj new file mode 100644 index 0000000000..ea6226f101 --- /dev/null +++ b/bsp/at91sam9g45/template.uvproj @@ -0,0 +1,407 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread + 0x4 + ARM-ADS + + + AT91SAM9260 + Atmel + IRAM(0x200000-0x200FFF) IRAM2(0x300000-0x300FFF) IROM(0x100000-0x107FFF) CLOCK(18432000) CPUTYPE(ARM926EJ-S) + + "STARTUP\Atmel\SAM9260.s" ("Atmel AT91SAM9260 Startup Code") + UL2ARM(-UV2077N9E -O47 -S0 -C0 -N00("ARM926EJ-S Core") -D00(0792603F) -L00(4) -FO7 -FD300000 -FC1000 -FN1 -FF0AT91SAM9_DF_P1056_CS1 -FS020000000 -FL083BE00) + 4210 + AT91SAM9260.H + + + + + + + + + + + 0 + 0 + + + + Atmel\SAM9260\ + Atmel\SAM9260\ + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARM.DLL + -cAT91SAM9260 + DARMATS9.DLL + -p91SAM9260 + SARM.DLL + + TARMATS9.DLL + -p91SAM9260 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + + 0 + 5 + + + + + + + + + + + + + .\jlink\at91sam9260.ini + Segger\JLTAgdi.dll + + + + + 1 + 0 + 0 + 0 + 1 + 4096 + + 1 + BIN\UL2ARM.DLL + "" () + .\jlink\at91sam9260.ini + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + ARM926EJ-S + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x200000 + 0x1000 + + + 1 + 0x100000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x20000000 + 0x800000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x100000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x20800000 + 0x1800000 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x200000 + 0x1000 + + + 0 + 0x300000 + 0x1000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + + + RT_USING_INTERRUPT_INFO + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + .\platform + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x20000000 + 0x20800000 + + .\link_scripts\at91sam9g45_ram.scat + + + + + + + + + + + +
diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S index 9f789b97f7..aca0e4577f 100644 --- a/libcpu/arm/arm926/start_rvds.S +++ b/libcpu/arm/arm926/start_rvds.S @@ -25,7 +25,14 @@ ; * 2015-06-04 aozima Align stack address to 8 byte. ; */ -#include "rt_low_level_init.h" +;#include "rt_low_level_init.h" +UND_STK_SIZE EQU 512 +SVC_STK_SIZE EQU 4096 +ABT_STK_SIZE EQU 512 +IRQ_STK_SIZE EQU 1024 +FIQ_STK_SIZE EQU 1024 +SYS_STK_SIZE EQU 512 +Heap_Size EQU 512 S_FRAME_SIZE EQU (18*4) ;72 ;S_SPSR EQU (17*4) ;SPSR -- cgit v1.3.1 From 86c76b0e8a4486dec13d61ee3ca68379b947dfb5 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 28 Dec 2018 09:06:32 +0800 Subject: add k210 SMP support --- bsp/k210/.config | 36 +-------- bsp/k210/driver/board.c | 22 ++--- bsp/k210/rtconfig.h | 159 +++++++++++++++++++++++++++++++++++++ bsp/k210/rtconfig.py | 5 +- libcpu/risc-v/common/context_gcc.S | 100 ++++++++++++++++++++++- libcpu/risc-v/common/cpuport.c | 24 ++++++ libcpu/risc-v/k210/cpuport_smp.c | 80 +++++++++++++++++++ libcpu/risc-v/k210/interrupt.c | 104 +++++++++++++++++++----- libcpu/risc-v/k210/interrupt_gcc.S | 9 +++ libcpu/risc-v/k210/startup_gcc.S | 31 ++++---- 10 files changed, 489 insertions(+), 81 deletions(-) create mode 100644 libcpu/risc-v/k210/cpuport_smp.c (limited to 'libcpu') diff --git a/bsp/k210/.config b/bsp/k210/.config index a9737f1c80..65164c210d 100644 --- a/bsp/k210/.config +++ b/bsp/k210/.config @@ -7,7 +7,8 @@ # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 -# CONFIG_RT_USING_SMP is not set +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 CONFIG_RT_ALIGN_SIZE=8 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y @@ -326,39 +327,6 @@ CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2" # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set -# CONFIG_PKG_USING_KENDRYTE_DEMO_V001 is not set -# CONFIG_PKG_USING_KENDRYTE_DEMO_LATEST_VERSION is not set -# CONFIG_KENDRYTE_DEMO_NONE is not set -# CONFIG_KENDRYTE_DEMO_AES_128_TEST is not set -# CONFIG_KENDRYTE_DEMO_AES_192_TEST is not set -# CONFIG_KENDRYTE_DEMO_AES_256_TEST is not set -# CONFIG_KENDRYTE_DEMO_AI_DEMO_SIM is not set -# CONFIG_KENDRYTE_DEMO_DVP_OV is not set -# CONFIG_KENDRYTE_DEMO_FACE_DETECT is not set -# CONFIG_KENDRYTE_DEMO_FFT_TEST is not set -# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX is not set -# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX_DMA_TEST is not set -# CONFIG_KENDRYTE_DEMO_FLASH_W25QXX_TEST is not set -# CONFIG_KENDRYTE_DEMO_GPIOHS_LED is not set -# CONFIG_KENDRYTE_DEMO_GPIO_LED is not set -# CONFIG_KENDRYTE_DEMO_HELLO_WORLD is not set -# CONFIG_KENDRYTE_DEMO_I2C_SLAVE is not set -# CONFIG_KENDRYTE_DEMO_KPU is not set -# CONFIG_KENDRYTE_DEMO_LCD is not set -# CONFIG_KENDRYTE_DEMO_MIC_PLAY is not set -# CONFIG_KENDRYTE_DEMO_PLAY_PCM is not set -# CONFIG_KENDRYTE_DEMO_PWM is not set -# CONFIG_KENDRYTE_DEMO_RTC is not set -# CONFIG_KENDRYTE_DEMO_RTC_SD3068 is not set -# CONFIG_KENDRYTE_DEMO_SD_CARD is not set -# CONFIG_KENDRYTE_DEMO_SERVO is not set -# CONFIG_KENDRYTE_DEMO_SHA256_TEST is not set -# CONFIG_KENDRYTE_DEMO_TIMER is not set -# CONFIG_KENDRYTE_DEMO_UART is not set -# CONFIG_KENDRYTE_DEMO_UART_DMA is not set -# CONFIG_KENDRYTE_DEMO_UART_DMA_IRQ is not set -# CONFIG_KENDRYTE_DEMO_UART_INTERRUPT is not set -# CONFIG_KENDRYTE_DEMO_WATCHDOG is not set # # samples: kernel and components samples diff --git a/bsp/k210/driver/board.c b/bsp/k210/driver/board.c index aac2adbc49..1b2b4c34e8 100644 --- a/bsp/k210/driver/board.c +++ b/bsp/k210/driver/board.c @@ -37,21 +37,14 @@ void init_bss(void) } } -void cpu_entry(int cpuid) +void primary_cpu_entry(void) { extern void entry(void); /* disable global interrupt */ + init_bss(); rt_hw_interrupt_disable(); - if (cpuid == 0) - { - init_bss(); - entry(); - } - else - { - while (1) ; - } + entry(); } #include @@ -85,6 +78,10 @@ int freq(void) } MSH_CMD_EXPORT(freq, show freq info); +#ifdef RT_USING_SMP +extern int rt_hw_clint_ipi_enable(void); +#endif + void rt_hw_board_init(void) { /* Init FPIOA */ @@ -96,8 +93,13 @@ void rt_hw_board_init(void) rt_hw_interrupt_init(); /* initialize hardware interrupt */ rt_hw_uart_init(); + rt_hw_tick_init(); +#ifdef RT_USING_SMP + rt_hw_clint_ipi_enable(); +#endif + #ifdef RT_USING_CONSOLE /* set console device */ rt_console_set_device(RT_CONSOLE_DEVICE_NAME); diff --git a/bsp/k210/rtconfig.h b/bsp/k210/rtconfig.h index b5fe0dfd48..94844cbf88 100644 --- a/bsp/k210/rtconfig.h +++ b/bsp/k210/rtconfig.h @@ -7,8 +7,12 @@ /* RT-Thread Kernel */ #define RT_NAME_MAX 8 +#define RT_USING_SMP +#define RT_CPUS_NR 2 #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 100 #define RT_USING_OVERFLOW_CHECK @@ -16,9 +20,19 @@ #define RT_USING_IDLE_HOOK #define RT_IDEL_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 1024 +/* RT_USING_TIMER_SOFT is not set */ #define RT_DEBUG #define RT_DEBUG_INIT_CONFIG #define RT_DEBUG_INIT 1 +/* RT_DEBUG_THREAD_CONFIG is not set */ +/* RT_DEBUG_SCHEDULER_CONFIG is not set */ +/* RT_DEBUG_IPC_CONFIG is not set */ +/* RT_DEBUG_TIMER_CONFIG is not set */ +/* RT_DEBUG_IRQ_CONFIG is not set */ +/* RT_DEBUG_MEM_CONFIG is not set */ +/* RT_DEBUG_SLAB_CONFIG is not set */ +/* RT_DEBUG_MEMHEAP_CONFIG is not set */ +/* RT_DEBUG_MODULE_CONFIG is not set */ /* Inter-Thread communication */ @@ -27,16 +41,23 @@ #define RT_USING_EVENT #define RT_USING_MAILBOX #define RT_USING_MESSAGEQUEUE +/* RT_USING_SIGNALS is not set */ /* Memory Management */ #define RT_USING_MEMPOOL +/* RT_USING_MEMHEAP is not set */ +/* RT_USING_NOHEAP is not set */ #define RT_USING_SMALL_MEM +/* RT_USING_SLAB is not set */ +/* RT_USING_MEMTRACE is not set */ #define RT_USING_HEAP /* Kernel Device Object */ #define RT_USING_DEVICE +/* RT_USING_DEVICE_OPS is not set */ +/* RT_USING_INTERRUPT_INFO is not set */ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uarths" @@ -44,6 +65,7 @@ #define ARCH_CPU_64BIT #define ARCH_RISCV #define ARCH_RISCV64 +/* ARCH_CPU_STACK_GROWS_UPWARD is not set */ /* RT-Thread Components */ @@ -54,6 +76,7 @@ /* C++ features */ +/* RT_USING_CPLUSPLUS is not set */ /* Command shell */ @@ -63,9 +86,11 @@ #define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION +/* FINSH_ECHO_DISABLE_DEFAULT is not set */ #define FINSH_THREAD_PRIORITY 20 #define FINSH_THREAD_STACK_SIZE 16384 #define FINSH_CMD_SIZE 80 +/* FINSH_USING_AUTH is not set */ #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT #define FINSH_USING_MSH_ONLY @@ -78,7 +103,13 @@ #define DFS_FILESYSTEMS_MAX 4 #define DFS_FILESYSTEM_TYPES_MAX 4 #define DFS_FD_MAX 16 +/* RT_USING_DFS_MNTTABLE is not set */ +/* RT_USING_DFS_ELMFAT is not set */ #define RT_USING_DFS_DEVFS +/* 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 */ /* Device Drivers */ @@ -86,87 +117,215 @@ #define RT_PIPE_BUFSZ 512 #define RT_USING_SERIAL #define RT_SERIAL_USING_DMA +/* RT_USING_CAN is not set */ +/* RT_USING_HWTIMER is not set */ +/* RT_USING_CPUTIME is not set */ +/* RT_USING_I2C is not set */ +/* RT_USING_PIN is not set */ +/* RT_USING_ADC is not set */ +/* RT_USING_PWM is not set */ +/* RT_USING_MTD_NOR is not set */ +/* RT_USING_MTD_NAND is not set */ +/* RT_USING_MTD is not set */ +/* RT_USING_PM is not set */ +/* RT_USING_RTC is not set */ +/* RT_USING_SDIO is not set */ +/* RT_USING_SPI is not set */ +/* RT_USING_WDT is not set */ +/* RT_USING_AUDIO is not set */ /* Using WiFi */ +/* 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 +/* RT_USING_PTHREADS is not set */ #define RT_USING_POSIX +/* RT_USING_POSIX_MMAP is not set */ +/* RT_USING_POSIX_TERMIOS is not set */ +/* RT_USING_POSIX_AIO is not set */ +/* RT_USING_MODULE is not set */ /* Network */ /* Socket abstraction layer */ +/* RT_USING_SAL is not set */ /* light weight TCP/IP stack */ +/* RT_USING_LWIP is not set */ /* Modbus master and slave stack */ +/* RT_USING_MODBUS is not set */ /* AT commands */ +/* RT_USING_AT 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_USING_ULOG is not set */ +/* RT_USING_UTEST is not set */ /* RT-Thread online packages */ /* IoT - internet of things */ +/* PKG_USING_PAHOMQTT is not set */ +/* PKG_USING_WEBCLIENT is not set */ +/* PKG_USING_WEBNET is not set */ +/* PKG_USING_MONGOOSE is not set */ +/* PKG_USING_WEBTERMINAL is not set */ +/* PKG_USING_CJSON is not set */ +/* PKG_USING_JSMN is not set */ +/* PKG_USING_LJSON is not set */ +/* PKG_USING_EZXML is not set */ +/* PKG_USING_NANOPB is not set */ /* Wi-Fi */ /* Marvell WiFi */ +/* PKG_USING_WLANMARVELL is not set */ /* Wiced WiFi */ +/* PKG_USING_WLAN_WICED is not set */ +/* PKG_USING_COAP is not set */ +/* PKG_USING_NOPOLL is not set */ +/* PKG_USING_NETUTILS is not set */ +/* PKG_USING_AT_DEVICE is not set */ +/* PKG_USING_WIZNET is not set */ /* IoT Cloud */ +/* PKG_USING_ONENET is not set */ +/* PKG_USING_GAGENT_CLOUD is not set */ +/* PKG_USING_ALI_IOTKIT is not set */ +/* PKG_USING_AZURE is not set */ +/* PKG_USING_TENCENT_IOTKIT is not set */ /* security packages */ +/* PKG_USING_MBEDTLS is not set */ +/* PKG_USING_libsodium is not set */ +/* PKG_USING_TINYCRYPT is not set */ /* language packages */ +/* PKG_USING_LUA is not set */ +/* PKG_USING_JERRYSCRIPT is not set */ +/* PKG_USING_MICROPYTHON is not set */ /* multimedia packages */ +/* PKG_USING_OPENMV is not set */ +/* PKG_USING_MUPDF is not set */ /* tools packages */ +/* PKG_USING_CMBACKTRACE is not set */ +/* PKG_USING_EASYFLASH is not set */ +/* PKG_USING_EASYLOGGER is not set */ +/* PKG_USING_SYSTEMVIEW is not set */ +/* PKG_USING_RDB is not set */ +/* PKG_USING_QRCODE is not set */ +/* PKG_USING_ULOG_EASYFLASH is not set */ /* system packages */ +/* PKG_USING_GUIENGINE is not set */ +/* PKG_USING_CAIRO is not set */ +/* PKG_USING_PIXMAN is not set */ +/* PKG_USING_LWEXT4 is not set */ +/* PKG_USING_PARTITION is not set */ +/* PKG_USING_FAL is not set */ +/* PKG_USING_SQLITE is not set */ +/* PKG_USING_RTI is not set */ +/* PKG_USING_LITTLEVGL2RTT is not set */ +/* PKG_USING_CMSIS is not set */ +/* PKG_USING_DFS_YAFFS is not set */ +/* PKG_USING_LITTLEFS is not set */ /* peripheral libraries and drivers */ +/* PKG_USING_REALTEK_AMEBA is not set */ +/* PKG_USING_SHT2X is not set */ +/* PKG_USING_AHT10 is not set */ +/* PKG_USING_AP3216C is not set */ +/* PKG_USING_STM32_SDIO is not set */ +/* PKG_USING_ICM20608 is not set */ +/* PKG_USING_U8G2 is not set */ +/* PKG_USING_BUTTON is not set */ +/* PKG_USING_MPU6XXX is not set */ +/* PKG_USING_PCF8574 is not set */ #define PKG_USING_KENDRYTE_SDK #define PKG_USING_KENDRYTE_SDK_V052 +/* PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set */ /* miscellaneous packages */ +/* PKG_USING_LIBCSV is not set */ +/* PKG_USING_OPTPARSE is not set */ +/* PKG_USING_FASTLZ is not set */ +/* PKG_USING_MINILZO is not set */ +/* PKG_USING_QUICKLZ is not set */ +/* PKG_USING_MULTIBUTTON is not set */ +/* PKG_USING_CANFESTIVAL is not set */ +/* PKG_USING_ZLIB is not set */ +/* PKG_USING_DSTR is not set */ +/* PKG_USING_TINYFRAME is not set */ +/* PKG_USING_KENDRYTE_DEMO is not set */ /* samples: kernel and components samples */ +/* PKG_USING_KERNEL_SAMPLES is not set */ +/* PKG_USING_FILESYSTEM_SAMPLES is not set */ +/* PKG_USING_NETWORK_SAMPLES is not set */ +/* PKG_USING_PERIPHERAL_SAMPLES is not set */ +/* PKG_USING_HELLO is not set */ /* Privated Packages of RealThread */ +/* PKG_USING_CODEC is not set */ +/* PKG_USING_PLAYER is not set */ +/* PKG_USING_PERSIMMON_SRC is not set */ +/* PKG_USING_JS_PERSIMMON is not set */ +/* PKG_USING_JERRYSCRIPT_WIN32 is not set */ /* Network Utilities */ +/* PKG_USING_WICED is not set */ +/* PKG_USING_CLOUDSDK is not set */ +/* PKG_USING_COREMARK is not set */ +/* PKG_USING_POWER_MANAGER is not set */ +/* PKG_USING_RT_OTA is not set */ +/* PKG_USING_RDBD_SRC is not set */ +/* PKG_USING_RTINSIGHT is not set */ +/* PKG_USING_SMARTCONFIG is not set */ +/* PKG_USING_RTX is not set */ #define BOARD_K210_EVB #define BSP_USING_UART_HS +/* BSP_USING_UART1 is not set */ +/* BSP_USING_UART2 is not set */ +/* BSP_USING_UART3 is not set */ +/* BSP_USING_I2C1 is not set */ +/* BSP_USING_SPI1 is not set */ #define __STACKSIZE__ 4096 #endif diff --git a/bsp/k210/rtconfig.py b/bsp/k210/rtconfig.py index 418c1d7456..4610f85adc 100644 --- a/bsp/k210/rtconfig.py +++ b/bsp/k210/rtconfig.py @@ -15,7 +15,7 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = r'/opt/riscv64-unknown-elf-gcc-2018.07.0-x86_64-linux-ubuntu14/bin' + EXEC_PATH = r'/opt/riscv64-unknown-elf/bin' else: print('Please make sure your toolchains is GNU GCC!') exit(0) @@ -27,8 +27,7 @@ BUILD = 'release' if PLATFORM == 'gcc': # toolchains - PREFIX = 'riscv-none-embed-' - # PREFIX = 'riscv64-unknown-elf-' + PREFIX = 'riscv64-unknown-elf-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' diff --git a/libcpu/risc-v/common/context_gcc.S b/libcpu/risc-v/common/context_gcc.S index 94ae5d9df4..62e64d8104 100644 --- a/libcpu/risc-v/common/context_gcc.S +++ b/libcpu/risc-v/common/context_gcc.S @@ -6,10 +6,16 @@ * Change Logs: * Date Author Notes * 2018/10/28 Bernard The unify RISC-V porting implementation + * 2018/12/27 Jesven Add SMP support */ #include "cpuport.h" +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + /* * rt_base_t rt_hw_interrupt_disable(void); */ @@ -27,13 +33,23 @@ rt_hw_interrupt_enable: ret /* - * void rt_hw_context_switch_to(rt_ubase_t to) + * #ifdef RT_USING_SMP + * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread); + * #else + * void rt_hw_context_switch_to(rt_ubase_t to); + * #endif * a0 --> to + * a1 --> to_thread */ .globl rt_hw_context_switch_to rt_hw_context_switch_to: LOAD sp, (a0) +#ifdef RT_USING_SMP + mv a0, a1 + jal rt_cpus_lock_status_restore +#endif + /* load epc from stack */ LOAD a0, 0 * REGBYTES(sp) csrw mepc, a0 @@ -74,9 +90,15 @@ rt_hw_context_switch_to: mret /* - * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to) + * #ifdef RT_USING_SMP + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * #else + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); + * #endif + * * a0 --> from * a1 --> to + * a2 --> to_thread */ .globl rt_hw_context_switch rt_hw_context_switch: @@ -136,6 +158,78 @@ save_mpie: */ LOAD sp, (a1) +#ifdef RT_USING_SMP + mv a0, a2 + jal rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + + /* resw ra to mepc */ + LOAD a1, 0 * REGBYTES(sp) + csrw mepc, a1 + LOAD x1, 1 * REGBYTES(sp) + + /* force to machin mode(MPP=11) */ + li a1, 0x00001800; + csrs mstatus, a1 + LOAD a1, 2 * REGBYTES(sp) + csrs mstatus, a1 + + LOAD x4, 4 * REGBYTES(sp) + LOAD x5, 5 * REGBYTES(sp) + LOAD x6, 6 * REGBYTES(sp) + LOAD x7, 7 * REGBYTES(sp) + LOAD x8, 8 * REGBYTES(sp) + LOAD x9, 9 * REGBYTES(sp) + LOAD x10, 10 * REGBYTES(sp) + LOAD x11, 11 * REGBYTES(sp) + LOAD x12, 12 * REGBYTES(sp) + LOAD x13, 13 * REGBYTES(sp) + LOAD x14, 14 * REGBYTES(sp) + LOAD x15, 15 * REGBYTES(sp) + LOAD x16, 16 * REGBYTES(sp) + LOAD x17, 17 * REGBYTES(sp) + LOAD x18, 18 * REGBYTES(sp) + LOAD x19, 19 * REGBYTES(sp) + LOAD x20, 20 * REGBYTES(sp) + LOAD x21, 21 * REGBYTES(sp) + LOAD x22, 22 * REGBYTES(sp) + LOAD x23, 23 * REGBYTES(sp) + LOAD x24, 24 * REGBYTES(sp) + LOAD x25, 25 * REGBYTES(sp) + LOAD x26, 26 * REGBYTES(sp) + LOAD x27, 27 * REGBYTES(sp) + LOAD x28, 28 * REGBYTES(sp) + LOAD x29, 29 * REGBYTES(sp) + LOAD x30, 30 * REGBYTES(sp) + LOAD x31, 31 * REGBYTES(sp) + + addi sp, sp, 32 * REGBYTES + mret + +#ifdef RT_USING_SMP +/* + * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * + * a0 --> context + * a1 --> from + * a2 --> to + * a3 --> to_thread + */ + .globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + + STORE a0, 0(a1) + + csrr a1, mepc + STORE a1, 0 * REGBYTES(a0) + + csrr a1, mstatus + STORE a1, 2 * REGBYTES(a0) + + LOAD sp, 0(a2) + move a0, a3 + call rt_cpus_lock_status_restore + /* resw ra to mepc */ LOAD a1, 0 * REGBYTES(sp) csrw mepc, a1 @@ -178,3 +272,5 @@ save_mpie: addi sp, sp, 32 * REGBYTES mret + +#endif diff --git a/libcpu/risc-v/common/cpuport.c b/libcpu/risc-v/common/cpuport.c index 2ad77b99c5..a44dc40f79 100644 --- a/libcpu/risc-v/common/cpuport.c +++ b/libcpu/risc-v/common/cpuport.c @@ -13,9 +13,11 @@ #include "cpuport.h" +#ifndef RT_USING_SMP volatile rt_ubase_t rt_interrupt_from_thread = 0; volatile rt_ubase_t rt_interrupt_to_thread = 0; volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0; +#endif struct rt_hw_stack_frame { @@ -93,6 +95,14 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, return stk; } +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * #else + * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); + * #endif + */ +#ifndef RT_USING_SMP void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) { if (rt_thread_switch_interrupt_flag == 0) @@ -103,3 +113,17 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) return ; } +#endif /* end of RT_USING_SMP */ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} diff --git a/libcpu/risc-v/k210/cpuport_smp.c b/libcpu/risc-v/k210/cpuport_smp.c new file mode 100644 index 0000000000..a31314a13f --- /dev/null +++ b/libcpu/risc-v/k210/cpuport_smp.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/12/23 Bernard The first version + * 2018/12/27 Jesven Add secondary cpu boot + */ + +#include +#include +#include + +#include "board.h" +#include +#include +#include + +#ifdef RT_USING_SMP + +int rt_hw_cpu_id(void) +{ + return read_csr(mhartid); +} + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + spinlock_lock((spinlock_t *)lock); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + spinlock_unlock((spinlock_t *)lock); +} + +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) +{ + int idx; + + for (idx = 0; idx < RT_CPUS_NR; idx ++) + { + if (cpu_mask & (1 << idx)) + { + clint_ipi_send(idx); + } + } +} + +extern rt_base_t secondary_boot_flag; +void rt_hw_secondary_cpu_up(void) +{ + mb(); + secondary_boot_flag = 0xa55a; +} + +extern void rt_hw_scondary_interrupt_init(void); +extern int rt_hw_tick_init(void); +extern int rt_hw_clint_ipi_enable(void); + +void secondary_cpu_c_start(void) +{ + rt_hw_spin_lock(&_cpus_lock); + + /* initialize interrupt controller */ + rt_hw_scondary_interrupt_init(); + + rt_hw_tick_init(); + + rt_hw_clint_ipi_enable(); + + rt_system_scheduler_start(); +} + +void rt_hw_secondary_cpu_idle_exec(void) +{ + asm volatile ("wfi"); +} +#endif /*RT_USING_SMP*/ diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c index f9c3eb5a67..3d30e69ed2 100644 --- a/libcpu/risc-v/k210/interrupt.c +++ b/libcpu/risc-v/k210/interrupt.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/10/01 Bernard The first version + * 2018/12/27 Jesven Change irq enable/disable to cpu0 */ #include @@ -19,7 +20,7 @@ #define CPU_NUM 2 #define MAX_HANDLERS IRQN_MAX -static struct rt_irq_desc irq_desc[CPU_NUM][MAX_HANDLERS]; +static struct rt_irq_desc irq_desc[MAX_HANDLERS]; static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) { @@ -27,6 +28,52 @@ static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) return RT_NULL; } +int rt_hw_clint_ipi_enable(void) +{ + /* Set the Machine-Software bit in MIE */ + set_csr(mie, MIP_MSIP); + return 0; +} + +int rt_hw_clint_ipi_disable(void) +{ + /* Clear the Machine-Software bit in MIE */ + clear_csr(mie, MIP_MSIP); + return 0; +} + +int rt_hw_plic_irq_enable(plic_irq_t irq_number) +{ + unsigned long core_id = 0; + + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return -1; + /* Get current enable bit array by IRQ number */ + uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32]; + /* Set enable bit in enable bit array */ + current |= (uint32_t)1 << (irq_number % 32); + /* Write back the enable bit array */ + plic->target_enables.target[core_id].enable[irq_number / 32] = current; + return 0; +} + +int rt_hw_plic_irq_disable(plic_irq_t irq_number) +{ + unsigned long core_id = 0; + + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return -1; + /* Get current enable bit array by IRQ number */ + uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32]; + /* Clear enable bit in enable bit array */ + current &= ~((uint32_t)1 << (irq_number % 32)); + /* Write back the enable bit array */ + plic->target_enables.target[core_id].enable[irq_number / 32] = current; + return 0; +} + /** * This function will initialize hardware interrupt */ @@ -52,11 +99,11 @@ void rt_hw_interrupt_init(void) for (idx = 0; idx < MAX_HANDLERS; idx++) { rt_hw_interrupt_mask(idx); - irq_desc[cpuid][idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; - irq_desc[cpuid][idx].param = RT_NULL; + irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[idx].param = RT_NULL; #ifdef RT_USING_INTERRUPT_INFO - rt_snprintf(irq_desc[cpuid][idx].name, RT_NAME_MAX - 1, "default"); - irq_desc[idx][cpuid].counter = 0; + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].counter = 0; #endif } @@ -64,13 +111,31 @@ void rt_hw_interrupt_init(void) set_csr(mie, MIP_MEIP); } +void rt_hw_scondary_interrupt_init(void) +{ + int idx; + int cpuid; + + cpuid = current_coreid(); + + /* Disable all interrupts for the current core. */ + for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++) + plic->target_enables.target[cpuid].enable[idx] = 0; + + /* Set the threshold to zero. */ + plic->targets.target[cpuid].priority_threshold = 0; + + /* Enable machine external interrupts. */ + set_csr(mie, MIP_MEIP); +} + /** * This function will mask a interrupt. * @param vector the interrupt number */ void rt_hw_interrupt_mask(int vector) { - plic_irq_disable(vector); + rt_hw_plic_irq_disable(vector); } /** @@ -80,7 +145,7 @@ void rt_hw_interrupt_mask(int vector) void rt_hw_interrupt_umask(int vector) { plic_set_priority(vector, 1); - plic_irq_enable(vector); + rt_hw_plic_irq_enable(vector); } /** @@ -92,21 +157,18 @@ void rt_hw_interrupt_umask(int vector) rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name) { - int cpuid; rt_isr_handler_t old_handler = RT_NULL; - cpuid = current_coreid(); - if(vector < MAX_HANDLERS) { - old_handler = irq_desc[cpuid][vector].handler; + old_handler = irq_desc[vector].handler; if (handler != RT_NULL) { - irq_desc[cpuid][vector].handler = (rt_isr_handler_t)handler; - irq_desc[cpuid][vector].param = param; + irq_desc[vector].handler = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; #ifdef RT_USING_INTERRUPT_INFO - rt_snprintf(irq_desc[cpuid][vector].name, RT_NAME_MAX - 1, "%s", name); - irq_desc[cpuid][vector].counter = 0; + rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); + irq_desc[vector].counter = 0; #endif } } @@ -149,14 +211,14 @@ uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) /* Disable software interrupt and timer interrupt */ clear_csr(mie, MIP_MTIP | MIP_MSIP); - if (irq_desc[core_id][int_num].handler == (rt_isr_handler_t)rt_hw_interrupt_handle) + if (irq_desc[int_num].handler == (rt_isr_handler_t)rt_hw_interrupt_handle) { /* default handler, route to kendryte bsp plic driver */ plic_irq_handle(int_num); } - else if (irq_desc[core_id][int_num].handler) + else if (irq_desc[int_num].handler) { - irq_desc[core_id][int_num].handler(int_num, irq_desc[core_id][int_num].param); + irq_desc[int_num].handler(int_num, irq_desc[int_num].param); } /* Perform IRQ complete */ @@ -185,6 +247,12 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) switch (cause) { case IRQ_M_SOFT: + { + uint64_t core_id = current_coreid(); + + clint_ipi_clear(core_id); + rt_schedule(); + } break; case IRQ_M_EXT: handle_irq_m_ext(mcause, epc); diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S index 5783322237..5d3e8368b1 100644 --- a/libcpu/risc-v/k210/interrupt_gcc.S +++ b/libcpu/risc-v/k210/interrupt_gcc.S @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/10/02 Bernard The first version + * 2018/12/27 Jesven Add SMP schedule */ #include "cpuport.h" @@ -72,6 +73,13 @@ trap_entry: call handle_trap call rt_interrupt_leave +#ifdef RT_USING_SMP + /* s0 --> sp */ + mv a0, s0 + call rt_scheduler_do_irq_switch + mv sp, s0 +#else + /* switch to from_thread stack */ move sp, s0 @@ -94,6 +102,7 @@ trap_entry: LOAD a0, 0 * REGBYTES(sp) csrw mepc, a0 +#endif spurious_interrupt: LOAD x1, 1 * REGBYTES(sp) diff --git a/libcpu/risc-v/k210/startup_gcc.S b/libcpu/risc-v/k210/startup_gcc.S index 2e69c5021e..f5c0d8fa94 100644 --- a/libcpu/risc-v/k210/startup_gcc.S +++ b/libcpu/risc-v/k210/startup_gcc.S @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/10/01 Bernard The first version + * 2018/12/27 Jesven Add SMP support */ #define MSTATUS_FS 0x00006000U /* initial state of FPU */ @@ -114,20 +115,22 @@ _start: add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */ /* other cpu core, jump to cpu entry directly */ - bnez a0, _cpu_entry + bnez a0, secondary_cpu_entry + j primary_cpu_entry -#if 0 - /* clear bss section */ - la a0, __bss_start - la a1, __bss_end - bgeu a0, a1, 2f -1: - sw zero, (a0) - addi a0, a0, REGBYTES - bltu a0, a1, 1b -2: +secondary_cpu_entry: +#ifdef RT_USING_SMP + la a0, secondary_boot_flag + ld a0, 0(a0) + li a1, 0xa55a + beq a0, a1, secondary_cpu_c_start #endif + j secondary_cpu_entry -_cpu_entry: - csrr a0, mhartid - j cpu_entry +#ifdef RT_USING_SMP +.data +.global secondary_boot_flag +.align 3 +secondary_boot_flag: + .dword 0 +#endif -- cgit v1.3.1 From bde47018b8327fb8106c68e84a719a97243a1653 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Mon, 7 Jan 2019 06:09:45 +0800 Subject: [libcpu] Add SConscript in libcpu. --- bsp/qemu-vexpress-a9/SConstruct | 1 + bsp/qemu-vexpress-gemini/SConstruct | 9 +-- bsp/realview-a8/SConstruct | 9 +-- libcpu/SConscript | 41 +++-------- libcpu/arm/AT91SAM7S/SConscript | 23 ++++++ libcpu/arm/AT91SAM7S/context_rvds.S | 130 ++++++++++++++++------------------ libcpu/arm/AT91SAM7X/SConscript | 23 ++++++ libcpu/arm/AT91SAM7X/context_rvds.S | 22 +++--- libcpu/arm/SConscript | 18 +++++ libcpu/arm/am335x/SConscript | 23 ++++++ libcpu/arm/arm926/SConscript | 25 +++++++ libcpu/arm/arm926/context_gcc.S | 18 +---- libcpu/arm/arm926/context_iar.S | 34 +++------ libcpu/arm/arm926/context_rvds.S | 22 ++---- libcpu/arm/arm926/start_iar.S | 18 +---- libcpu/arm/arm926/start_rvds.S | 37 +--------- libcpu/arm/armv6/SConscript | 23 ++++++ libcpu/arm/common/SConscript | 23 ++++++ libcpu/arm/common/backtrace.c | 58 +++++++-------- libcpu/arm/cortex-a/SConscript | 23 ++++++ libcpu/arm/cortex-m0/SConscript | 23 ++++++ libcpu/arm/cortex-m0/context_iar.S | 8 +-- libcpu/arm/cortex-m0/context_rvds.S | 8 +-- libcpu/arm/cortex-m3/SConscript | 23 ++++++ libcpu/arm/cortex-m3/context_iar.S | 8 +-- libcpu/arm/cortex-m3/context_rvds.S | 8 +-- libcpu/arm/cortex-m4/SConscript | 23 ++++++ libcpu/arm/cortex-m4/context_iar.S | 8 +-- libcpu/arm/cortex-m7/SConscript | 23 ++++++ libcpu/arm/cortex-m7/context_iar.S | 8 +-- libcpu/arm/cortex-m7/context_rvds.S | 8 +-- libcpu/arm/cortex-r4/SConscript | 23 ++++++ libcpu/arm/cortex-r4/context_ccs.asm | 10 +-- libcpu/arm/dm36x/SConscript | 23 ++++++ libcpu/arm/dm36x/context_rvds.S | 18 +---- libcpu/arm/lpc214x/SConscript | 23 ++++++ libcpu/arm/lpc214x/context_rvds.S | 8 +-- libcpu/arm/lpc24xx/SConscript | 23 ++++++ libcpu/arm/lpc24xx/context_rvds.S | 8 +-- libcpu/arm/realview-a8-vmm/SConscript | 22 +++--- libcpu/arm/s3c24x0/SConscript | 23 ++++++ libcpu/arm/s3c24x0/context_rvds.S | 8 +-- libcpu/arm/s3c44b0/SConscript | 23 ++++++ libcpu/arm/s3c44b0/context_rvds.S | 8 +-- libcpu/arm/sep4020/SConscript | 23 ++++++ libcpu/arm/sep4020/context_rvds.S | 8 +-- libcpu/arm/zynq7000/SConscript | 22 +++--- libcpu/arm/zynq7000/context_gcc.S | 20 ++---- libcpu/arm/zynq7000/cp15.h | 25 +++---- libcpu/arm/zynq7000/gic.c | 20 ++---- libcpu/arm/zynq7000/gic.h | 20 ++---- libcpu/arm/zynq7000/interrupt.h | 25 +++---- libcpu/arm/zynq7000/mmu.c | 20 ++---- libcpu/arm/zynq7000/trap.c | 20 ++---- libcpu/avr32/SConscript | 15 ++++ libcpu/avr32/uc3/SConscript | 14 ++++ libcpu/blackfin/SConscript | 15 ++++ libcpu/blackfin/bf53x/SConscript | 14 ++++ libcpu/c-sky/SConscript | 18 +++++ libcpu/c-sky/ck802/SConscript | 14 ++++ libcpu/c-sky/common/SConscript | 14 ++++ libcpu/ia32/SConscript | 14 ++++ libcpu/m16c/SConscript | 15 ++++ libcpu/m16c/m16c62p/SConscript | 14 ++++ libcpu/mips/SConscript | 18 +++++ libcpu/mips/common/SConscript | 14 ++++ libcpu/mips/loongson_1b/SConscript | 14 ++++ libcpu/mips/loongson_1c/SConscript | 14 ++++ libcpu/mips/pic32/SConscript | 14 ++++ libcpu/mips/x1000/SConscript | 14 ++++ libcpu/mips/xburst/SConscript.1 | 14 ++++ libcpu/nios/SConscript | 15 ++++ libcpu/nios/nios_ii/SConscript | 14 ++++ libcpu/ppc/SConscript | 18 +++++ libcpu/ppc/common/SConscript | 14 ++++ libcpu/ppc/common/ptrace.h | 28 ++++---- libcpu/ppc/ppc405/SConscript | 14 ++++ libcpu/risc-v/SConscript | 18 +++++ libcpu/risc-v/common/SConscript | 12 ++++ libcpu/risc-v/e310/SConscript | 13 ++-- libcpu/risc-v/k210/SConscript | 14 ++++ libcpu/risc-v/rv32m1/SConscript | 14 ++++ libcpu/rx/SConscript | 14 ++++ libcpu/sim/SConscript | 15 ++++ libcpu/sim/posix/SConscript | 14 ++++ libcpu/sim/win32/SConscript | 14 ++++ libcpu/ti-dsp/SConscript | 15 ++++ libcpu/ti-dsp/c28x/SConscript | 14 ++++ libcpu/unicore32/SConscript | 15 ++++ libcpu/unicore32/sep6200/SConscript | 14 ++++ libcpu/v850/70f34/SConscript | 14 ++++ libcpu/v850/SConscript | 15 ++++ libcpu/xilinx/SConscript | 15 ++++ libcpu/xilinx/microblaze/SConscript | 14 ++++ 94 files changed, 1249 insertions(+), 498 deletions(-) create mode 100644 libcpu/arm/AT91SAM7S/SConscript create mode 100644 libcpu/arm/AT91SAM7X/SConscript create mode 100644 libcpu/arm/SConscript create mode 100644 libcpu/arm/am335x/SConscript create mode 100644 libcpu/arm/arm926/SConscript create mode 100644 libcpu/arm/armv6/SConscript create mode 100644 libcpu/arm/common/SConscript create mode 100644 libcpu/arm/cortex-a/SConscript create mode 100644 libcpu/arm/cortex-m0/SConscript create mode 100644 libcpu/arm/cortex-m3/SConscript create mode 100644 libcpu/arm/cortex-m4/SConscript create mode 100644 libcpu/arm/cortex-m7/SConscript create mode 100644 libcpu/arm/cortex-r4/SConscript create mode 100644 libcpu/arm/dm36x/SConscript create mode 100644 libcpu/arm/lpc214x/SConscript create mode 100644 libcpu/arm/lpc24xx/SConscript create mode 100644 libcpu/arm/s3c24x0/SConscript create mode 100644 libcpu/arm/s3c44b0/SConscript create mode 100644 libcpu/arm/sep4020/SConscript create mode 100644 libcpu/avr32/SConscript create mode 100644 libcpu/avr32/uc3/SConscript create mode 100644 libcpu/blackfin/SConscript create mode 100644 libcpu/blackfin/bf53x/SConscript create mode 100644 libcpu/c-sky/SConscript create mode 100644 libcpu/c-sky/ck802/SConscript create mode 100644 libcpu/c-sky/common/SConscript create mode 100644 libcpu/ia32/SConscript create mode 100644 libcpu/m16c/SConscript create mode 100644 libcpu/m16c/m16c62p/SConscript create mode 100644 libcpu/mips/SConscript create mode 100644 libcpu/mips/common/SConscript create mode 100644 libcpu/mips/loongson_1b/SConscript create mode 100644 libcpu/mips/loongson_1c/SConscript create mode 100644 libcpu/mips/pic32/SConscript create mode 100644 libcpu/mips/x1000/SConscript create mode 100644 libcpu/mips/xburst/SConscript.1 create mode 100644 libcpu/nios/SConscript create mode 100644 libcpu/nios/nios_ii/SConscript create mode 100644 libcpu/ppc/SConscript create mode 100644 libcpu/ppc/common/SConscript create mode 100644 libcpu/ppc/ppc405/SConscript create mode 100644 libcpu/risc-v/SConscript create mode 100644 libcpu/risc-v/common/SConscript create mode 100644 libcpu/risc-v/k210/SConscript create mode 100644 libcpu/risc-v/rv32m1/SConscript create mode 100644 libcpu/rx/SConscript create mode 100644 libcpu/sim/SConscript create mode 100644 libcpu/sim/posix/SConscript create mode 100644 libcpu/sim/win32/SConscript create mode 100644 libcpu/ti-dsp/SConscript create mode 100644 libcpu/ti-dsp/c28x/SConscript create mode 100644 libcpu/unicore32/SConscript create mode 100644 libcpu/unicore32/sep6200/SConscript create mode 100644 libcpu/v850/70f34/SConscript create mode 100644 libcpu/v850/SConscript create mode 100644 libcpu/xilinx/SConscript create mode 100644 libcpu/xilinx/microblaze/SConscript (limited to 'libcpu') diff --git a/bsp/qemu-vexpress-a9/SConstruct b/bsp/qemu-vexpress-a9/SConstruct index 61af0ee620..638311d697 100644 --- a/bsp/qemu-vexpress-a9/SConstruct +++ b/bsp/qemu-vexpress-a9/SConstruct @@ -19,6 +19,7 @@ env = Environment(tools = ['mingw'], AR = rtconfig.AR, ARFLAGS = '-rc', LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] Export('RTT_ROOT') Export('rtconfig') diff --git a/bsp/qemu-vexpress-gemini/SConstruct b/bsp/qemu-vexpress-gemini/SConstruct index 6fa1553e4d..765abd555a 100644 --- a/bsp/qemu-vexpress-gemini/SConstruct +++ b/bsp/qemu-vexpress-gemini/SConstruct @@ -13,11 +13,12 @@ from building import * TARGET = 'rtthread-vexpress.' + rtconfig.TARGET_EXT env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - AR = rtconfig.AR, ARFLAGS = '-rc', - LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] Export('RTT_ROOT') Export('rtconfig') diff --git a/bsp/realview-a8/SConstruct b/bsp/realview-a8/SConstruct index 67ae413023..0885dbfc0e 100644 --- a/bsp/realview-a8/SConstruct +++ b/bsp/realview-a8/SConstruct @@ -13,11 +13,12 @@ from building import * TARGET = 'rtthread-realview.' + rtconfig.TARGET_EXT env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - AR = rtconfig.AR, ARFLAGS = '-rc', - LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] Export('RTT_ROOT') Export('rtconfig') diff --git a/libcpu/SConscript b/libcpu/SConscript index 568da67cc9..774e7f4043 100644 --- a/libcpu/SConscript +++ b/libcpu/SConscript @@ -1,38 +1,15 @@ -Import('RTT_ROOT') -Import('rtconfig') -from building import * - -arch = rtconfig.ARCH -comm = rtconfig.ARCH + '/common' -path = rtconfig.ARCH + '/' + rtconfig.CPU -src = [] -ASFLAGS = '' - -# The set of source files associated with this SConscript file. -if rtconfig.PLATFORM == 'armcc': - src += Glob(path + '/*.c') + Glob(path + '/*_rvds.S') - src += Glob(comm + '/*.c') + Glob(comm + '/*_rvds.S') - -if rtconfig.PLATFORM == 'gcc': - src += Glob(path + '/*_init.S') - src += Glob(path + '/*.c') + Glob(path + '/*_gcc.S') - src += Glob(comm + '/*.c') + Glob(comm + '/*_gcc.S') +# RT-Thread building script for bridge -if rtconfig.PLATFORM == 'iar': - src += Glob(path + '/*.c') + Glob(path + '/*_iar.S') - src += Glob(comm + '/*.c') + Glob(comm + '/*_iar.S') - -if rtconfig.PLATFORM == 'cl': - src = Glob(path + '/*.c') - -if rtconfig.PLATFORM == 'mingw': - src = Glob(path + '/*.c') +import os +from building import * -if rtconfig.PLATFORM == 'armcc' and rtconfig.ARCH == 'arm' and rtconfig.CPU == 'arm926': - ASFLAGS = ' --cpreproc' +Import('rtconfig') -CPPPATH = [RTT_ROOT + '/libcpu/' + arch + '/' + rtconfig.CPU, RTT_ROOT + '/libcpu/' + arch + '/common'] +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) -group = DefineGroup(rtconfig.CPU.upper(), src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +if rtconfig.ARCH in list: + group = group + SConscript(os.path.join(cwd, rtconfig.ARCH, 'SConscript')) Return('group') diff --git a/libcpu/arm/AT91SAM7S/SConscript b/libcpu/arm/AT91SAM7S/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/AT91SAM7S/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/AT91SAM7S/context_rvds.S b/libcpu/arm/AT91SAM7S/context_rvds.S index 641ec7a6b1..78e3df9736 100644 --- a/libcpu/arm/AT91SAM7S/context_rvds.S +++ b/libcpu/arm/AT91SAM7S/context_rvds.S @@ -1,43 +1,39 @@ -;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team -; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE -; * -; * Change Logs: -; * Date Author Notes -; * 2009-01-20 Bernard first version -; */ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-20 Bernard first version + */ NOINT EQU 0xc0 ; disable interrupt in psr - AREA |.text|, CODE, READONLY, ALIGN=2 - ARM - REQUIRE8 - PRESERVE8 + AREA |.text|, CODE, READONLY, ALIGN=2 + ARM + REQUIRE8 + PRESERVE8 ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ rt_hw_interrupt_disable PROC - EXPORT rt_hw_interrupt_disable - MRS r0, cpsr - ORR r1, r0, #NOINT - MSR cpsr_c, r1 - BX lr - ENDP + EXPORT rt_hw_interrupt_disable + MRS r0, cpsr + ORR r1, r0, #NOINT + MSR cpsr_c, r1 + BX lr + ENDP ;/* ; * void rt_hw_interrupt_enable(rt_base_t level); ; */ rt_hw_interrupt_enable PROC - EXPORT rt_hw_interrupt_enable - MSR cpsr_c, r0 - BX lr - ENDP + EXPORT rt_hw_interrupt_enable + MSR cpsr_c, r0 + BX lr + ENDP ;/* ; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); @@ -45,63 +41,63 @@ rt_hw_interrupt_enable PROC ; * r1 --> to ; */ rt_hw_context_switch PROC - EXPORT rt_hw_context_switch - STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC) - STMFD sp!, {r0-r12, lr} ; push lr & register file + EXPORT rt_hw_context_switch + STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC) + STMFD sp!, {r0-r12, lr} ; push lr & register file - MRS r4, cpsr - STMFD sp!, {r4} ; push cpsr - MRS r4, spsr - STMFD sp!, {r4} ; push spsr + MRS r4, cpsr + STMFD sp!, {r4} ; push cpsr + MRS r4, spsr + STMFD sp!, {r4} ; push spsr - STR sp, [r0] ; store sp in preempted tasks TCB - LDR sp, [r1] ; get new task stack pointer + STR sp, [r0] ; store sp in preempted tasks TCB + LDR sp, [r1] ; get new task stack pointer - LDMFD sp!, {r4} ; pop new task spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task cpsr - MSR cpsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 - LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc - ENDP + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + ENDP ;/* ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to ; */ rt_hw_context_switch_to PROC - EXPORT rt_hw_context_switch_to - LDR sp, [r0] ; get new task stack pointer + EXPORT rt_hw_context_switch_to + LDR sp, [r0] ; get new task stack pointer - LDMFD sp!, {r4} ; pop new task spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task cpsr - MSR cpsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 - LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc - ENDP + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + ENDP ;/* ; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); ; */ - IMPORT rt_thread_switch_interrupt_flag - IMPORT rt_interrupt_from_thread - IMPORT rt_interrupt_to_thread + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread rt_hw_context_switch_interrupt PROC - EXPORT rt_hw_context_switch_interrupt - LDR r2, =rt_thread_switch_interrupt_flag - LDR r3, [r2] - CMP r3, #1 - BEQ _reswitch - MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1 - STR r3, [r2] - LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread - STR r0, [r2] + EXPORT rt_hw_context_switch_interrupt + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1 + STR r3, [r2] + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] _reswitch - LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread - STR r1, [r2] - BX lr - ENDP + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + BX lr + ENDP - END \ No newline at end of file + END \ No newline at end of file diff --git a/libcpu/arm/AT91SAM7X/SConscript b/libcpu/arm/AT91SAM7X/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/AT91SAM7X/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/AT91SAM7X/context_rvds.S b/libcpu/arm/AT91SAM7X/context_rvds.S index 641ec7a6b1..0d8bf56237 100644 --- a/libcpu/arm/AT91SAM7X/context_rvds.S +++ b/libcpu/arm/AT91SAM7X/context_rvds.S @@ -1,16 +1,12 @@ -;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team -; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE -; * -; * Change Logs: -; * Date Author Notes -; * 2009-01-20 Bernard first version -; */ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-20 Bernard first version + */ NOINT EQU 0xc0 ; disable interrupt in psr diff --git a/libcpu/arm/SConscript b/libcpu/arm/SConscript new file mode 100644 index 0000000000..36a214327b --- /dev/null +++ b/libcpu/arm/SConscript @@ -0,0 +1,18 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/arm/am335x/SConscript b/libcpu/arm/am335x/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/am335x/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/arm926/SConscript b/libcpu/arm/arm926/SConscript new file mode 100644 index 0000000000..00785a135b --- /dev/null +++ b/libcpu/arm/arm926/SConscript @@ -0,0 +1,25 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] +ASFLAGS = '' + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + ASFLAGS = ' --cpreproc' + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S index 5152618d24..b6b7863679 100644 --- a/libcpu/arm/arm926/context_gcc.S +++ b/libcpu/arm/arm926/context_gcc.S @@ -1,21 +1,7 @@ ;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * 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. +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S index 14110e5220..902552734e 100644 --- a/libcpu/arm/arm926/context_iar.S +++ b/libcpu/arm/arm926/context_iar.S @@ -1,27 +1,13 @@ -;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, 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-14 weety copy from mini2440 -; * 2015-04-15 ArdaFu convert from context_gcc.s -; */ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-08-14 weety copy from mini2440 + * 2015-04-15 ArdaFu convert from context_gcc.s + */ #define NOINT 0xc0 diff --git a/libcpu/arm/arm926/context_rvds.S b/libcpu/arm/arm926/context_rvds.S index 32bd235fef..03eff68d4c 100644 --- a/libcpu/arm/arm926/context_rvds.S +++ b/libcpu/arm/arm926/context_rvds.S @@ -1,24 +1,10 @@ ;/* -; * file : context_rvds.s -; * this file is part of rt-thread rtos -; * copyright (c) 2006, rt-thread development team +; * 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. +; * SPDX-License-Identifier: Apache-2.0 ; * -; * 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 +; * Change Logs: +; * Date Author Notes ; * 2011-08-14 weety copy from mini2440 ; */ diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S index 880f2d9706..080acd57b6 100644 --- a/libcpu/arm/arm926/start_iar.S +++ b/libcpu/arm/arm926/start_iar.S @@ -1,21 +1,7 @@ ;/* -; * File : start.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * 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. +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S index aca0e4577f..fc7e84ffaa 100644 --- a/libcpu/arm/arm926/start_rvds.S +++ b/libcpu/arm/arm926/start_rvds.S @@ -1,21 +1,7 @@ ;/* -; * File : start_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * 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. +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes @@ -25,7 +11,6 @@ ; * 2015-06-04 aozima Align stack address to 8 byte. ; */ -;#include "rt_low_level_init.h" UND_STK_SIZE EQU 512 SVC_STK_SIZE EQU 4096 ABT_STK_SIZE EQU 512 @@ -35,25 +20,7 @@ SYS_STK_SIZE EQU 512 Heap_Size EQU 512 S_FRAME_SIZE EQU (18*4) ;72 -;S_SPSR EQU (17*4) ;SPSR -;S_CPSR EQU (16*4) ;CPSR S_PC EQU (15*4) ;R15 -;S_LR EQU (14*4) ;R14 -;S_SP EQU (13*4) ;R13 - -;S_IP EQU (12*4) ;R12 -;S_FP EQU (11*4) ;R11 -;S_R10 EQU (10*4) -;S_R9 EQU (9*4) -;S_R8 EQU (8*4) -;S_R7 EQU (7*4) -;S_R6 EQU (6*4) -;S_R5 EQU (5*4) -;S_R4 EQU (4*4) -;S_R3 EQU (3*4) -;S_R2 EQU (2*4) -;S_R1 EQU (1*4) -;S_R0 EQU (0*4) MODE_USR EQU 0X10 MODE_FIQ EQU 0X11 diff --git a/libcpu/arm/armv6/SConscript b/libcpu/arm/armv6/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/armv6/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/common/SConscript b/libcpu/arm/common/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/common/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/common/backtrace.c b/libcpu/arm/common/backtrace.c index f61c69ef01..4fc87b20d1 100644 --- a/libcpu/arm/common/backtrace.c +++ b/libcpu/arm/common/backtrace.c @@ -13,51 +13,51 @@ #ifdef __GNUC__ /* -->High Address,Stack Top -PC<-----| -LR | -IP | -FP | -...... | -PC<-| | -LR | | -IP | | +PC<------| +LR | +IP | +FP | +...... | +PC <-| | +LR | | +IP | | FP---|-- | -...... | -PC | -LR | -IP | +...... | +PC | +LR | +IP | FP--- -->Low Address,Stack Bottom */ void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry) { - rt_uint32_t i, pc, func_entry; + rt_uint32_t i, pc, func_entry; - pc = *fp; - rt_kprintf("[0x%x]\n", pc-0xC); + pc = *fp; + rt_kprintf("[0x%x]\n", pc-0xC); - for(i=0; i<10; i++) - { - fp = (rt_uint32_t *)*(fp - 3); - pc = *fp ; + for(i=0; i<10; i++) + { + fp = (rt_uint32_t *)*(fp - 3); + pc = *fp ; - func_entry = pc - 0xC; + func_entry = pc - 0xC; - if(func_entry <= 0x30000000) break; + if(func_entry <= 0x30000000) break; - if(func_entry == thread_entry) - { - rt_kprintf("EntryPoint:0x%x\n", func_entry); + if(func_entry == thread_entry) + { + rt_kprintf("EntryPoint:0x%x\n", func_entry); - break; - } + break; + } - rt_kprintf("[0x%x]\n", func_entry); - } + rt_kprintf("[0x%x]\n", func_entry); + } } #else void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry) { - /* old compiler implementation */ + /* old compiler implementation */ } #endif diff --git a/libcpu/arm/cortex-a/SConscript b/libcpu/arm/cortex-a/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-a/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m0/SConscript b/libcpu/arm/cortex-m0/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-m0/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m0/context_iar.S b/libcpu/arm/cortex-m0/context_iar.S index 67ea808d8c..50d3781359 100644 --- a/libcpu/arm/cortex-m0/context_iar.S +++ b/libcpu/arm/cortex-m0/context_iar.S @@ -1,11 +1,7 @@ ;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2009, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m0/context_rvds.S b/libcpu/arm/cortex-m0/context_rvds.S index bf68592e63..fb9ce9b4bf 100644 --- a/libcpu/arm/cortex-m0/context_rvds.S +++ b/libcpu/arm/cortex-m0/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2009, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m3/SConscript b/libcpu/arm/cortex-m3/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-m3/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m3/context_iar.S b/libcpu/arm/cortex-m3/context_iar.S index 95dee8062d..91645c48b3 100644 --- a/libcpu/arm/cortex-m3/context_iar.S +++ b/libcpu/arm/cortex-m3/context_iar.S @@ -1,11 +1,7 @@ ;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S index 9a7ff10abe..a2a7f41a27 100644 --- a/libcpu/arm/cortex-m3/context_rvds.S +++ b/libcpu/arm/cortex-m3/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m4/SConscript b/libcpu/arm/cortex-m4/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-m4/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index bf707d0d53..06b8c7f884 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/libcpu/arm/cortex-m4/context_iar.S @@ -1,11 +1,7 @@ ;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m7/SConscript b/libcpu/arm/cortex-m7/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-m7/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m7/context_iar.S b/libcpu/arm/cortex-m7/context_iar.S index bf707d0d53..06b8c7f884 100644 --- a/libcpu/arm/cortex-m7/context_iar.S +++ b/libcpu/arm/cortex-m7/context_iar.S @@ -1,11 +1,7 @@ ;/* -; * File : context_iar.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-m7/context_rvds.S b/libcpu/arm/cortex-m7/context_rvds.S index 1abe477eab..ea9e9cb8b3 100644 --- a/libcpu/arm/cortex-m7/context_rvds.S +++ b/libcpu/arm/cortex-m7/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/cortex-r4/SConscript b/libcpu/arm/cortex-r4/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-r4/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-r4/context_ccs.asm b/libcpu/arm/cortex-r4/context_ccs.asm index 2b459f8238..9463556743 100644 --- a/libcpu/arm/cortex-r4/context_ccs.asm +++ b/libcpu/arm/cortex-r4/context_ccs.asm @@ -1,14 +1,10 @@ ;/* -; * File : context_ccs.asm -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: -; * Date Author Notes +; * Date Author Notes ; * 2009-01-20 Bernard first version ; * 2011-07-22 Bernard added thumb mode porting ; * 2013-05-24 Grissiom port to CCS diff --git a/libcpu/arm/dm36x/SConscript b/libcpu/arm/dm36x/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/dm36x/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/dm36x/context_rvds.S b/libcpu/arm/dm36x/context_rvds.S index 631da83372..8e0fc4465b 100644 --- a/libcpu/arm/dm36x/context_rvds.S +++ b/libcpu/arm/dm36x/context_rvds.S @@ -1,21 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * 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. +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/lpc214x/SConscript b/libcpu/arm/lpc214x/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/lpc214x/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/lpc214x/context_rvds.S b/libcpu/arm/lpc214x/context_rvds.S index 762b67d42e..47ca31cd1f 100644 --- a/libcpu/arm/lpc214x/context_rvds.S +++ b/libcpu/arm/lpc214x/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/lpc24xx/SConscript b/libcpu/arm/lpc24xx/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/lpc24xx/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/lpc24xx/context_rvds.S b/libcpu/arm/lpc24xx/context_rvds.S index ecd20e4bbe..0d9915f4f1 100644 --- a/libcpu/arm/lpc24xx/context_rvds.S +++ b/libcpu/arm/lpc24xx/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/realview-a8-vmm/SConscript b/libcpu/arm/realview-a8-vmm/SConscript index 61057c04cc..9ff30a796b 100644 --- a/libcpu/arm/realview-a8-vmm/SConscript +++ b/libcpu/arm/realview-a8-vmm/SConscript @@ -1,17 +1,23 @@ -Import('rtconfig') +# RT-Thread building script for component + from building import * +Import('rtconfig') + cwd = GetCurrentDir() -src = Glob('*.c') +src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + if rtconfig.PLATFORM == 'iar': - src += Glob('*_iar.S') -elif rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') -elif rtconfig.PLATFORM == 'armcc': - src += Glob('*_rvds.S') + src += Glob('*_iar.S') -group = DefineGroup('AM335x', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/s3c24x0/SConscript b/libcpu/arm/s3c24x0/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/s3c24x0/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/s3c24x0/context_rvds.S b/libcpu/arm/s3c24x0/context_rvds.S index 54d655afe1..9078f6173a 100644 --- a/libcpu/arm/s3c24x0/context_rvds.S +++ b/libcpu/arm/s3c24x0/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/s3c44b0/SConscript b/libcpu/arm/s3c44b0/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/s3c44b0/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/s3c44b0/context_rvds.S b/libcpu/arm/s3c44b0/context_rvds.S index 641ec7a6b1..27ebf8f5e3 100644 --- a/libcpu/arm/s3c44b0/context_rvds.S +++ b/libcpu/arm/s3c44b0/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/sep4020/SConscript b/libcpu/arm/sep4020/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/sep4020/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/sep4020/context_rvds.S b/libcpu/arm/sep4020/context_rvds.S index 641ec7a6b1..27ebf8f5e3 100644 --- a/libcpu/arm/sep4020/context_rvds.S +++ b/libcpu/arm/sep4020/context_rvds.S @@ -1,11 +1,7 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * Copyright (c) 2006-2018, RT-Thread Development Team ; * -; * The license and distribution terms for this file may be -; * found in the file LICENSE in this distribution or at -; * http://www.rt-thread.org/license/LICENSE +; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes diff --git a/libcpu/arm/zynq7000/SConscript b/libcpu/arm/zynq7000/SConscript index 2ad51b573e..9ff30a796b 100644 --- a/libcpu/arm/zynq7000/SConscript +++ b/libcpu/arm/zynq7000/SConscript @@ -1,17 +1,23 @@ -Import('rtconfig') +# RT-Thread building script for component + from building import * +Import('rtconfig') + cwd = GetCurrentDir() -src = Glob('*.c') +src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + if rtconfig.PLATFORM == 'iar': - src += Glob('*_iar.S') -elif rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') -elif rtconfig.PLATFORM == 'armcc': - src += Glob('*_rvds.S') + src += Glob('*_iar.S') -group = DefineGroup('AM1808', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/zynq7000/context_gcc.S b/libcpu/arm/zynq7000/context_gcc.S index 3dbf3c861d..98f98a0244 100644 --- a/libcpu/arm/zynq7000/context_gcc.S +++ b/libcpu/arm/zynq7000/context_gcc.S @@ -1,21 +1,11 @@ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * Copyright (c) 2006-2018, Shanghai Real-Thread Technology Co., Ltd * - * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2009-01-20 Bernard first version */ #define NOINT 0xc0 diff --git a/libcpu/arm/zynq7000/cp15.h b/libcpu/arm/zynq7000/cp15.h index bd6a23f1b2..75d81736ab 100644 --- a/libcpu/arm/zynq7000/cp15.h +++ b/libcpu/arm/zynq7000/cp15.h @@ -1,25 +1,16 @@ -#ifndef __CP15_H__ -#define __CP15_H__ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd - * - * All rights reserved. - * - * 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. + * Copyright (c) 2006-2018, RT-Thread Development Team * - * 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. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ +#ifndef __CP15_H__ +#define __CP15_H__ + unsigned long rt_cpu_get_smp_id(void); void rt_cpu_mmu_disable(void); diff --git a/libcpu/arm/zynq7000/gic.c b/libcpu/arm/zynq7000/gic.c index 498446db43..e23a359e6e 100644 --- a/libcpu/arm/zynq7000/gic.c +++ b/libcpu/arm/zynq7000/gic.c @@ -1,21 +1,11 @@ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * Copyright (c) 2006-2018, RT-Thread Development Team * - * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ #include diff --git a/libcpu/arm/zynq7000/gic.h b/libcpu/arm/zynq7000/gic.h index 4b89538948..8fcdf05f6f 100644 --- a/libcpu/arm/zynq7000/gic.h +++ b/libcpu/arm/zynq7000/gic.h @@ -1,21 +1,11 @@ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * Copyright (c) 2006-2018, RT-Thread Development Team * - * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ #ifndef __GIC_H__ diff --git a/libcpu/arm/zynq7000/interrupt.h b/libcpu/arm/zynq7000/interrupt.h index 07eafc84e5..da266c42a2 100644 --- a/libcpu/arm/zynq7000/interrupt.h +++ b/libcpu/arm/zynq7000/interrupt.h @@ -1,25 +1,16 @@ -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd - * - * All rights reserved. - * - * 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. + * Copyright (c) 2006-2018, RT-Thread Development Team * - * 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. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + void rt_hw_interrupt_clear(int vector); #endif /* end of include guard: __INTERRUPT_H__ */ diff --git a/libcpu/arm/zynq7000/mmu.c b/libcpu/arm/zynq7000/mmu.c index 2a58fabe4f..fbdacca10f 100644 --- a/libcpu/arm/zynq7000/mmu.c +++ b/libcpu/arm/zynq7000/mmu.c @@ -1,21 +1,11 @@ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * Copyright (c) 2006-2018, RT-Thread Development Team * - * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ #include diff --git a/libcpu/arm/zynq7000/trap.c b/libcpu/arm/zynq7000/trap.c index 9bf58f916c..6243ea82b4 100644 --- a/libcpu/arm/zynq7000/trap.c +++ b/libcpu/arm/zynq7000/trap.c @@ -1,21 +1,11 @@ /* - * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * Copyright (c) 2006-2018, RT-Thread Development Team * - * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 * - * 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 + * 2013-07-20 Bernard first version */ #include diff --git a/libcpu/avr32/SConscript b/libcpu/avr32/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/avr32/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/avr32/uc3/SConscript b/libcpu/avr32/uc3/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/avr32/uc3/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/blackfin/SConscript b/libcpu/blackfin/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/blackfin/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/blackfin/bf53x/SConscript b/libcpu/blackfin/bf53x/SConscript new file mode 100644 index 0000000000..af9ba4bc81 --- /dev/null +++ b/libcpu/blackfin/bf53x/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_vdsp.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/c-sky/SConscript b/libcpu/c-sky/SConscript new file mode 100644 index 0000000000..36a214327b --- /dev/null +++ b/libcpu/c-sky/SConscript @@ -0,0 +1,18 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/c-sky/ck802/SConscript b/libcpu/c-sky/ck802/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/c-sky/ck802/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/c-sky/common/SConscript b/libcpu/c-sky/common/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/c-sky/common/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/ia32/SConscript b/libcpu/ia32/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/ia32/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/m16c/SConscript b/libcpu/m16c/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/m16c/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/m16c/m16c62p/SConscript b/libcpu/m16c/m16c62p/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/m16c/m16c62p/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/SConscript b/libcpu/mips/SConscript new file mode 100644 index 0000000000..ced01a4b3e --- /dev/null +++ b/libcpu/mips/SConscript @@ -0,0 +1,18 @@ +# RT-Thread building script for bridge + +import os +from building import * + +import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/mips/common/SConscript b/libcpu/mips/common/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/common/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/loongson_1b/SConscript b/libcpu/mips/loongson_1b/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/loongson_1b/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/loongson_1c/SConscript b/libcpu/mips/loongson_1c/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/loongson_1c/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/pic32/SConscript b/libcpu/mips/pic32/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/pic32/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/x1000/SConscript b/libcpu/mips/x1000/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/x1000/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/mips/xburst/SConscript.1 b/libcpu/mips/xburst/SConscript.1 new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/mips/xburst/SConscript.1 @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/nios/SConscript b/libcpu/nios/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/nios/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/nios/nios_ii/SConscript b/libcpu/nios/nios_ii/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/nios/nios_ii/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/ppc/SConscript b/libcpu/ppc/SConscript new file mode 100644 index 0000000000..36a214327b --- /dev/null +++ b/libcpu/ppc/SConscript @@ -0,0 +1,18 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/ppc/common/SConscript b/libcpu/ppc/common/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/ppc/common/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/ppc/common/ptrace.h b/libcpu/ppc/common/ptrace.h index d60e7fdcef..72ef31bfbc 100644 --- a/libcpu/ppc/common/ptrace.h +++ b/libcpu/ppc/common/ptrace.h @@ -21,20 +21,20 @@ #define PPC_REG unsigned long struct pt_regs { - PPC_REG gpr[32]; - PPC_REG nip; - PPC_REG msr; - PPC_REG orig_gpr3; /* Used for restarting system calls */ - PPC_REG ctr; - PPC_REG link; - PPC_REG xer; - PPC_REG ccr; - PPC_REG mq; /* 601 only (not used at present) */ - /* Used on APUS to hold IPL value. */ - PPC_REG trap; /* Reason for being here */ - PPC_REG dar; /* Fault registers */ - PPC_REG dsisr; - PPC_REG result; /* Result of a system call */ + PPC_REG gpr[32]; + PPC_REG nip; + PPC_REG msr; + PPC_REG orig_gpr3; /* Used for restarting system calls */ + PPC_REG ctr; + PPC_REG link; + PPC_REG xer; + PPC_REG ccr; + PPC_REG mq; /* 601 only (not used at present) */ + /* Used on APUS to hold IPL value. */ + PPC_REG trap; /* Reason for being here */ + PPC_REG dar; /* Fault registers */ + PPC_REG dsisr; + PPC_REG result; /* Result of a system call */ }__attribute__((packed)) CELL_STACK_FRAME_t; #endif diff --git a/libcpu/ppc/ppc405/SConscript b/libcpu/ppc/ppc405/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/ppc/ppc405/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/SConscript b/libcpu/risc-v/SConscript new file mode 100644 index 0000000000..36a214327b --- /dev/null +++ b/libcpu/risc-v/SConscript @@ -0,0 +1,18 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/risc-v/common/SConscript b/libcpu/risc-v/common/SConscript new file mode 100644 index 0000000000..2f698f530a --- /dev/null +++ b/libcpu/risc-v/common/SConscript @@ -0,0 +1,12 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/e310/SConscript b/libcpu/risc-v/e310/SConscript index 4e4bc0c3d9..b0ae20ba02 100644 --- a/libcpu/risc-v/e310/SConscript +++ b/libcpu/risc-v/e310/SConscript @@ -1,13 +1,14 @@ -Import('rtconfig') +# RT-Thread building script for component + from building import * +Import('rtconfig') + cwd = GetCurrentDir() -src = Glob('*.c') +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] +ASFLAGS = '' -if rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') - -group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/k210/SConscript b/libcpu/risc-v/k210/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/risc-v/k210/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/rv32m1/SConscript b/libcpu/risc-v/rv32m1/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/risc-v/rv32m1/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/rx/SConscript b/libcpu/rx/SConscript new file mode 100644 index 0000000000..e5890498c9 --- /dev/null +++ b/libcpu/rx/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_iar.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/sim/SConscript b/libcpu/sim/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/sim/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/sim/posix/SConscript b/libcpu/sim/posix/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/sim/posix/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/sim/win32/SConscript b/libcpu/sim/win32/SConscript new file mode 100644 index 0000000000..afab42d47c --- /dev/null +++ b/libcpu/sim/win32/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/ti-dsp/SConscript b/libcpu/ti-dsp/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/ti-dsp/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/ti-dsp/c28x/SConscript b/libcpu/ti-dsp/c28x/SConscript new file mode 100644 index 0000000000..08b274341b --- /dev/null +++ b/libcpu/ti-dsp/c28x/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*.s') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/unicore32/SConscript b/libcpu/unicore32/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/unicore32/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/unicore32/sep6200/SConscript b/libcpu/unicore32/sep6200/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/unicore32/sep6200/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/v850/70f34/SConscript b/libcpu/v850/70f34/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/v850/70f34/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/v850/SConscript b/libcpu/v850/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/v850/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/xilinx/SConscript b/libcpu/xilinx/SConscript new file mode 100644 index 0000000000..ebdd1357ee --- /dev/null +++ b/libcpu/xilinx/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/xilinx/microblaze/SConscript b/libcpu/xilinx/microblaze/SConscript new file mode 100644 index 0000000000..b0ae20ba02 --- /dev/null +++ b/libcpu/xilinx/microblaze/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') -- cgit v1.3.1 From 4c0aafb57f508db9bba73eae7ab9c6a4c1adf231 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Mon, 7 Jan 2019 09:20:30 +0800 Subject: [libcpu] Fix the SCoscript issue in cpu/MIPS. --- libcpu/mips/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libcpu') diff --git a/libcpu/mips/SConscript b/libcpu/mips/SConscript index ced01a4b3e..36a214327b 100644 --- a/libcpu/mips/SConscript +++ b/libcpu/mips/SConscript @@ -3,7 +3,7 @@ import os from building import * -import('rtconfig') +Import('rtconfig') cwd = GetCurrentDir() group = [] -- cgit v1.3.1 From 3a3c6c51f890fd4ee5fac446778c6beea24ebd26 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Mon, 7 Jan 2019 21:16:05 +0800 Subject: [libcpu] remove cache.h from mips/common folder. --- libcpu/mips/common/cache.h | 232 --------------------------------------------- 1 file changed, 232 deletions(-) delete mode 100644 libcpu/mips/common/cache.h (limited to 'libcpu') diff --git a/libcpu/mips/common/cache.h b/libcpu/mips/common/cache.h deleted file mode 100644 index 1c7cf41324..0000000000 --- a/libcpu/mips/common/cache.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Cache operations for the cache instruction. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle - * (C) Copyright 1999 Silicon Graphics, Inc. - */ -#ifndef __CACHE_H__ -#define __CACHE_H__ - - -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 - -/* - * Cache Operations available on all MIPS processors with R4000-style caches - */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 -#define Index_Load_Tag_I 0x04 -#define Index_Load_Tag_D 0x05 -#define Index_Store_Tag_I 0x08 -#define Index_Store_Tag_D 0x09 - -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 -#define Hit_Writeback_Inv_D 0x15 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 - -/* - *The lock state is cleared by executing an Index -Invalidate, Index Writeback Invalidate, Hit -Invalidate, or Hit Writeback Invalidate -operation to the locked line, or via an Index -Store Tag operation with the lock bit reset in -the TagLo register. - */ -#define Fetch_And_Lock_I 0x1c -#define Fetch_And_Lock_D 0x1d -/* - * R4000-specific cacheops - */ -#define Create_Dirty_Excl_D 0x0d -#define Fill 0x14 - -/* - * R4000SC and R4400SC-specific cacheops - */ -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 -#define Index_Store_Tag_SI 0x0A -#define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_SI 0x12 -#define Hit_Invalidate_SD 0x13 -#define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_SD 0x1b -#define Hit_Set_Virtual_SI 0x1e -#define Hit_Set_Virtual_SD 0x1f - -/* - * R5000-specific cacheops - */ -#define R5K_Page_Invalidate_S 0x17 - -/* - * RM7000-specific cacheops - */ -#define Page_Invalidate_T 0x16 - -/* - * R1000-specific cacheops - * - * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. - * Most of the _S cacheops are identical to the R4000SC _SD cacheops. - */ -#define Index_Writeback_Inv_S 0x03 -#define Index_Load_Tag_S 0x07 -#define Index_Store_Tag_S 0x0B -#define Hit_Invalidate_S 0x13 -#define Cache_Barrier 0x14 -#define Hit_Writeback_Inv_S 0x17 -#define Index_Load_Data_I 0x18 -#define Index_Load_Data_D 0x19 -#define Index_Load_Data_S 0x1b -#define Index_Store_Data_I 0x1c -#define Index_Store_Data_D 0x1d -#define Index_Store_Data_S 0x1f - - -#ifndef __ASSEMBLER__ - -#ifndef dcache_size -#define dcache_size (g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size) -#endif - -#ifndef icache_size -#define icache_size (g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size) -#endif - -#ifndef cpu_dcache_line_size -#define cpu_dcache_line_size() g_mips_core.icache_line_size -#endif - -#ifndef cpu_icache_line_size -#define cpu_icache_line_size() g_mips_core.icache_line_size -#endif - -#define cache_op(op, addr) \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " .set mips3\n\t \n" \ - " cache %0, %1 \n" \ - " .set mips0 \n" \ - " .set reorder" \ - : \ - : "i" (op), "m" (*(unsigned char *)(addr))) - -#define cache16_unroll32(base, op) \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " .set mips3 \n" \ - " cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \ - " cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \ - " cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \ - " cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \ - " cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \ - " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \ - " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \ - " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \ - " cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \ - " cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \ - " cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \ - " cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \ - " cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \ - " cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \ - " cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \ - " cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \ - " .set mips0 \n" \ - " .set reorder \n" \ - : \ - : "r" (base), \ - "i" (op)); - - -static inline void flush_icache_line_indexed(rt_ubase_t addr) -{ - cache_op(Index_Invalidate_I, addr); -} - -static inline void flush_dcache_line_indexed(rt_ubase_t addr) -{ - cache_op(Index_Writeback_Inv_D, addr); -} - -static inline void flush_icache_line(rt_ubase_t addr) -{ - cache_op(Hit_Invalidate_I, addr); -} - -static inline void lock_icache_line(rt_ubase_t addr) -{ - cache_op(Fetch_And_Lock_I, addr); -} - -static inline void lock_dcache_line(rt_ubase_t addr) -{ - cache_op(Fetch_And_Lock_D, addr); -} - -static inline void flush_dcache_line(rt_ubase_t addr) -{ - cache_op(Hit_Writeback_Inv_D, addr); -} - -static inline void invalidate_dcache_line(rt_ubase_t addr) -{ - cache_op(Hit_Invalidate_D, addr); -} - -static inline void blast_dcache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + dcache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Index_Writeback_Inv_D); -} - -static inline void inv_dcache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + dcache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Hit_Invalidate_D); -} - -static inline void blast_icache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + icache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Index_Invalidate_I); -} - - - -void r4k_cache_init(void); -void r4k_cache_flush_all(void); -void r4k_icache_flush_all(void); -void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size); -void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size); -void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size); -void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size); - -#endif /*end of __ASSEMBLER__ */ - -#endif /* end of __CACHE_H__ */ -- cgit v1.3.1 From d8aa99a29c47da520986dcd79fff9861d97ca6ed Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Wed, 23 Jan 2019 17:29:54 +0800 Subject: [bsp][synopsys] add the support of synopsys arc emsk * the initial support of synopsys designware arc processor * the initial support of synospsy ARC EM Starter Kit * the bsp code is based on embarc which is a common SDK for all synopsys ARC-based boards * use "scons --gdb" to debug emsk with em9d configuration * for detailed board information, pls go embarc.org Signed-off-by: Wayne Ren --- bsp/synopsys/embarc/SConscript | 28 + bsp/synopsys/embarc/arc/arc_cache.c | 420 ++++++ bsp/synopsys/embarc/arc/arc_exc_asm.S | 201 +++ bsp/synopsys/embarc/arc/arc_exception.c | 501 +++++++ bsp/synopsys/embarc/arc/arc_timer.c | 211 +++ bsp/synopsys/embarc/arc/startup/arc_cxx_support.c | 168 +++ bsp/synopsys/embarc/arc/startup/arc_startup.S | 262 ++++ .../embarc/device/designware/gpio/dw_gpio.c | 481 ++++++ .../embarc/device/designware/gpio/dw_gpio.h | 145 ++ bsp/synopsys/embarc/device/designware/iic/dw_iic.c | 1584 ++++++++++++++++++++ bsp/synopsys/embarc/device/designware/iic/dw_iic.h | 242 +++ .../embarc/device/designware/iic/dw_iic_hal.h | 186 +++ .../embarc/device/designware/iic/dw_iic_hal_cfg.h | 82 + bsp/synopsys/embarc/device/designware/spi/dw_spi.c | 1337 +++++++++++++++++ bsp/synopsys/embarc/device/designware/spi/dw_spi.h | 190 +++ .../embarc/device/designware/spi/dw_spi_hal.h | 141 ++ .../embarc/device/designware/spi/dw_spi_hal_cfg.h | 58 + .../embarc/device/designware/uart/dw_uart.c | 956 ++++++++++++ .../embarc/device/designware/uart/dw_uart.h | 141 ++ .../embarc/device/designware/uart/dw_uart_hal.h | 253 ++++ .../embarc/device/device_hal/inc/dev_common.h | 173 +++ .../embarc/device/device_hal/inc/dev_gpio.h | 424 ++++++ .../embarc/device/device_hal/inc/dev_iic.h | 526 +++++++ .../embarc/device/device_hal/inc/dev_spi.h | 577 +++++++ .../embarc/device/device_hal/inc/dev_uart.h | 475 ++++++ bsp/synopsys/embarc/inc/arc/arc.h | 436 ++++++ bsp/synopsys/embarc/inc/arc/arc_asm_common.h | 541 +++++++ bsp/synopsys/embarc/inc/arc/arc_builtin.h | 301 ++++ bsp/synopsys/embarc/inc/arc/arc_cache.h | 321 ++++ bsp/synopsys/embarc/inc/arc/arc_em.h | 133 ++ bsp/synopsys/embarc/inc/arc/arc_exception.h | 461 ++++++ bsp/synopsys/embarc/inc/arc/arc_feature_config.h | 397 +++++ bsp/synopsys/embarc/inc/arc/arc_timer.h | 99 ++ bsp/synopsys/embarc/inc/embARC_debug.h | 94 ++ bsp/synopsys/embarc/inc/embARC_error.h | 156 ++ bsp/synopsys/embarc/inc/embARC_toolchain.h | 121 ++ bsp/synopsys/emsk_em9d/.config | 402 +++++ bsp/synopsys/emsk_em9d/Kconfig | 26 + bsp/synopsys/emsk_em9d/SConscript | 18 + bsp/synopsys/emsk_em9d/SConstruct | 52 + bsp/synopsys/emsk_em9d/applications/SConscript | 11 + bsp/synopsys/emsk_em9d/applications/application.c | 29 + bsp/synopsys/emsk_em9d/applications/startup.c | 71 + bsp/synopsys/emsk_em9d/drivers/Kconfig | 10 + bsp/synopsys/emsk_em9d/drivers/SConscript | 15 + bsp/synopsys/emsk_em9d/drivers/arc_core_config.h | 229 +++ bsp/synopsys/emsk_em9d/drivers/board.c | 283 ++++ bsp/synopsys/emsk_em9d/drivers/board.h | 28 + bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c | 324 ++++ bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h | 51 + bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c | 210 +++ bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h | 52 + bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h | 39 + bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h | 85 ++ bsp/synopsys/emsk_em9d/drivers/mux.c | 67 + bsp/synopsys/emsk_em9d/drivers/mux.h | 147 ++ bsp/synopsys/emsk_em9d/drivers/mux_hal.h | 29 + bsp/synopsys/emsk_em9d/emsk_em9d.ld | 114 ++ bsp/synopsys/emsk_em9d/openocd.log | 9 + bsp/synopsys/emsk_em9d/rtconfig.h | 142 ++ bsp/synopsys/emsk_em9d/rtconfig.py | 60 + libcpu/arc/SConscript | 17 + libcpu/arc/common/SConscript | 10 + libcpu/arc/em/SConscript | 17 + libcpu/arc/em/contex_gcc.S | 266 ++++ libcpu/arc/em/cpuport.c | 69 + 66 files changed, 15704 insertions(+) create mode 100644 bsp/synopsys/embarc/SConscript create mode 100644 bsp/synopsys/embarc/arc/arc_cache.c create mode 100644 bsp/synopsys/embarc/arc/arc_exc_asm.S create mode 100644 bsp/synopsys/embarc/arc/arc_exception.c create mode 100644 bsp/synopsys/embarc/arc/arc_timer.c create mode 100644 bsp/synopsys/embarc/arc/startup/arc_cxx_support.c create mode 100644 bsp/synopsys/embarc/arc/startup/arc_startup.S create mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c create mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.h create mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.c create mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.h create mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h create mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h create mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.c create mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.h create mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h create mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h create mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.c create mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.h create mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h create mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_common.h create mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h create mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h create mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h create mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_asm_common.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_builtin.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_cache.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_em.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_exception.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_feature_config.h create mode 100644 bsp/synopsys/embarc/inc/arc/arc_timer.h create mode 100644 bsp/synopsys/embarc/inc/embARC_debug.h create mode 100644 bsp/synopsys/embarc/inc/embARC_error.h create mode 100644 bsp/synopsys/embarc/inc/embARC_toolchain.h create mode 100644 bsp/synopsys/emsk_em9d/.config create mode 100644 bsp/synopsys/emsk_em9d/Kconfig create mode 100644 bsp/synopsys/emsk_em9d/SConscript create mode 100644 bsp/synopsys/emsk_em9d/SConstruct create mode 100644 bsp/synopsys/emsk_em9d/applications/SConscript create mode 100644 bsp/synopsys/emsk_em9d/applications/application.c create mode 100644 bsp/synopsys/emsk_em9d/applications/startup.c create mode 100644 bsp/synopsys/emsk_em9d/drivers/Kconfig create mode 100644 bsp/synopsys/emsk_em9d/drivers/SConscript create mode 100644 bsp/synopsys/emsk_em9d/drivers/arc_core_config.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/board.c create mode 100644 bsp/synopsys/emsk_em9d/drivers/board.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c create mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c create mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.c create mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.h create mode 100644 bsp/synopsys/emsk_em9d/drivers/mux_hal.h create mode 100644 bsp/synopsys/emsk_em9d/emsk_em9d.ld create mode 100644 bsp/synopsys/emsk_em9d/openocd.log create mode 100644 bsp/synopsys/emsk_em9d/rtconfig.h create mode 100644 bsp/synopsys/emsk_em9d/rtconfig.py create mode 100644 libcpu/arc/SConscript create mode 100644 libcpu/arc/common/SConscript create mode 100644 libcpu/arc/em/SConscript create mode 100644 libcpu/arc/em/contex_gcc.S create mode 100644 libcpu/arc/em/cpuport.c (limited to 'libcpu') diff --git a/bsp/synopsys/embarc/SConscript b/bsp/synopsys/embarc/SConscript new file mode 100644 index 0000000000..9e086739af --- /dev/null +++ b/bsp/synopsys/embarc/SConscript @@ -0,0 +1,28 @@ +from building import * + +cwd = GetCurrentDir() + +embarc_arc_hal_SRCS = Split(""" +arc/arc_cache.c +arc/arc_exc_asm.S +arc/arc_exception.c +arc/arc_timer.c +arc/startup/arc_cxx_support.c +arc/startup/arc_startup.S +device/designware/uart/dw_uart.c +device/designware/gpio/dw_gpio.c +""") + + +ASFLAGS = ' -I' + cwd + +src = embarc_arc_hal_SRCS + +path = [cwd, + cwd + '/arc', + cwd + '/arc/startup' + ] + +group = DefineGroup('embarc', src, depend = [], CPPPATH = path, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/bsp/synopsys/embarc/arc/arc_cache.c b/bsp/synopsys/embarc/arc/arc_cache.c new file mode 100644 index 0000000000..632a3e3291 --- /dev/null +++ b/bsp/synopsys/embarc/arc/arc_cache.c @@ -0,0 +1,420 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_MISC_CACHE + * \brief implementation of cache related functions + */ + +#include "inc/arc/arc_cache.h" + +#define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) + + +struct cache_config { + uint8_t ver; /* version */ + uint8_t assoc; /* Cache Associativity */ + uint16_t line; /* cache line/block size */ + uint32_t capacity; /* capacity */ +}; + + +static struct cache_config icache_config, dcache_config; + +/** + * \brief invalidate multi instruction cache lines + * + * \param[in] start_addr start address in instruction cache + * \param[in] size the bytes to be invalidated + * \return 0, succeeded, -1, failed + */ +int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size) +{ + if (!icache_available()) return -1; + + if ((size == 0) || (size > icache_config.capacity)) { + return -1; + } + + uint32_t end_addr; + uint32_t line_size; + uint32_t status; + + line_size = (uint32_t)(icache_config.line); + end_addr = start_addr + size - 1; + start_addr &= (uint32_t)(~(line_size - 1)); + + status = cpu_lock_save(); + do { + _arc_aux_write(AUX_IC_IVIL, start_addr); + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); + start_addr += line_size; + } while (start_addr <= end_addr); + cpu_unlock_restore(status); + + return 0; +} + +/** + * \brief lock multi lines in instruction cache + * + * \param[in] start_addr start address in instruction cache + * \param[in] size the bytes to be locked + * \return 0, succeeded, -1, failed (cache already locked or other reasons) + */ +int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size) +{ + if (!icache_available()) return -1; + + if ((size == 0) || (size > icache_config.capacity)) { + return -1; + } + + uint32_t end_addr; + uint32_t line_size; + uint32_t status; + int32_t ercd = 0; + + line_size = (uint32_t)(icache_config.line); + end_addr = start_addr + size - 1; + start_addr &= (uint32_t)(~(line_size - 1)); + + status = cpu_lock_save(); + do { + _arc_aux_write(AUX_IC_LIL, start_addr); + if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { + start_addr += line_size; + } else { + ercd = -1; /* the operation failed */ + break; + } + } while (start_addr <= end_addr); + cpu_unlock_restore(status); + + return ercd; +} + +/** + * \brief directly write icache internal ram + * + * \param[in] cache_addr, icache internal address(way+index+offset) + * \param[in] tag cache tag to write (tag+lock bit+valid bit) + * \param[in] data cache data to write + * \return 0, succeeded, -1, failed + */ +int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data) +{ + if (!icache_available()) return -1; + + if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) { + return -1; + } + _arc_aux_write(AUX_IC_RAM_ADDR, cache_addr); + _arc_aux_write(AUX_IC_TAG, tag ); + _arc_aux_write(AUX_IC_DATA, data); + + return 0; +} + +/** + * \brief directly read icache internal ram + * + * \param[in] cache_addr, icache internal address(way+index+offset) + * \param[out] tag cache tag to read (tag+index+lock bit+valid bit) + * \param[out] data cache data to read + * \return 0, succeeded, -1, failed + */ +int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data) +{ + if (!icache_available()) return -1; + + if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) { + return -1; + } + _arc_aux_write(AUX_IC_RAM_ADDR, cache_addr); + *tag = _arc_aux_read(AUX_IC_TAG); + *data = _arc_aux_read(AUX_IC_DATA); + + return 0; +} + +/** + * \brief indirectly read icache internal ram + * + * \param[in] mem_addr, memory address + * \param[out] tag cache tag to read + * \param[out] data cache data to read + * \return 0, succeeded, -1, failed + */ +int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data) +{ + if (!icache_available()) return -1; + + if (!(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS)) { + return -1; + } + _arc_aux_write(AUX_IC_RAM_ADDR, mem_addr); + if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { + *tag = _arc_aux_read(AUX_IC_TAG); + *data = _arc_aux_read(AUX_IC_DATA); + } else { + return -1; /* the specified memory is not in icache */ + } + return 0; + } + +/** + * \brief invalidate multi data cache lines + * + * \param[in] start_addr start address in data cache + * \param[in] size the bytes to be invalidated + * \return 0, succeeded, -1, failed + */ +int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size) +{ + if (!dcache_available()) return -1; + + uint32_t end_addr; + uint32_t line_size; + uint32_t status; + + if ((size == 0) || (size > dcache_config.capacity)) { + return -1; + } + + line_size = (uint32_t)(dcache_config.line); + end_addr = start_addr + size - 1; + start_addr &= (uint32_t)(~(line_size - 1)); + + status = cpu_lock_save(); + do { + _arc_aux_write(AUX_DC_IVDL, start_addr); + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); + /* wait for flush completion */ + while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); + start_addr += line_size; + } while (start_addr <= end_addr); + cpu_unlock_restore(status); + + return 0; + +} + +/** + * \brief flush multi lines in data cache + * + * \param[in] start_addr start address + * \param[in] size the bytes to be flushed + * \return 0, succeeded, -1, failed + */ +int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size) +{ + if (!dcache_available()) return -1; + + if ((size == 0) || (size > dcache_config.capacity)) { + return -1; + } + + uint32_t end_addr; + uint32_t line_size; + uint32_t status; + + line_size = (uint32_t)(dcache_config.line); + end_addr = start_addr + size - 1; + start_addr &= (uint32_t)(~(line_size - 1)); + + status = cpu_lock_save(); + do { + _arc_aux_write(AUX_DC_FLDL, start_addr); + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); + /* wait for flush completion */ + while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); + start_addr += line_size; + } while (start_addr <= end_addr); + cpu_unlock_restore(status); + + return 0; +} + +/** + * \brief lock multi lines in data cache + * + * \param[in] start_addr start address in data cache + * \param[in] size the bytes to be locked + * \return 0, succeeded, -1, failed + */ +int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size) +{ + if (!dcache_available()) return -1; + + if ((size == 0) || (size > dcache_config.capacity)) { + return -1; + } + + uint32_t end_addr; + uint32_t line_size; + uint32_t status; + int32_t ercd = 0; + + line_size = (uint32_t)(dcache_config.line); + end_addr = start_addr + size - 1; + start_addr &= (uint32_t)(~(line_size - 1)); + + status = cpu_lock_save(); + do { + _arc_aux_write(AUX_DC_LDL, start_addr); + Asm("nop_s"); + if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { + start_addr += line_size; + } else { + ercd = -1; /* the operation failed */ + break; + } + } while (start_addr <= end_addr); + cpu_unlock_restore(status); + + return ercd; +} + +/** + * \brief directly write dcache internal ram + * + * \param[in] cache_addr, dcache internal address(way+index+offset) + * \param[in] tag cache tag to write + * \param[in] data cache data to write + * \return 0, succeeded, -1, failed + */ +int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data) +{ + if (!dcache_available()) return -1; + + if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) { + return -1; + } + _arc_aux_write(AUX_DC_RAM_ADDR, cache_addr); + _arc_aux_write(AUX_DC_TAG, tag); + _arc_aux_write(AUX_DC_DATA, data); + + return 0; +} + +/** + * \brief directly read dcache internal ram + * + * \param[in] cache_addr, dcache internal address(way+index+offset) + * \param[out] tag cache tag to read + * \param[out] data cache data to read + * \return 0, succeeded, -1, failed + */ +int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data) +{ + if (!dcache_available()) return -1; + + if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) { + return -1; + } + _arc_aux_write(AUX_DC_RAM_ADDR, cache_addr); + *tag = _arc_aux_read(AUX_DC_TAG); + *data = _arc_aux_read(AUX_DC_DATA); + + return 0; +} + +/** + * \brief indirectly read dcache internal ram + * + * \param[in] mem_addr, memory address(tag+index+offset) + * \param[out] tag cache tag to read + * \param[out] data cache data to read + * \return 0, succeeded, -1, failed + */ +int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data) +{ + if (!dcache_available()) return -1; + + if (!(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS)) { + return -1; + } + _arc_aux_write(AUX_DC_RAM_ADDR, mem_addr); + if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { + *tag = _arc_aux_read(AUX_DC_TAG); + *data = _arc_aux_read(AUX_DC_DATA); + } else { + return -1; /* the specified memory is not in dcache */ + } + return 0; + } + +/** + * \brief initialize cache + * 1. invalidate icache and dcache + * 2. Only support ARCv2 cache + */ +void arc_cache_init(void) +{ + uint32_t build_cfg; + + build_cfg = _arc_aux_read(AUX_BCR_D_CACHE); + + dcache_config.ver = build_cfg & 0xff; + + if (dcache_config.ver >= 0x04) { /* ARCv2 */ + dcache_enable(DC_CTRL_DISABLE_FLUSH_LOCKED | + DC_CTRL_INDIRECT_ACCESS | DC_CTRL_INVALID_FLUSH); + dcache_invalidate(); + dcache_config.assoc = 1 << ((build_cfg >> 8) & 0xf); + dcache_config.capacity = 512 << ((build_cfg >> 12) & 0xf); + dcache_config.line = 16 << ((build_cfg >> 16) & 0xf); + } + + build_cfg = _arc_aux_read(AUX_BCR_I_CACHE); + + icache_config.ver = build_cfg & 0xff; + + if (icache_config.ver >= 0x04) { /* ARCv2 */ + icache_config.assoc = 1 << ((build_cfg >> 8) & 0xf); + icache_config.capacity = 512 << ((build_cfg >> 12) & 0xf); + icache_config.line = 8 << ((build_cfg >> 16) & 0xf); + + icache_enable(IC_CTRL_IC_ENABLE); + icache_invalidate(); + } + +} diff --git a/bsp/synopsys/embarc/arc/arc_exc_asm.S b/bsp/synopsys/embarc/arc/arc_exc_asm.S new file mode 100644 index 0000000000..7410db3154 --- /dev/null +++ b/bsp/synopsys/embarc/arc/arc_exc_asm.S @@ -0,0 +1,201 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief assembly part of exception and interrupt processing + */ + +/** + * \addtogroup ARC_HAL_EXCEPTION_CPU + * @{ + */ + +/* function documentation */ +/** + * \fn void exc_entry_cpu(void) + * \brief default entry of CPU exceptions, such as TLB miss and swap. + * + * \fn void exc_entry_int(void) + * \brief normal interrupt exception entry. + * In default, all interrupt exceptions are installed with normal entry. + * If FIRQ is required, exc_entry_firq should be the entry. + * + * \fn void exc_entry_firq(void) + * \brief firq exception entry + */ +/** }@ */ + +/** @cond EXCEPTION_ASM */ + +#define __ASSEMBLY__ +#include "inc/arc/arc.h" +#include "inc/arc/arc_asm_common.h" + + .file "arc_exc_asm.S" + +/* entry for cpu exception handling */ + .text + .global exc_entry_cpu + .weak exc_entry_cpu + .align 4 +exc_entry_cpu: + + EXCEPTION_PROLOGUE + + mov r3, sp /* as exception handler's para(exc_frame) */ + +/* exc_nest_count +1 */ + ld r0, [exc_nest_count] + add r0, r0, 1 + st r0, [exc_nest_count] + +/* find the exception cause */ + lr r0, [AUX_ECR] + lsr r0, r0, 16 + bmsk r0, r0, 7 + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] + + mov r0, r3 + jl [r2] /* jump to exception handler where interrupts are not allowed! */ + +/* interrupts are not allowed */ +exc_return: + +/* exc_nest_count -1 */ + ld r0, [exc_nest_count] + sub r0, r0, 1 + st r0, [exc_nest_count] + + EXCEPTION_EPILOGUE + rtie + + +/****** entry for normal interrupt exception handling ******/ + .global exc_entry_int + .weak exc_entry_int + .align 4 +exc_entry_int: + clri /* disable interrupt */ + +#if ARC_FEATURE_FIRQ == 1 +#if ARC_FEATURE_RGF_NUM_BANKS > 1 + lr r0, [AUX_IRQ_ACT] /* check whether it is P0 interrupt */ + btst r0, 0 + bnz exc_entry_firq +#else + PUSH r10 + lr r10, [AUX_IRQ_ACT] + btst r10, 0 + POP r10 + bnz exc_entry_firq +#endif +#endif + INTERRUPT_PROLOGUE /* save scratch regs, this will be affected */ + + +/* exc_nest_count +1 */ + ld r0, [exc_nest_count] + add r0, r0, 1 + st r0, [exc_nest_count] + + + lr r0, [AUX_IRQ_CAUSE] + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ + +/* for the case of software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d irq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +irq_hint_handled: + seti /* enable higher priority interrupt */ + + mov r0, sp + jl [r2] /* jump to interrupt handler */ + +/* no interrupts are allowed from here */ +int_return: + clri /* disable interrupt */ + +/* exc_nest_count -1 */ + ld r0, [exc_nest_count] + sub r0, r0, 1 + st r0, [exc_nest_count] + + INTERRUPT_EPILOGUE + rtie + +/****** entry for fast irq exception handling ******/ + .global exc_entry_firq + .weak exc_entry_firq + .align 4 +exc_entry_firq: + clri /* disable interrupt */ + SAVE_FIQ_EXC_REGS + +/* exc_nest_count +1 */ + ld r0, [exc_nest_count] + add r0, r0, 1 + st r0, [exc_nest_count] + + lr r0, [AUX_IRQ_CAUSE] + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ + +/* for the case of software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d firq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +firq_hint_handled: + + jl [r2] /* jump to interrupt handler */ + +/* no interrupts are allowed from here */ +firq_return: + +/* exc_nest_count -1 */ + ld r0, [exc_nest_count] + sub r0, r0, 1 + st r0, [exc_nest_count] + + RESTORE_FIQ_EXC_REGS + rtie + +/** @endcond */ diff --git a/bsp/synopsys/embarc/arc/arc_exception.c b/bsp/synopsys/embarc/arc/arc_exception.c new file mode 100644 index 0000000000..a256b0b394 --- /dev/null +++ b/bsp/synopsys/embarc/arc/arc_exception.c @@ -0,0 +1,501 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT + * \brief C Implementation of exception and interrupt management + */ +#include "inc/arc/arc_exception.h" +#include "inc/arc/arc_cache.h" + +//#define DBG_LESS +//#include "embARC_debug.h" + +/** + * \addtogroup ARC_HAL_EXCEPTION_CPU + * @{ + * \var exc_entry_table + * \brief exception entry table + * + * install exception entry table to ARC_AUX_INT_VECT_BASE in startup. + * According to ARCv2 ISA, vectors are fetched in instruction space and thus + * may be present in ICCM, Instruction Cache, or + * main memory accessed by instruction fetch logic. + * So it is put into a specific section .vector. + * + * Please note that the exc_entry_table maybe cached in ARC. Some functions is + * defined in .s files. + * + */ + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief default cpu exception handler + * \param p_excinf pointer to the exception frame + */ +static void exc_handler_default(void *p_excinf) +{ + // uint32_t excpt_cause_reg = 0; + // uint32_t excpt_ret_reg = 0; + // uint32_t exc_no = 0; + + // excpt_cause_reg = _arc_aux_read(AUX_ECR); + // excpt_ret_reg = _arc_aux_read(AUX_ERRET); + // exc_no = (excpt_cause_reg >> 16) & 0xff; + + Asm("kflag 1"); +} + + +/** + * \ingroup ARC_HAL_EXCEPTION_INTERRUPT + * \brief default interrupt handler + * \param[in] p_excinf information for interrupt handler + */ +static void int_handler_default(void *p_excinf) +{ + // uint32_t int_cause_reg = 0; + + // int_cause_reg = _arc_aux_read(AUX_IRQ_CAUSE); + Asm("kflag 1"); +} + +__attribute__ ((aligned(1024), section(".vector"))) +EXC_ENTRY exc_entry_table[NUM_EXC_ALL] = { + [0] = _arc_reset, + [1 ... NUM_EXC_CPU-1] = exc_entry_cpu, + [NUM_EXC_CPU ... NUM_EXC_ALL-1] = exc_entry_int + }; +/** + * \var exc_int_handler_table + * \brief the cpu exception and interrupt exception handler table + * called in exc_entry_default and exc_entry_int + */ +EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL] = { + [0 ... NUM_EXC_CPU-1] = exc_handler_default, + [NUM_EXC_CPU ... NUM_EXC_ALL-1] = int_handler_default +}; + +/** + * \var exc_nest_count + * \brief the counter for exc/int processing, =0 no int/exc + * >1 in int/exc processing + * @} + */ +uint32_t exc_nest_count; + +typedef struct aux_irq_ctrl_field { + /* note: little endian */ + uint32_t save_nr_gpr_pairs: 5; /** Indicates number of general-purpose register pairs saved, from 0 to 8/16 */ + uint32_t res: 4; /** Reserved */ + uint32_t save_blink: 1; /** Indicates whether to save and restore BLINK */ + uint32_t save_lp_regs: 1; /** Indicates whether to save and restore loop registers (LP_COUNT, LP_START, LP_END) */ + uint32_t save_u_to_u: 1; /** Indicates if user context is saved to user stack */ + uint32_t res2: 1; /** Reserved */ + uint32_t save_idx_regs: 1; /** Indicates whether to save and restore code-density registers (EI_BASE, JLI_BASE, LDI_BASE) */ + uint32_t res3: 18; /** Reserved */ +} aux_irq_ctrl_field_t; + +typedef union { + aux_irq_ctrl_field_t bits; + uint32_t value; +} aux_irq_ctrl_t; + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT + * \brief intialize the exception and interrupt handling + */ +void exc_int_init(void) +{ + uint32_t i; + uint32_t status; + aux_irq_ctrl_t ictrl; + + ictrl.value = 0; + +#ifndef ARC_FEATURE_RF16 + ictrl.bits.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */ +#else + ictrl.bits.save_nr_gpr_pairs = 3; /* r0 to r3, r10, r11 */ +#endif + ictrl.bits.save_blink = 1; + ictrl.bits.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */ + ictrl.bits.save_u_to_u = 0; /* user ctxt saved on kernel stack */ + ictrl.bits.save_idx_regs = 1; /* JLI, LDI, EI */ + + status = arc_lock_save(); + for (i = NUM_EXC_CPU; i < NUM_EXC_ALL; i++) { + /* interrupt level triggered, disabled, priority is the lowest */ + _arc_aux_write(AUX_IRQ_SELECT, i); + _arc_aux_write(AUX_IRQ_ENABLE, 0); + _arc_aux_write(AUX_IRQ_TRIGGER, 0); +#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2) + _arc_aux_write(AUX_IRQ_PRIORITY, (1 << AUX_IRQ_PRIORITY_BIT_S)|(INT_PRI_MAX - INT_PRI_MIN)); +#else + _arc_aux_write(AUX_IRQ_PRIORITY, INT_PRI_MAX - INT_PRI_MIN); +#endif + } + _arc_aux_write(AUX_IRQ_CTRL, ictrl.value); + + arc_unlock_restore(status); + + /** ipm should be set after cpu unlock restore to avoid reset of the status32 value */ + arc_int_ipm_set((INT_PRI_MAX - INT_PRI_MIN)); +} + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief install a CPU exception entry + * \param[in] excno exception number + * \param[in] entry the entry of exception to install + */ +int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry) +{ + uint32_t status; + + EXC_ENTRY *table = (EXC_ENTRY *)_arc_aux_read(AUX_INT_VECT_BASE); + + if (excno < NUM_EXC_ALL && entry != NULL + && table[excno] != entry) { + status = cpu_lock_save(); + /* directly write to mem, as arc gets exception handler from mem not from cache */ + /* FIXME, here maybe icache is dirty, need to be invalidated */ + table[excno] = entry; + + if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) { + /* dcache is available */ + dcache_flush_line((uint32_t)&table[excno]); + } + + if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) { + /* icache is available */ + icache_invalidate_line((uint32_t)&table[excno]); + } + cpu_unlock_restore(status); + return 0; + } + return -1; +} + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief get the installed CPU exception entry + * \param[in] excno exception number + * \return the installed CPU exception entry + */ +EXC_ENTRY exc_entry_get(const uint32_t excno) +{ + if (excno < NUM_EXC_ALL) { + return exc_entry_table[excno]; + } + return NULL; +} + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief install an exception handler + * \param[in] excno exception number + * \param[in] handler the handler of exception to install + */ +int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler) +{ + if (excno < NUM_EXC_ALL && handler != NULL) { + exc_int_handler_table[excno] = handler; + return 0; + } + + return -1; +} + +/** + * \ingroup ARC_HAL_EXCEPTION_CPU + * \brief get the installed exception handler + * \param[in] excno exception number + * \return the installed exception handler or NULL + */ +EXC_HANDLER exc_handler_get(const uint32_t excno) +{ + if (excno < NUM_EXC_ALL) { + return exc_int_handler_table[excno]; + } + + return NULL; +} + + +#ifndef EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT +/** + * \brief disable the specific interrupt + * + * \param[in] intno interrupt number + */ +int32_t int_disable(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + arc_int_disable(intno); + return 0; + } + + return -1; +} + +/** + * \brief enable the specific int + * + * \param[in] intno interrupt number + */ +int32_t int_enable(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + arc_int_enable(intno); + return 0; + } + + return -1; +} + +/** + * \brief check whether the specific int is enabled + * + * \param[in] intno interrupt number + * \return 0 disabled, 1 enabled, < 0 error + */ +int32_t int_enabled(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + _arc_aux_write(AUX_IRQ_SELECT, intno); + return _arc_aux_read(AUX_IRQ_ENABLE); + } + + return -1; +} + +/** + * \brief get the interrupt priority mask + * + * \returns interrupt priority mask, negative num + */ +int32_t int_ipm_get(void) +{ + return ((int32_t)arc_int_ipm_get() + INT_PRI_MIN); +} + + +/** + * \brief set the interrupt priority mask + * + * \param[in] intpri interrupt priority + */ +int32_t int_ipm_set(int32_t intpri) +{ + if (intpri >= INT_PRI_MIN && intpri <= INT_PRI_MAX) { + intpri = intpri - INT_PRI_MIN; + arc_int_ipm_set(intpri); + return 0; + } + + return -1; +} + + +/** + * \brief get current interrupt priority mask + * + * \param[in] intno interrupt number + * \return <0 interrupt priority, 0 error + */ +int32_t int_pri_get(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + return (int32_t)arc_int_pri_get(intno) + INT_PRI_MIN; + } + + return 0; +} + + +/** + * \brief set interrupt priority + * + * \param[in] intno interrupt number + * \param[in] intpri interrupt priority + * \return <0 error, 0 ok + */ +int32_t int_pri_set(const uint32_t intno, int32_t intpri) +{ + uint32_t status; + + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + status = cpu_lock_save(); + intpri = intpri - INT_PRI_MIN; + arc_int_pri_set(intno,(uint32_t)intpri); + cpu_unlock_restore(status); + return 0; + } + return -1; +} + +/** + * \brief set interrupt secure or not secure + * This function is valid in secureshield v2 + * \param[in] intno interrupt number + * \param[in] secure, 0 for normal, >0 for secure + * \return <0 error, 0 ok + */ +int32_t int_secure_set(const uint32_t intno, uint32_t secure) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + arc_int_secure_set(intno, secure); + return 0; + } + return -1; + +} + + +/** + * \brief probe the pending status of interrupt + * + * \param[in] intno interrupt number + * + * \returns 1 pending, 0 no pending, -1 error + */ +int32_t int_probe(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + return arc_int_probe(intno); + } + return -1; +} + + +/** + * \brief trigger the interrupt in software + * + * \param[in] intno interrupt number + * \return 0 ok, -1 error + */ +int32_t int_sw_trigger(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + arc_int_sw_trigger(intno); + return 0; + } + return -1; +} + +/** + * \brief config the interrupt level triggered or pulse triggered + * + * \param[in] intno interrupt number + * \param[in] level, 0-level trigger, 1-pulse triggered + * \return 0 ok, -1 error + */ +int32_t int_level_config(const uint32_t intno, const uint32_t level) +{ + if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { + arc_int_level_config(intno, level); + return 0; + } + return -1; +} + + +/** + * \brief lock cpu, disable interrupts + */ +void cpu_lock(void) +{ + arc_lock(); +} + +/** + * \brief unlock cpu, enable interrupts to happen + */ +void cpu_unlock(void) +{ + arc_unlock(); +} + +/** + * \brief lock cpu and return status + * + * \returns cpu status + */ +uint32_t cpu_lock_save(void) +{ + return arc_lock_save(); +} + +/** + * \brief unlock cpu with the specific status + * + * \param[in] status cpu status saved by cpu_lock_save + */ +void cpu_unlock_restore(const uint32_t status) +{ + arc_unlock_restore(status); +} + +/** + * \ingroup ARC_HAL_EXCEPTION_INTERRUPT + * \brief install an interrupt handler + * \param[in] intno interrupt number + * \param[in] handler interrupt handler to install + */ +int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler) +{ + /*!< \todo parameter check ? */ + if (intno >= NUM_EXC_CPU) { + return exc_handler_install(intno, handler); + } + + return -1; +} + +/** + * \ingroup ARC_HAL_EXCEPTION_INTERRUPT + * \brief get the installed an interrupt handler + * \param[in] intno interrupt number + * \return the installed interrupt handler or NULL + */ +INT_HANDLER int_handler_get(const uint32_t intno) +{ + if (intno >= NUM_EXC_CPU) { + return exc_handler_get(intno); + } + + return NULL; +} +#endif /* EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT */ diff --git a/bsp/synopsys/embarc/arc/arc_timer.c b/bsp/synopsys/embarc/arc/arc_timer.c new file mode 100644 index 0000000000..3d0c4b4f83 --- /dev/null +++ b/bsp/synopsys/embarc/arc/arc_timer.c @@ -0,0 +1,211 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_MISC_TIMER + * \brief implementation of internal timer related functions + * \todo RTC support should be improved if RTC is enabled + */ +#include "inc/arc/arc_timer.h" +#include "inc/arc/arc.h" +#include "inc/arc/arc_builtin.h" + +/** + * \brief check whether the specific timer present + * \param[in] no timer number + * \retval 1 present + * \retval 0 not present + */ +int32_t arc_timer_present(const uint32_t no) +{ + uint32_t bcr = _arc_aux_read(AUX_BCR_TIMERS); + switch (no) { + case TIMER_0: + bcr = (bcr >> 8) & 1; + break; + case TIMER_1: + bcr = (bcr >> 9) & 1; + break; + case TIMER_RTC: + bcr = (bcr >> 10) & 1; + break; + default: + bcr = 0; + /* illegal argument so return false */ + break; + } + + return (int)bcr; +} + +/** + * \brief start the specific timer + * \param[in] no timer number + * \param[in] mode timer mode + * \param[in] val timer limit value (not for RTC) + * \return 0 success, -1 failure + */ +int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val) +{ + if (arc_timer_present(no) == 0) { + return -1; + } + + switch (no) { + case TIMER_0: + _arc_aux_write(AUX_TIMER0_CTRL, 0); + _arc_aux_write(AUX_TIMER0_LIMIT, val); + _arc_aux_write(AUX_TIMER0_CTRL, mode); + _arc_aux_write(AUX_TIMER0_CNT, 0); + break; + case TIMER_1: + _arc_aux_write(AUX_TIMER1_CTRL, 0); + _arc_aux_write(AUX_TIMER1_LIMIT, val); + _arc_aux_write(AUX_TIMER1_CTRL, mode); + _arc_aux_write(AUX_TIMER1_CNT, 0); + break; + case TIMER_RTC: + _arc_aux_write(AUX_RTC_CTRL, mode); + break; + default: + return -1; + } + + return 0; +} + +/** + * \brief stop and clear the specific timer + * + * \param[in] no timer number + * \return 0 success, -1 failure + */ +int32_t arc_timer_stop(const uint32_t no) +{ + if (arc_timer_present(no) == 0) { + return -1; + } + + switch (no) { + case TIMER_0 : + _arc_aux_write(AUX_TIMER0_CTRL, 0); + _arc_aux_write(AUX_TIMER0_LIMIT,0); + _arc_aux_write(AUX_TIMER0_CNT, 0); + break; + case TIMER_1: + _arc_aux_write(AUX_TIMER1_CTRL, 0); + _arc_aux_write(AUX_TIMER1_LIMIT,0); + _arc_aux_write(AUX_TIMER1_CNT, 0); + break; + case TIMER_RTC: + _arc_aux_write(AUX_RTC_CTRL, TIMER_RTC_CLEAR); + break; + default: + return -1; + } + + return 0; +} + +/** + * \brief get timer current tick + * + * \param[in] no timer number + * \param[out] val, timer value + * \return 0 success, -1 failure + */ +int32_t arc_timer_current(const uint32_t no, void *val) +{ + if (arc_timer_present(no) == 0) { + return -1; + } + + switch (no) { + case TIMER_0 : + *((uint32_t *)val) = _arc_aux_read(AUX_TIMER0_CNT); + break; + case TIMER_1 : + *((uint32_t *)val) = _arc_aux_read(AUX_TIMER1_CNT); + break; + case TIMER_RTC: + *((uint64_t *)val) = _arc_aux_read(AUX_RTC_LOW); + break; + default : + return -1; + } + + return 0; +} + +/** + * \brief clear the interrupt pending bit of timer + * + * \param[in] no timer number + * \return 0 success, -1 failure + */ +int32_t arc_timer_int_clear(const uint32_t no) +{ + uint32_t val; + + if (arc_timer_present(no) == 0) { + return -1; + } + + switch (no) { + case TIMER_0 : + val = _arc_aux_read(AUX_TIMER0_CTRL); + val &= ~TIMER_CTRL_IP; + _arc_aux_write(AUX_TIMER0_CTRL, val); + break; + case TIMER_1 : + val = _arc_aux_read(AUX_TIMER1_CTRL); + val &= ~TIMER_CTRL_IP; + _arc_aux_write(AUX_TIMER1_CTRL, val); + break; + default : + return -1; + } + + return 0; +} + +/** + * \brief init internal timer + */ +void arc_timer_init(void) +{ + arc_timer_stop(TIMER_0); + arc_timer_stop(TIMER_1); + arc_timer_stop(TIMER_RTC); +} diff --git a/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c b/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c new file mode 100644 index 0000000000..af842fddc6 --- /dev/null +++ b/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014 Wind River Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ------------------------------------------ + * Copyright (c) 2015, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2016-03-02 + * \author Wayne Ren(wei.ren@synopsys.com) +--------------------------------------------- */ +#include "embARC_BSP_config.h" +#if defined(__GNU__) +/* embARC's GNU C++ support takes reference from Zephyr (cpp_xxx.c) */ + +/** + * @file - Constructor module + * @brief + * The ctors section contains a list of function pointers that execute the + * C++ constructors of static global objects. These must be executed before + * the application's main() routine. + * + * NOTE: Not all compilers put those function pointers into the ctors section; + * some put them into the init_array section instead. + */ + +/* What a constructor function pointer looks like */ + +typedef void (*CtorFuncPtr)(void); + +/* Constructor function pointer list is generated by the linker script. */ + +extern CtorFuncPtr __CTOR_LIST__[]; +extern CtorFuncPtr __CTOR_END__[]; + +/** + * + * @brief Invoke all C++ style global object constructors + * + * This routine is invoked before the execution of the + * application's main(). + */ +void __do_global_ctors_aux(void) +{ + unsigned int nCtors; + + nCtors = (unsigned int)__CTOR_LIST__[0]; + + while (nCtors >= 1) { + __CTOR_LIST__[nCtors--](); + } +} + +typedef void (*DtorFuncPtr)(void); + +extern DtorFuncPtr __DTOR_LIST__[]; +extern DtorFuncPtr __DTOR_END__[]; + +/** + * + * @brief Invoke all C++ style global object destructors + * + * This routine is invoked after the execution of the + * application's main(). + */ +void __do_global_dtors_aux(void) +{ + unsigned int nDtors; + unsigned int i; + + nDtors = (unsigned int)__DTOR_LIST__[0]; + i = 0; + + while (i <= nDtors) { + __DTOR_LIST__[i++](); + } +} + +void *__dso_handle = 0; + +/** + * @brief Register destructor for a global object + * + * @param destructor the global object destructor function + * @param objptr global object pointer + * @param dso Dynamic Shared Object handle for shared libraries + * + * Function does nothing at the moment, assuming the global objects + * do not need to be deleted + * + * @return N/A + */ +int __cxa_atexit(void (*destructor)(void *), void *objptr, void *dso) +{ + return 0; +} + +typedef void (*func_ptr)(void); + +extern func_ptr __init_array_start[0]; +extern func_ptr __init_array_end[0]; + +/** + * @brief Execute initialization routines referenced in .init_array section + * + * @return N/A + */ +void __do_init_array_aux(void) +{ + for (func_ptr *func = __init_array_start; + func < __init_array_end; + func++) { + (*func)(); + } +} + +/** + * @brief Stub for pure virtual functions + * + * This routine is needed for linking C++ code that uses pure virtual + * functions. + * + * @return N/A + */ +void __cxa_pure_virtual(void) +{ + while (1) { + ; + } +} +#endif diff --git a/bsp/synopsys/embarc/arc/startup/arc_startup.S b/bsp/synopsys/embarc/arc/startup/arc_startup.S new file mode 100644 index 0000000000..26a6fdb519 --- /dev/null +++ b/bsp/synopsys/embarc/arc/startup/arc_startup.S @@ -0,0 +1,262 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_STARTUP + * \brief assembly part of startup process + */ + +/** + * \addtogroup ARC_HAL_STARTUP + * @{ + */ +/** @cond STARTUP_ASM */ + +#define __ASSEMBLY__ +#include "embARC_BSP_config.h" +#include "inc/arc/arc.h" + + .file "arc_startup.S" + +.weak _f_sdata /* start of small data, defined in link script */ +.weak init_hardware_hook /* app hardware init hook */ +.weak init_software_hook /* app software init hook */ + +.extern board_main +.extern exc_entry_table + +/* initial vector table */ + .section .init_vector, "a" + .long _arc_reset + .section .init_bootstrap, "ax" + .global _arc_reset + .global _start + .align 4 +_start: +_arc_reset: +_arc_reset_stage1: + kflag STATUS32_RESET_VALUE + +/* STAGE 1 */ + +/* necessary hardware should be done first to speed up initialization + 1. system clk + 2. mem controller must be initialized before any access to external + mem. + 3. others +*/ +_arc_cache_init_start: + lr r0, [AUX_BCR_D_CACHE] + cmp r0, 2 + /* invalidate dcache */ + jle _arc_icache_init + mov r0, 1 + sr r0, [AUX_DC_IVDC] + sr r0, [AUX_DC_CTRL] +_arc_icache_init: + lr r0, [AUX_BCR_I_CACHE] + cmp r0, 2 + jle _arc_cache_init_end + /* invalidate icache */ + mov r0, 1 + sr r0, [AUX_IC_IVIC] + nop_s + nop_s + nop_s + sr r0, [AUX_IC_CTRL] + +_arc_cache_init_end: + mov r0, init_hardware_hook + cmp r0, 0 + jlne [r0] + +/* STAGE 2: init necessary registers */ + +_arc_reset_stage2: + mov r0, 0 + +/* interrupt related init */ + sr r0, [AUX_IRQ_ACT] + sr r0, [AUX_IRQ_CTRL] + sr r0, [AUX_IRQ_HINT] + +/* use the new vector table to replace the old one */ +#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2) + sr exc_entry_table, [AUX_INT_VECT_BASE_S] +#else + sr exc_entry_table, [AUX_INT_VECT_BASE] +#endif + +/* init stack */ +#if ARC_FEATURE_RGF_BANKED_REGS >= 16 && ARC_FEATURE_RGF_BANKED_REGS > 1 && ARC_FEATURE_FIRQ == 1 +#if _STACKSIZE < 512 +#error "not enough stack size for irq and firq" +#endif + +/* switch to register bank1 */ + lr r0, [AUX_STATUS32] + bic r0, r0, 0x70000 + or r0, r0, 0x10000 + kflag r0 +/* set sp, gp, fp in bank1 */ + mov sp, _e_stack + mov gp, _f_sdata + mov fp, 0 +/* come back to bank0 */ + lr r0, [AUX_STATUS32] + bic r0, r0, 0x70000 + kflag r0 + mov sp, _e_stack-256 +#else + mov sp, _e_stack /* init stack pointer */ +#endif + mov gp, _f_sdata /* init small-data base register */ + mov fp, 0 /* init fp register */ + +_arc_reset_stage3: +_s3_copy_text: + mov r0, _f_text + mov r1, _load_addr_text + cmp r0, r1 + +/* if load addr == run addr, no need to copy */ + jeq _s3_copy_rodata + mov r3, _e_text +_s3_copy_text_loop: + ld.ab r2, [r1, 4] + st.ab r2, [r0, 4] + cmp r0, r3 + jlt _s3_copy_text_loop +_s3_copy_rodata: + mov r0, _f_rodata + mov r1, _load_addr_rodata + cmp r0, r1 + +/* if load addr == run addr, no need to copy */ + jeq _s3_copy_data + mov r3, _e_rodata +_s3_copy_rodata_loop: + ld.ab r2, [r1, 4] + st.ab r2, [r0, 4] + cmp r0, r3 + jlt _s3_copy_rodata_loop +_s3_copy_data: + mov r0, _f_data + mov r1, _load_addr_data + cmp r0, r1 + jeq _s3_clear_bss + +/* if load addr == run addr, no need to copy */ + mov r3, _e_data +_s3_copy_data_loop: + ld.ab r2, [r1, 4] + st.ab r2, [r0, 4] + cmp r0, r3 + jlt _s3_copy_data_loop +_s3_clear_bss: + mov r0, _f_bss + mov r1, _e_bss + cmp r0, r1 + jge _arc_reset_call_main + mov r2, 0 +_s3_clear_bss_loop: + st.ab r2, [r0, 4] + cmp r0, r1 + jlt _s3_clear_bss_loop + +/* STAGE 3: go to main */ + +_arc_reset_call_main: + +/* \todo add cpp init here */ + mov r0, init_software_hook + cmp r0, 0 + jlne [r0] +/* board level library init */ +/* early init of interrupt and exception */ + jl exc_int_init +/* init cache */ + jl arc_cache_init +#if defined(__MW__) + jl _init +#elif defined(__GNU__) + jl __do_global_ctors_aux + jl __do_init_array_aux +#endif + jl board_main /* board-level main */ +#if defined(__MW__) + jl _fini +#elif defined(__GNU__) + jl __do_global_dtors_aux +#endif + .global _exit_loop + .global _exit_halt + .align 4 +_exit_halt: +_exit_loop: + flag 0x1 + nop + nop + nop + b _exit_loop + +#if defined(__MW__) + .global _init, _fini + .section ".init",text +_init: + .cfa_bf _init + push %blink + .cfa_push {%blink} + + .section ".init$999999", text, 1, 2, check_text_align=0 + pop %blink + .cfa_pop {%blink} + j [%blink] + .cfa_ef + + .section ".fini", text +_fini: + .cfa_bf _fini + push %blink + .cfa_push {%blink} + + .section ".fini$999999", text, 1, 2, check_text_align=0 + pop %blink + .cfa_pop {%blink} + j [%blink] + .cfa_ef +#endif +/** @endcond */ + +/** }@*/ diff --git a/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c b/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c new file mode 100644 index 0000000000..ce79414fc6 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c @@ -0,0 +1,481 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-22 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_DW_GPIO Designware GPIO Driver + * \ingroup DEVICE_DW + * \brief Designware GPIO Driver Implementation + */ + +/** + * \file + * \brief designware gpio driver + * \ingroup DEVICE_DW_GPIO + * \brief Designware GPIO driver + */ +#include "inc/embARC_toolchain.h" +#include "inc/embARC_error.h" +#include "inc/arc/arc_exception.h" + +#include "device/designware/gpio/dw_gpio.h" + +/** check expressions used in DesignWare GPIO driver implementation */ +#define DW_GPIO_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) + +#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK +/** valid check of uart info object */ +#define VALID_CHK_GPIO_INFO_OBJECT(gpioinfo_obj_ptr) { \ + DW_GPIO_CHECK_EXP((gpioinfo_obj_ptr)!=NULL, E_OBJ); \ + DW_GPIO_CHECK_EXP(((gpioinfo_obj_ptr)->gpio_ctrl)!=NULL, E_OBJ); \ + } +#endif + +/** + * \defgroup DEVICE_DW_GPIO_STATIC DesignWare GPIO Driver Static Functions + * \ingroup DEVICE_DW_GPIO + * \brief Static or inline functions, variables for DesignWare GPIO handle gpio operations, + * only used in this file + * @{ + */ +Inline uint32_t dw_gpio_read_ext(DW_GPIO_PORT_PTR port) +{ + return port->regs->EXT_PORTS[port->no]; +} + +Inline uint32_t dw_gpio_read_dir(DW_GPIO_PORT_PTR port) +{ + return port->regs->SWPORTS[port->no].DDR; +} + +Inline uint32_t dw_gpio_read_dr(DW_GPIO_PORT_PTR port) +{ + return port->regs->SWPORTS[port->no].DR; +} + +Inline uint32_t dw_gpio_read_mthd(DW_GPIO_PORT_PTR port) +{ + return port->regs->INTEN; +} + +Inline void dw_gpio_int_enable(DW_GPIO_PORT_PTR port, uint32_t bit_mask) +{ + port->regs->INTEN |= bit_mask; +} + +Inline void dw_gpio_int_disable(DW_GPIO_PORT_PTR port, uint32_t bit_mask) +{ + port->regs->INTEN &= (~bit_mask); +} + +Inline void dw_gpio_int_mask(DW_GPIO_PORT_PTR port, uint32_t bit_mask) +{ + port->regs->INTMASK |= bit_mask; +} + +Inline void dw_gpio_int_unmask(DW_GPIO_PORT_PTR port, uint32_t bit_mask) +{ + port->regs->INTMASK &= (~bit_mask); +} + +Inline uint32_t dw_gpio_int_read_level(DW_GPIO_PORT_PTR port) +{ + return port->regs->INTTYPE_LEVEL; +} + +Inline uint32_t dw_gpio_int_read_polarity(DW_GPIO_PORT_PTR port) +{ + return port->regs->INT_POLARITY; +} + +Inline uint32_t dw_gpio_int_read_debounce(DW_GPIO_PORT_PTR port) +{ + return port->regs->DEBOUNCE; +} + +Inline uint32_t dw_gpio_int_read_status(DW_GPIO_PORT_PTR port) +{ + return port->regs->INTSTATUS; +} + +Inline void dw_gpio_int_clear(DW_GPIO_PORT_PTR port, uint32_t bit_mask) +{ + port->regs->PORTA_EOI = bit_mask; +} + +static void dw_gpio_int_write_level(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_level) +{ + uint32_t reg_val; + + reg_val = port->regs->INTTYPE_LEVEL; + reg_val &= (~bit_mask); + bit_level &= bit_mask; + reg_val |= bit_level; + + port->regs->INTTYPE_LEVEL = reg_val; +} + +static void dw_gpio_int_write_polarity(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_polarity) +{ + uint32_t reg_val; + + reg_val = port->regs->INT_POLARITY; + + reg_val &= (~bit_mask); + bit_polarity &= bit_mask; + reg_val |= bit_polarity; + + port->regs->INT_POLARITY = reg_val; +} + +static void dw_gpio_int_write_debounce(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_debounce) +{ + uint32_t reg_val; + + reg_val = port->regs->DEBOUNCE; + + reg_val &= (~bit_mask); + bit_debounce &= bit_mask; + reg_val |= bit_debounce; + + port->regs->DEBOUNCE = reg_val; +} + +static void dw_gpio_set_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg) +{ + dw_gpio_int_write_level(port, int_cfg->int_bit_mask, int_cfg->int_bit_type); + dw_gpio_int_write_polarity(port, int_cfg->int_bit_mask, int_cfg->int_bit_polarity); + dw_gpio_int_write_debounce(port, int_cfg->int_bit_mask, int_cfg->int_bit_debounce); +} + +static void dw_gpio_get_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg) +{ + int_cfg->int_bit_type = dw_gpio_int_read_level(port) & int_cfg->int_bit_mask; + int_cfg->int_bit_polarity = dw_gpio_int_read_polarity(port) & int_cfg->int_bit_mask; + int_cfg->int_bit_debounce = dw_gpio_int_read_debounce(port) & int_cfg->int_bit_mask; +} + +static void dw_gpio_write_dr(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val) +{ + uint32_t temp_reg; + + temp_reg = port->regs->SWPORTS[port->no].DR; + temp_reg &= ~bit_mask; + val &= bit_mask; + temp_reg |= val; + + port->regs->SWPORTS[port->no].DR = temp_reg; +} + +static void dw_gpio_write_dir(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val) +{ + uint32_t temp_reg; + + temp_reg = port->regs->SWPORTS[port->no].DDR; + temp_reg &= ~bit_mask; + val &= bit_mask; + temp_reg |= val; + + port->regs->SWPORTS[port->no].DDR = temp_reg; +} + +static uint32_t dw_gpio_read_val(DW_GPIO_PORT_PTR port) +{ + uint32_t val; + + val = dw_gpio_read_ext(port) & (~dw_gpio_read_dir(port)); + val |= dw_gpio_read_dr(port) & dw_gpio_read_dir(port); + + return val; +} + +/** @} end of group DEVICE_DW_GPIO_STATIC */ + +/* interface for DEV_GPIO */ +/** Open designware gpio device with specified io direction configuration */ +int32_t dw_gpio_open(DEV_GPIO *gpio_obj, uint32_t dir) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); + + port_info_ptr->opn_cnt ++; + if (port_info_ptr->opn_cnt > 1) { /* opened before */ + if (dir == port_info_ptr->direction) { /* direction is the same */ + return E_OK; + } else { /* open with different direction */ + return E_OPNED; + } + } + + dw_gpio_write_dir(port, port->valid_bit_mask, dir); + + if (port->no == DW_GPIO_PORT_A) { + dw_gpio_int_clear(port, DW_GPIO_MASK_ALL); + dw_gpio_int_disable(port, DW_GPIO_MASK_ALL); + dw_gpio_int_unmask(port, DW_GPIO_MASK_ALL); + /* install gpio interrupt handler */ + int_handler_install(port->intno, port->int_handler); + int_disable(port->intno); + /** Set int type, int polarity and debounce configuration to default settings of device gpio */ + dw_gpio_set_int_cfg(port, (DEV_GPIO_INT_CFG *)(&gpio_int_cfg_default)); + port_info_ptr->method = dw_gpio_read_mthd(port); + } else { + port_info_ptr->method = DEV_GPIO_BITS_MTHD_DEFAULT; + } + + dw_gpio_write_dr(port, port->valid_bit_mask, 0); + + port_info_ptr->direction = dir; + port_info_ptr->extra = NULL; + +error_exit: + return ercd; +} + +/** Close designware gpio device */ +int32_t dw_gpio_close(DEV_GPIO *gpio_obj) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); + + DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_OK); + + port_info_ptr->opn_cnt --; + if (port_info_ptr->opn_cnt == 0) { + dw_gpio_write_dr(port, port->valid_bit_mask, 0); + dw_gpio_write_dir(port, port->valid_bit_mask, 0); + if (port->no == DW_GPIO_PORT_A) { + dw_gpio_int_clear(port, DW_GPIO_MASK_ALL); + dw_gpio_int_disable(port, DW_GPIO_MASK_ALL); + int_disable(port->intno); + } + + port_info_ptr->direction = 0; + port_info_ptr->method = 0; + port_info_ptr->extra = NULL; + } else { + ercd = E_OPNED; + } + +error_exit: + return ercd; +} + +/** Read designware gpio device value */ +int32_t dw_gpio_read(DEV_GPIO *gpio_obj, uint32_t *val, uint32_t mask) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); + DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); + + DW_GPIO_CHECK_EXP(val!=NULL, E_PAR); + + //*val = dw_gpio_read_ext(port) & mask; + *val = dw_gpio_read_val(port) & mask; + +error_exit: + return ercd; +} + +/** Write designware gpio device value */ +int32_t dw_gpio_write(DEV_GPIO *gpio_obj, uint32_t val, uint32_t mask) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); + DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); + + dw_gpio_write_dr(port, mask, val); + +error_exit: + return ercd; +} + +/** Control designware gpio device */ +int32_t dw_gpio_control(DEV_GPIO *gpio_obj, uint32_t ctrl_cmd, void *param) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); + DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); + + uint32_t val32; /** to receive unsigned int value */ + + if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_INPUT) { + val32 = (uint32_t)param; + dw_gpio_write_dir(port, val32, DW_GPIO_INPUT_ALL); + port_info_ptr->direction = dw_gpio_read_dir(port); + } else if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_OUTPUT) { + val32 = (uint32_t)param; + dw_gpio_write_dir(port, val32, DW_GPIO_OUTPUT_ALL); + port_info_ptr->direction = dw_gpio_read_dir(port); + } else if (ctrl_cmd == GPIO_CMD_GET_BIT_DIR) { + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + port_info_ptr->direction = dw_gpio_read_dir(port); + *((int32_t *)param) = port_info_ptr->direction; + } else { + DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT); + /* output pin cannot be used as interrupt */ + DEV_GPIO_INT_CFG *gpio_int_cfg; + DEV_GPIO_BIT_ISR *port_bit_isr; + + switch (ctrl_cmd) { + case GPIO_CMD_SET_BIT_INT_CFG: + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + gpio_int_cfg = (DEV_GPIO_INT_CFG *)param; + dw_gpio_set_int_cfg(port, gpio_int_cfg); + break; + case GPIO_CMD_GET_BIT_INT_CFG: + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + gpio_int_cfg = (DEV_GPIO_INT_CFG *)param; + /** read configuration, each bit stands for different configuration */ + dw_gpio_get_int_cfg(port, gpio_int_cfg); + break; + case GPIO_CMD_SET_BIT_ISR: + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + port_bit_isr = (DEV_GPIO_BIT_ISR *)param; + if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) { + port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs] = port_bit_isr->int_bit_handler; + } else { + ercd = E_PAR; + } + break; + case GPIO_CMD_GET_BIT_ISR: + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + port_bit_isr = (DEV_GPIO_BIT_ISR *)param; + if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) { + port_bit_isr->int_bit_handler = port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs]; + } else { + ercd = E_PAR; + } + break; + case GPIO_CMD_ENA_BIT_INT: + val32 = (uint32_t)param; + dw_gpio_int_enable(port, val32); + port_info_ptr->method = dw_gpio_read_mthd(port); + if (port_info_ptr->method) { + int_enable(port->intno); + } + break; + case GPIO_CMD_DIS_BIT_INT: + val32 = (uint32_t)param; + dw_gpio_int_disable(port, val32); + port_info_ptr->method = dw_gpio_read_mthd(port); + if (port_info_ptr->method == 0) { + int_disable(port->intno); + } + break; + case GPIO_CMD_GET_BIT_MTHD: + DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + port_info_ptr->method = dw_gpio_read_mthd(port); + *((int32_t *)param) = port_info_ptr->method; + break; + default: + ercd = E_NOSPT; + break; + } + } +error_exit: + return ercd; +} + +/** designware gpio interrupt process */ +int32_t dw_gpio_isr_handler(DEV_GPIO *gpio_obj, void *ptr) +{ + int32_t ercd = E_OK; + DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); + + /* START ERROR CHECK */ + VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); + /* END OF ERROR CHECK */ + + DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); + DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT); + + uint32_t i, gpio_bit_isr_state; + uint32_t max_int_bit_count = 0; + + /** read interrupt status */ + gpio_bit_isr_state = dw_gpio_int_read_status(port); + + if (port->gpio_bit_isr) { + max_int_bit_count = (port->gpio_bit_isr->int_bit_max_cnt); + } else { + dw_gpio_int_clear(port, gpio_bit_isr_state); + } + + for (i=0; igpio_bit_isr->int_bit_handler_ptr[i]) { + port->gpio_bit_isr->int_bit_handler_ptr[i](gpio_obj); + } + dw_gpio_int_clear(port, (1< + +#include "inc/embARC_toolchain.h" +#include "inc/embARC_error.h" + +#include "inc/arc/arc_exception.h" + +#include "device/designware/iic/dw_iic_hal.h" +#include "device/designware/iic/dw_iic.h" + +/** check expressions used in DesignWare IIC driver implementation */ +#define DW_IIC_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) + +#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK +/** valid check of iic info object */ +#define VALID_CHK_IIC_INFO_OBJECT(iicinfo_obj_ptr) { \ + DW_IIC_CHECK_EXP((iicinfo_obj_ptr)!=NULL, E_OBJ); \ + DW_IIC_CHECK_EXP(((iicinfo_obj_ptr)->iic_ctrl)!=NULL, E_OBJ); \ + } +#endif + +/** + * \name DesignWare IIC Interrupt Callback Routine Select Marcos + * \brief DesignWare IIC interrupt callback routines select macros definitions + * @{ + */ +#define DW_IIC_RDY_SND (1U) /*!< ready to send callback */ +#define DW_IIC_RDY_RCV (2U) /*!< ready to receive callback */ +/** @} */ + +/** + * \defgroup DEVICE_DW_IIC_STATIC DesignWare IIC Driver Static Functions + * \ingroup DEVICE_DW_IIC + * \brief Static or inline functions, variables for DesignWare IIC handle iic operations, + * only used in this file. + * @{ + */ +/** Disable designware iic device */ +Inline void dw_iic_disable(DW_IIC_REG *iic_reg_ptr) +{ + iic_reg_ptr->IC_ENABLE = DW_IIC_DISABLE; +} +/** Enable designware iic device */ +Inline void dw_iic_enable(DW_IIC_REG *iic_reg_ptr) +{ + iic_reg_ptr->IC_ENABLE = DW_IIC_ENABLE; +} + +/** Clear all designware iic interrupt */ +Inline void dw_iic_clear_interrupt_all(DW_IIC_REG *iic_reg_ptr) +{ + (void)iic_reg_ptr->IC_CLR_INTR; +} + +/** test whether iic is ready to write, 1 ready, 0 not ready */ +Inline int32_t dw_iic_putready(DW_IIC_REG *iic_reg_ptr) +{ + return ((iic_reg_ptr->IC_STATUS & IC_STATUS_TFNF) != 0); +} +/** test whether iic is ready to receive, 1 ready, 0 not ready */ +Inline int32_t dw_iic_getready(DW_IIC_REG *iic_reg_ptr) +{ + return ((iic_reg_ptr->IC_STATUS & IC_STATUS_RFNE) != 0); +} +/** Write data into IIC TX FIFO with STOP/RESTART Condition, and R/W bit */ +Inline void dw_iic_putdata(DW_IIC_REG *iic_reg_ptr, uint32_t data) +{ + iic_reg_ptr->IC_DATA_CMD = data; +} + +/** Read Data from IIC RX FIFO */ +Inline uint32_t dw_iic_getdata(DW_IIC_REG *iic_reg_ptr) +{ + return (iic_reg_ptr->IC_DATA_CMD) & 0xff; +} + +/** Enable designware iic bit interrupt with mask */ +Inline void dw_iic_unmask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask) +{ + iic_reg_ptr->IC_INTR_MASK |= mask; +} + +/** Disable designware iic bit interrupt with mask */ +Inline void dw_iic_mask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask) +{ + iic_reg_ptr->IC_INTR_MASK &= ~mask; +} + +/** Get TX FIFO Length */ +Inline uint32_t dw_iic_get_txfifo_len(DW_IIC_REG *iic_reg_ptr) +{ + uint32_t txfifolen; + + txfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 16) & 0xff) + 1; + + return txfifolen; +} + +/** Get RX FIFO Length */ +Inline uint32_t dw_iic_get_rxfifo_len(DW_IIC_REG *iic_reg_ptr) +{ + uint32_t rxfifolen; + + rxfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 8) & 0xff) + 1; + + return rxfifolen; +} + +/** Set designware iic transfer in 7bit of 10bit addressing mode as a master */ +Inline void dw_iic_set_mstaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) +{ +#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT + if (mode == IIC_7BIT_ADDRESS) { + iic_reg_ptr->IC_TAR &= ~IC_10BITADDR_MASTER; + } else { + iic_reg_ptr->IC_TAR |= IC_10BITADDR_MASTER; + } +#else + dw_iic_disable(iic_reg_ptr); + if (mode == IIC_7BIT_ADDRESS) { + iic_reg_ptr->IC_CON &= ~MST_10_BIT_ADDR_MODE; + } else { + iic_reg_ptr->IC_CON |= MST_10_BIT_ADDR_MODE; + } + dw_iic_enable(iic_reg_ptr); +#endif +} + +/** Set designware iic transfer in 7bit of 10bit addressing mode as a slave */ +Inline void dw_iic_set_slvaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) +{ + dw_iic_disable(iic_reg_ptr); + if (mode == IIC_7BIT_ADDRESS) { + iic_reg_ptr->IC_CON &= ~SLV_10_BIT_ADDR_MODE; + } else { + iic_reg_ptr->IC_CON |= SLV_10_BIT_ADDR_MODE; + } + dw_iic_enable(iic_reg_ptr); +} + +/** Set designware iic transfer target address for addressing any iic slave device as a master */ +Inline void dw_iic_set_taraddr(DW_IIC_REG *iic_reg_ptr, uint32_t address) +{ +#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT + iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK); + iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address); +#else + dw_iic_disable(iic_reg_ptr); + iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK); + iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address); + dw_iic_enable(iic_reg_ptr); +#endif +} + +/** Set designware iic slave address as a slave */ +Inline void dw_iic_set_slvaddr(DW_IIC_REG *iic_reg_ptr, uint32_t address) +{ + dw_iic_disable(iic_reg_ptr); + iic_reg_ptr->IC_SAR &= ~(IC_SAR_10BIT_ADDR_MASK); + iic_reg_ptr->IC_SAR |= (IC_SAR_10BIT_ADDR_MASK & address); + dw_iic_enable(iic_reg_ptr); +} + +/** Select speed mode, and return proper speed mode configuration */ +Inline uint32_t dw_iic_select_speedmode(uint32_t speedmode) +{ + uint32_t speedcfg; + + if (speedmode == IIC_SPEED_STANDARD) { + speedcfg = IC_CON_SPEED_STANDARD; + } else if (speedmode == IIC_SPEED_FAST) { + speedcfg = IC_CON_SPEED_FAST; + } else if (speedmode == IIC_SPEED_FASTPLUS) { + speedcfg = IC_CON_SPEED_FAST; + } else if (speedmode == IIC_SPEED_HIGH) { + speedcfg = IC_CON_SPEED_HIGH; + } else { + speedcfg = IC_CON_SPEED_HIGH; + } + return speedcfg; +} +/** Set designware iic speed mode */ +Inline void dw_iic_set_speedmode(DW_IIC_REG *iic_reg_ptr, uint32_t speedmode) +{ + uint32_t ic_con_val; + + dw_iic_disable(iic_reg_ptr); + ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_SPEED_MASK); + ic_con_val |= dw_iic_select_speedmode(speedmode); + iic_reg_ptr->IC_CON = ic_con_val; + dw_iic_enable(iic_reg_ptr); +} + +/** Set designware working mode as master or slave */ +Inline void dw_iic_set_working_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) +{ + uint32_t ic_con_val; + dw_iic_disable(iic_reg_ptr); + ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_MST_SLV_MODE_MASK); + if (mode == DEV_MASTER_MODE) { + ic_con_val |= IC_CON_ENA_MASTER_MODE; + } else { + ic_con_val |= IC_CON_ENA_SLAVE_MODE; + } + dw_iic_enable(iic_reg_ptr); +} + +/** Set IC_CLK frequency by configuration the *CNT registers for different speed modes */ +Inline void dw_iic_set_scl_cnt(DW_IIC_REG *iic_reg_ptr, DW_IIC_SCL_CNT *scl_cnt) +{ + dw_iic_disable(iic_reg_ptr); + iic_reg_ptr->IC_SS_SCL_HCNT = scl_cnt->ss_scl_hcnt; + iic_reg_ptr->IC_SS_SCL_LCNT = scl_cnt->ss_scl_lcnt; + iic_reg_ptr->IC_FS_SCL_HCNT = scl_cnt->fs_scl_hcnt; + iic_reg_ptr->IC_FS_SCL_LCNT = scl_cnt->fs_scl_lcnt; + iic_reg_ptr->IC_HS_SCL_HCNT = scl_cnt->hs_scl_hcnt; + iic_reg_ptr->IC_HS_SCL_LCNT = scl_cnt->hs_scl_lcnt; + dw_iic_enable(iic_reg_ptr); +} + +/** Set spike suppression configuration */ +Inline void dw_iic_set_spike_len(DW_IIC_REG *iic_reg_ptr, DW_IIC_SPKLEN *spklen) +{ + dw_iic_disable(iic_reg_ptr); + iic_reg_ptr->IC_FS_SPKLEN = spklen->fs_spklen; + iic_reg_ptr->IC_HS_SPKLEN = spklen->hs_spklen; + dw_iic_enable(iic_reg_ptr); +} + +Inline void dw_iic_flush_tx(DW_IIC_REG *iic_reg_ptr) +{ + (void)iic_reg_ptr->IC_CLR_INTR; +} + +Inline void dw_iic_flush_rx(DW_IIC_REG *iic_reg_ptr) +{ +} + +static uint32_t dw_iic_get_slv_state(DW_IIC_REG *iic_reg_ptr) +{ + uint32_t status; + uint32_t slv_state = IIC_SLAVE_STATE_FREE; + + status = iic_reg_ptr->IC_RAW_INTR_STAT; + if (status & IC_INTR_STAT_GEN_CALL) { + /* General Call address is received and it is acknowledged */ + slv_state |= IIC_SLAVE_STATE_GC_REQ; + } + if (status & IC_INTR_STAT_RX_FULL) { + /* master is attempting to write data to this slave */ + slv_state |= IIC_SLAVE_STATE_WR_REQ; + } + if (status & IC_INTR_STAT_RD_REQ) { + /* master is attempting to read data from this slave */ + slv_state |= IIC_SLAVE_STATE_RD_REQ; + } + if (status & IC_INTR_STAT_RX_DONE) { + /* master does not acknowledge a transmitted byte, and transmission is done */ + slv_state |= IIC_SLAVE_STATE_RD_DONE; + status = iic_reg_ptr->IC_CLR_RX_DONE; + } + if (status & IC_INTR_STAT_START_DET) { + /* a START or RESTART condition has occurred */ + slv_state |= IIC_SLAVE_STATE_START; + status = iic_reg_ptr->IC_CLR_START_DET; /* Clear it when read */ + } + if (status & IC_INTR_STAT_STOP_DET) { + /* a STOP condition has occurred */ + slv_state |= IIC_SLAVE_STATE_STOP; + status = iic_reg_ptr->IC_CLR_STOP_DET; /* Clear it when read */ + } + if (status & (IC_INTR_STAT_TX_ABRT|IC_INTR_STAT_TX_OVER\ + |IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { + /* error case */ + slv_state |= IIC_SLAVE_STATE_ERROR; + status = iic_reg_ptr->IC_CLR_TX_ABRT; /* Clear it when read */ + status = iic_reg_ptr->IC_CLR_TX_OVER; + status = iic_reg_ptr->IC_CLR_RX_OVER; + status = iic_reg_ptr->IC_CLR_RX_UNDER; + } + + return slv_state; +} + +/** Init Designware IIC Device into Master mode */ +static void dw_iic_master_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t speed_mode, uint32_t addr_mode, uint32_t tar_addr) +{ + uint32_t ic_con_val = 0; + DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs; + + dw_iic_disable(iic_reg_ptr); + + /* disable all iic interrupt */ + iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL; + + /* Set to 7bit addressing and update target address */ + iic_reg_ptr->IC_TAR = (tar_addr & IC_TAR_10BIT_ADDR_MASK) | IC_TAR_SPECIAL | IC_TAR_GC_OR_START; + /* master mode, restart enabled */ + ic_con_val = dw_iic_select_speedmode(speed_mode) | IC_CON_ENA_MASTER_MODE | IC_CON_RESTART_EN; + +#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT + if (addr_mode == IIC_10BIT_ADDRESS) { + iic_reg_ptr->IC_TAR |= MST_10_BIT_ADDR_MODE; + } +#else + if (addr_mode == IIC_10BIT_ADDRESS) { + ic_con_val |= MST_10_BIT_ADDR_MODE; + } +#endif + /* Set final IC_CON value */ + iic_reg_ptr->IC_CON = ic_con_val; + /* FIFO threshold settings */ + iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD; + iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD; + /* Master code settings */ + iic_reg_ptr->IC_HS_MADDR = iic_ctrl_ptr->iic_master_code; + dw_iic_enable(iic_reg_ptr); + + /* Clock Settings */ + dw_iic_set_scl_cnt(iic_reg_ptr, &(iic_ctrl_ptr->iic_scl_cnt)); + dw_iic_set_spike_len(iic_reg_ptr, &(iic_ctrl_ptr->iic_spklen)); +} + +/** Init Designware IIC Device into Slave mode */ +static void dw_iic_slave_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t addr_mode, uint32_t slv_addr) +{ + uint32_t ic_con_val = 0; + DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs; + + dw_iic_disable(iic_reg_ptr); + + /* disable all iic interrupt */ + iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL; + + /* Set slave device address as a slave */ + iic_reg_ptr->IC_SAR = slv_addr & IC_SAR_10BIT_ADDR_MASK; + /* slave mode, 7 bit slave address */ + ic_con_val = IC_CON_ENA_SLAVE_MODE; + /* If addr mode select to be 10 bit address mode */ + if (addr_mode == IIC_10BIT_ADDRESS) { + ic_con_val |= SLV_10_BIT_ADDR_MODE; + } + + /* Set final IC_CON value */ + iic_reg_ptr->IC_CON = ic_con_val; + /* FIFO threshold settings */ + iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD; + iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD; + + dw_iic_enable(iic_reg_ptr); +} + +/** Check error for IIC master device */ +static int32_t dw_iic_mst_chkerr(DW_IIC_CTRL *iic_ctrl_ptr) +{ + uint32_t status; + int32_t ercd = IIC_ERR_NONE; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + status = iic_reg_ptr->IC_RAW_INTR_STAT; + if (status & IC_INTR_STAT_TX_ABRT) { + status = iic_reg_ptr->IC_TX_ABRT_SOURCE; + if (status & IIC_MST_ABRT_LOST_BUS) { + ercd = IIC_ERR_LOST_BUS; + } else if (status & IIC_MST_ABRT_ADDR_NOACK) { + ercd = IIC_ERR_ADDR_NOACK; + } else if (status & IIC_MST_ABRT_DATA_NOACK) { + ercd = IIC_ERR_DATA_NOACK; + } else { + ercd = IIC_ERR_UNDEF; + } + status = iic_reg_ptr->IC_CLR_TX_ABRT; + } else { + if (status & IC_INTR_STAT_TX_OVER) { + iic_ctrl_ptr->iic_tx_over ++; + status = iic_reg_ptr->IC_CLR_TX_OVER; + } + if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { + iic_ctrl_ptr->iic_rx_over ++; + status = iic_reg_ptr->IC_CLR_RX_OVER; + status = iic_reg_ptr->IC_CLR_RX_UNDER; + } + } + return ercd; +} + +/** Check error for IIC slave device */ +static int32_t dw_iic_slv_chkerr(DW_IIC_CTRL *iic_ctrl_ptr) +{ + uint32_t status; + int32_t ercd = IIC_ERR_NONE; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + status = iic_reg_ptr->IC_RAW_INTR_STAT; + if (status & IC_INTR_STAT_TX_ABRT) { + status = iic_reg_ptr->IC_TX_ABRT_SOURCE; + if (status & IIC_SLV_ABRT_LOST_BUS) { + ercd = IIC_ERR_LOST_BUS; + } else if (status & IC_TX_ABRT_SLVFLUSH_TXFIFO) { + /* Flush tx fifo */ + status = iic_reg_ptr->IC_TX_ABRT_SOURCE; + } else { + ercd = IIC_ERR_UNDEF; + } + status = iic_reg_ptr->IC_CLR_TX_ABRT; + } else { + if (status & IC_INTR_STAT_TX_OVER) { + iic_ctrl_ptr->iic_tx_over ++; + status = iic_reg_ptr->IC_CLR_TX_OVER; + } + if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { + iic_ctrl_ptr->iic_rx_over ++; + status = iic_reg_ptr->IC_CLR_RX_OVER; + status = iic_reg_ptr->IC_CLR_RX_UNDER; + } + } + return ercd; +} + +/** enable designware iic */ +static void dw_iic_enable_device(DEV_IIC_INFO *iic_info_ptr) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + if ((iic_info_ptr->status & DEV_ENABLED) == 0) { + dw_iic_enable(iic_reg_ptr); + iic_info_ptr->status |= DEV_ENABLED; + } +} + +/** disable designware iic */ +static void dw_iic_disable_device(DEV_IIC_INFO *iic_info_ptr) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + uint32_t i; + + for (i=0; iIC_ENABLE_STATUS & IC_ENABLE_STATUS_IC_EN) == 0) { + break; + } + } + iic_info_ptr->status &= ~DEV_ENABLED; +} + +static void dw_iic_reset_device(DEV_IIC_INFO *iic_info_ptr) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + dw_iic_disable_device(iic_info_ptr); + dw_iic_clear_interrupt_all(iic_reg_ptr); + iic_info_ptr->next_cond = IIC_MODE_STOP; + iic_info_ptr->cur_state = IIC_FREE; + iic_info_ptr->err_state = IIC_ERR_NONE; + iic_ctrl_ptr->iic_tx_over = 0; + iic_ctrl_ptr->iic_rx_over = 0; + dw_iic_enable_device(iic_info_ptr); +} + +/** Disable iic master interrupt for transmit or receive */ +static void dw_iic_mst_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) +{ + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + switch (cbrtn) { + case DW_IIC_RDY_SND: + dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE); + iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE; + break; + case DW_IIC_RDY_RCV: + dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE); + iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE; + break; + default: + break; + } +} + +/** Disable iic slave interrupt for transmit or receive */ +static void dw_iic_slv_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) +{ + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + switch (cbrtn) { + case DW_IIC_RDY_SND: + dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE); + iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE; + break; + case DW_IIC_RDY_RCV: + dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE); + iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE; + break; + default: + break; + } +} + +/** Enable iic master interrupt for transmit or receive */ +static void dw_iic_mst_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) +{ + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + switch (cbrtn) { + case DW_IIC_RDY_SND: + iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE; + dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE); + break; + case DW_IIC_RDY_RCV: + iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE; + dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE); + break; + default: + break; + } +} + +/** Enable iic slave interrupt for transmit or receive */ +static void dw_iic_slv_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) +{ + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + switch (cbrtn) { + case DW_IIC_RDY_SND: + iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE; + dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE); + break; + case DW_IIC_RDY_RCV: + iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE; + dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE); + break; + default: + break; + } +} + +/** + * \brief disable designware iic send or receive interrupt + * \param[in] DEV_IIC_INFO *iic_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static void dw_iic_dis_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + dw_iic_mst_dis_cbr(iic_ctrl_ptr, cbrtn); + } else { + dw_iic_slv_dis_cbr(iic_ctrl_ptr, cbrtn); + } + + if (iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) { + if ((iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) == 0) { + int_disable(iic_ctrl_ptr->intno); + iic_ctrl_ptr->int_status &= ~DW_IIC_GINT_ENABLE; + } + } +} + +/** + * \brief enable DesignWare IIC send or receive interrupt + * \param[in] DEV_IIC_INFO *iic_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static void dw_iic_ena_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + dw_iic_mst_ena_cbr(iic_ctrl_ptr, cbrtn); + } else { + dw_iic_slv_ena_cbr(iic_ctrl_ptr, cbrtn); + } + + if ((iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) == 0) { + if (iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) { + iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE; + int_enable(iic_ctrl_ptr->intno); + } + } +} + +/** + * \brief enable designware iic interrupt + * \param iic_info_ptr iic information structure pointer + */ +static void dw_iic_enable_interrupt(DEV_IIC_INFO *iic_info_ptr) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler); + iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE; + int_enable(iic_ctrl_ptr->intno); /** enable iic interrupt */ +} +/** + * \brief disable designware iic interrupt + * \param iic_info_ptr iic information structure pointer + */ +static void dw_iic_disable_interrupt(DEV_IIC_INFO *iic_info_ptr) +{ + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + /** disable iic send&receive interrupt after disable iic interrupt */ + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + /* disable iic interrupt */ + int_disable(iic_ctrl_ptr->intno); + iic_ctrl_ptr->int_status &= ~(DW_IIC_GINT_ENABLE|DW_IIC_TXINT_ENABLE|DW_IIC_RXINT_ENABLE); +} + +/** abort current interrupt transmit transfer */ +static void dw_iic_abort_tx(DEV_IIC *iic_obj) +{ + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + if (iic_ctrl_ptr->int_status & DW_IIC_TXINT_ENABLE) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + iic_info_ptr->status |= DEV_IN_TX_ABRT; + if (iic_info_ptr->iic_cbs.tx_cb != NULL) { + iic_info_ptr->iic_cbs.tx_cb(iic_obj); + } + iic_info_ptr->status &= ~(DEV_IN_TX_ABRT); + } +} + +/** abort current interrupt receive transfer */ +static void dw_iic_abort_rx(DEV_IIC *iic_obj) +{ + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + if (iic_ctrl_ptr->int_status & DW_IIC_RXINT_ENABLE) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + iic_info_ptr->status |= DEV_IN_RX_ABRT; + if (iic_info_ptr->iic_cbs.rx_cb != NULL) { + iic_info_ptr->iic_cbs.rx_cb(iic_obj); + } + iic_info_ptr->status &= ~(DEV_IN_RX_ABRT); + } +} + +/** Get available transmit fifo count */ +static int32_t dw_iic_get_txavail(DW_IIC_CTRL *iic_ctrl_ptr) +{ + int32_t tx_avail = 0; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + if (iic_ctrl_ptr->tx_fifo_len <= 1) { + if (dw_iic_putready(iic_reg_ptr) == 1) { + tx_avail = 1; + } else { + tx_avail = 0; + } + } else { + tx_avail = iic_ctrl_ptr->tx_fifo_len - iic_reg_ptr->IC_TXFLR; + } + return tx_avail; +} + +/** Get available receive fifo count */ +static int32_t dw_iic_get_rxavail(DW_IIC_CTRL *iic_ctrl_ptr) +{ + int32_t rx_avail = 0; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + if (iic_ctrl_ptr->rx_fifo_len <= 1) { + if (dw_iic_getready(iic_reg_ptr) == 1) { + rx_avail = 1; + } else { + rx_avail = 0; + } + } else { + rx_avail = iic_reg_ptr->IC_RXFLR; + } + return rx_avail; +} + +/** + * IIC Master device transmit 1 data, + * next_cond can be \ref IC_DATA_CMD_STOP, + * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE + */ +static int32_t dw_iic_mst_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data, uint32_t next_cond) +{ + uint32_t i = 0; + int32_t ercd = IIC_ERR_NONE; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + while (dw_iic_putready(iic_reg_ptr) == 0) { + if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; + ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); + if (ercd != IIC_ERR_NONE) return ercd; + } + dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ|next_cond); + + return ercd; +} + +/** IIC Slave device transmit 1 data */ +static int32_t dw_iic_slv_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data) +{ + uint32_t i = 0; + int32_t ercd = IIC_ERR_NONE; + uint32_t slv_state, temp; + uint32_t ready2send = 0; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) { + ercd = dw_iic_slv_chkerr(iic_ctrl_ptr); + if (ercd != IIC_ERR_NONE) return ercd; + slv_state = iic_reg_ptr->IC_RAW_INTR_STAT; + if (slv_state & IC_INTR_STAT_RD_REQ) { + if (dw_iic_putready(iic_reg_ptr)) { + temp = iic_reg_ptr->IC_CLR_RD_REQ; + ready2send = 1; + break; + } + } else if (slv_state & IC_INTR_STAT_RX_DONE) { /* Put RX Done before STOP */ + temp = iic_reg_ptr->IC_CLR_RX_DONE; + return IIC_ERR_MSTSTOP; + } else if (slv_state & IC_INTR_STAT_STOP_DET) { + temp = iic_reg_ptr->IC_CLR_STOP_DET; + return IIC_ERR_MSTSTOP; + } + } + if (ready2send) { + dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ); + } else { + ercd = IIC_ERR_TIMEOUT; + } + + return ercd; +} + +/** + * IIC Master device receive 1 data, + * next_cond can be \ref IC_DATA_CMD_STOP, + * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE + */ +static int32_t dw_iic_mst_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data, uint32_t next_cond) +{ + uint32_t i = 0; + int32_t ercd = IIC_ERR_NONE; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + /* Issue a read request */ + while (dw_iic_putready(iic_reg_ptr) == 0) { + if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; + ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); + if (ercd != IIC_ERR_NONE) return ercd; + } + dw_iic_putdata(iic_reg_ptr, next_cond|IC_DATA_CMD_READ_REQ); + /* Wait to read data */ + i = 0; + while (dw_iic_getready(iic_reg_ptr) == 0) { + if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; + ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); + if (ercd != IIC_ERR_NONE) return ercd; + } + *data = dw_iic_getdata(iic_reg_ptr); + return ercd; +} + +/** IIC Slave device receive 1 data */ +static int32_t dw_iic_slv_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data) +{ + uint32_t i = 0; + int32_t ercd = IIC_ERR_NONE; + uint32_t slv_state, temp; + uint32_t ready2read = 0; + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) { + ercd = dw_iic_slv_chkerr(iic_ctrl_ptr); + if (ercd != IIC_ERR_NONE) return ercd; + slv_state = iic_reg_ptr->IC_RAW_INTR_STAT; + if (slv_state & IC_INTR_STAT_START_DET) { + temp = iic_reg_ptr->IC_CLR_START_DET; + } + if (slv_state & IC_INTR_STAT_RX_FULL) { + if (dw_iic_getready(iic_reg_ptr)) { + ready2read = 1; + break; + } + } else if (slv_state & IC_INTR_STAT_STOP_DET) { + temp = iic_reg_ptr->IC_CLR_STOP_DET; + return IIC_ERR_MSTSTOP; + } + } + if (ready2read) { + *data = dw_iic_getdata(iic_reg_ptr); + } else { + ercd = IIC_ERR_TIMEOUT; + } + + return ercd; +} + +/** IIC Master transmit called in interrupt */ +static void dw_iic_mst_int_write(DEV_IIC *iic_obj) +{ + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); + uint32_t iic_int_status; /** iic interrupt status */ + uint32_t last_cond, xmit_data, xmit_end = 0; + DEV_BUFFER *buf_ptr; + uint8_t *p_charbuf; + + if (iic_info_ptr->next_cond == IIC_MODE_STOP) { + last_cond = IC_DATA_CMD_STOP; + } else { + last_cond = IC_DATA_CMD_RESTART; + } + iic_int_status = (iic_reg_ptr->IC_INTR_STAT); + buf_ptr = &(iic_info_ptr->tx_buf); + p_charbuf = (uint8_t *)buf_ptr->buf; + if (p_charbuf) { + if (iic_int_status & IC_INTR_STAT_TX_EMPTY) { + xmit_end = 0; + while (dw_iic_putready(iic_reg_ptr)) { + xmit_data = (uint32_t)(p_charbuf[buf_ptr->ofs])|IC_DATA_CMD_WRITE_REQ; + if (buf_ptr->ofs == (buf_ptr->len-1)) { + xmit_end = 1; + xmit_data |= last_cond; + } else { + xmit_data |= IC_DATA_CMD_NONE; + } + buf_ptr->ofs ++; + dw_iic_putdata(iic_reg_ptr, xmit_data); + if (xmit_end) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + iic_info_ptr->cur_state = IIC_FREE; + if (iic_info_ptr->iic_cbs.tx_cb) { + iic_info_ptr->iic_cbs.tx_cb(iic_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + break; + } + } + } + if (iic_int_status & IC_INTR_STAT_TX_OVER) { + iic_ctrl_ptr->iic_tx_over ++; + } + if (iic_int_status & IC_INTR_STAT_TX_ABRT) { + iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr); + if (iic_info_ptr->err_state != IIC_ERR_NONE) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + iic_info_ptr->cur_state = IIC_FREE; + if (iic_info_ptr->iic_cbs.err_cb) { + iic_info_ptr->iic_cbs.err_cb(iic_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + } + } + } else { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + iic_info_ptr->cur_state = IIC_FREE; + } + /* Clear Interrupt */ + iic_int_status = iic_reg_ptr->IC_CLR_INTR; +} + +/** IIC Master receive called in interrupt */ +static void dw_iic_mst_int_read(DEV_IIC *iic_obj) +{ + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); + uint32_t iic_int_status; /** iic interrupt status */ + uint32_t last_cond, xmit_data; + DEV_BUFFER *buf_ptr; + DW_IIC_BUFFER *dw_iic_rxbuf_ptr; + uint8_t *p_charbuf; + + if (iic_info_ptr->next_cond == IIC_MODE_STOP) { + last_cond = IC_DATA_CMD_STOP; + } else { + last_cond = IC_DATA_CMD_RESTART; + } + iic_int_status = (iic_reg_ptr->IC_INTR_STAT); + buf_ptr = &(iic_info_ptr->rx_buf); + p_charbuf = (uint8_t *)buf_ptr->buf; + if (p_charbuf) { + dw_iic_rxbuf_ptr = &(iic_ctrl_ptr->dw_iic_rxbuf); + if (iic_int_status & IC_INTR_STAT_TX_EMPTY) { + while (dw_iic_putready(iic_reg_ptr)) { + if (dw_iic_rxbuf_ptr->ofs >= dw_iic_rxbuf_ptr->len) { + dw_iic_mask_interrupt(iic_reg_ptr, IC_INTR_STAT_TX_EMPTY); + break; + } + xmit_data = IC_DATA_CMD_READ_REQ; + if (dw_iic_rxbuf_ptr->ofs == (dw_iic_rxbuf_ptr->len-1)) { + xmit_data |= last_cond; + } else { + xmit_data |= IC_DATA_CMD_NONE; + } + dw_iic_rxbuf_ptr->ofs ++; + dw_iic_putdata(iic_reg_ptr, xmit_data); + } + } + if (iic_int_status & IC_INTR_STAT_RX_FULL) { + while (dw_iic_getready(iic_reg_ptr)) { + p_charbuf[buf_ptr->ofs] = dw_iic_getdata(iic_reg_ptr); + buf_ptr->ofs ++; + if (buf_ptr->ofs >= buf_ptr->len) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + iic_info_ptr->cur_state = IIC_FREE; + if (iic_info_ptr->iic_cbs.rx_cb) { + iic_info_ptr->iic_cbs.rx_cb(iic_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + dw_iic_rxbuf_ptr->ofs = 0; + dw_iic_rxbuf_ptr->len = 0; + break; + } + } + } + if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { + iic_ctrl_ptr->iic_rx_over ++; + } + if (iic_int_status & IC_INTR_STAT_TX_ABRT) { + iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr); + if (iic_info_ptr->err_state != IIC_ERR_NONE) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + iic_info_ptr->cur_state = IIC_FREE; + if (iic_info_ptr->iic_cbs.err_cb) { + iic_info_ptr->iic_cbs.err_cb(iic_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + dw_iic_rxbuf_ptr->ofs = 0; + dw_iic_rxbuf_ptr->len = 0; + } + } + } else { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + iic_info_ptr->cur_state = IIC_FREE; + } + /* Clear Interrupt */ + iic_int_status = iic_reg_ptr->IC_CLR_INTR; +} + +/** IIC Slave transmit called in interrupt */ +static void dw_iic_slv_int_process(DEV_IIC *iic_obj) +{ + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); + uint32_t iic_int_status; /** iic interrupt status */ + + iic_int_status = (iic_reg_ptr->IC_INTR_STAT); + if (iic_int_status & IC_INTR_STAT_RD_REQ) { /* Read request from master */ + if (iic_info_ptr->iic_cbs.tx_cb) { + iic_info_ptr->iic_cbs.tx_cb(iic_obj); + } else { /* When tx callback function is not set disable this tx int for slave */ + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + } + } + if (iic_int_status & IC_INTR_STAT_RX_FULL) { /* Write request from master */ + if (iic_info_ptr->iic_cbs.rx_cb) { + iic_info_ptr->iic_cbs.rx_cb(iic_obj); + } else { /* When rx callback function is not set disable this rx int for slave */ + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + } + } + if (iic_int_status & IC_INTR_STAT_TX_OVER) { + iic_ctrl_ptr->iic_tx_over ++; + } + if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { + iic_ctrl_ptr->iic_rx_over ++; + } + if (iic_int_status & IC_INTR_STAT_TX_ABRT) { + iic_info_ptr->err_state = dw_iic_slv_chkerr(iic_ctrl_ptr); + if (iic_info_ptr->err_state != IIC_ERR_NONE) { + if (iic_info_ptr->iic_cbs.err_cb) { + iic_info_ptr->iic_cbs.err_cb(iic_obj); + } + } + } + /* Clear Interrupt */ + iic_int_status = iic_reg_ptr->IC_CLR_INTR; +} + +/** @} end of group DEVICE_DW_IIC_STATIC */ + +/** + * \defgroup DEVICE_DW_IIC_IMPLEMENT DesignWare IIC Driver Function API Implement + * \ingroup DEVICE_DW_IIC + * \brief implement device hal iic api with DesignWare IIC + * @{ + */ + +/** + * \brief open a designware iic device + * \param[in] iic_obj iic device object pointer + * \param[in] mode iic working mode (master or slave) + * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_iic_info::speed_mode "speed mode", + * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_iic_info::slv_addr "slave device 7bit address" + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_iic_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ +int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param) +{ + int32_t ercd = E_OK; + uint32_t support_modes; + uint32_t param2check; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + DW_IIC_CHECK_EXP((mode==DEV_MASTER_MODE)||(mode==DEV_SLAVE_MODE), E_PAR); + if (mode == DEV_MASTER_MODE) { + DW_IIC_CHECK_EXP((param>=IIC_SPEED_STANDARD) && (param<=IIC_SPEED_ULTRA), E_PAR); + } + /* END OF ERROR CHECK */ + + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + + /* Check supported modes, master or slave */ + support_modes = iic_ctrl_ptr->support_modes; + DW_IIC_CHECK_EXP( (((support_modes)&DW_IIC_MASTER_SUPPORTED)&&(mode == DEV_MASTER_MODE)) || \ + (((support_modes)&DW_IIC_SLAVE_SUPPORTED)&&(mode == DEV_SLAVE_MODE)), E_NOSPT); + + /** Check opened before use case */ + if (iic_info_ptr->opn_cnt > 0) { + if (mode != iic_info_ptr->mode) { + /* current working mode is different from passing mode */ + return E_SYS; + } + if (mode == DEV_MASTER_MODE) { /* param is speed_mode when as master */ + param2check = iic_info_ptr->speed_mode; + } else { /* param is slv_addr when as slave */ + param2check = iic_info_ptr->slv_addr; + } + iic_info_ptr->opn_cnt ++; + if (param != param2check) { /* open with different speed mode */ + return E_OPNED; + } else { + return E_OK; + } + } + /* auto increase open count */ + iic_info_ptr->opn_cnt ++; + + iic_info_ptr->mode = mode; + if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { + iic_info_ptr->tar_addr &= IIC_7BIT_ADDRESS_MASK; + iic_info_ptr->slv_addr &= IIC_7BIT_ADDRESS_MASK; + } else { + iic_info_ptr->addr_mode = IIC_10BIT_ADDRESS; + iic_info_ptr->tar_addr &= IIC_10BIT_ADDRESS_MASK; + iic_info_ptr->slv_addr &= IIC_10BIT_ADDRESS_MASK; + } + +/* Do FIFO Length get before init */ +#if DW_IIC_CALC_FIFO_LEN_ENABLE + iic_ctrl_ptr->tx_fifo_len = dw_iic_get_txfifo_len(iic_ctrl_ptr->dw_iic_regs); + iic_ctrl_ptr->rx_fifo_len = dw_iic_get_rxfifo_len(iic_ctrl_ptr->dw_iic_regs); +#endif + + /* Disable device before init it */ + dw_iic_disable_device(iic_info_ptr); + + if (mode == DEV_MASTER_MODE) { + iic_info_ptr->speed_mode = param; + dw_iic_master_init(iic_ctrl_ptr, param, iic_info_ptr->addr_mode, iic_info_ptr->tar_addr); + } else { + iic_info_ptr->slv_addr = param; + dw_iic_slave_init(iic_ctrl_ptr, iic_info_ptr->addr_mode, param); + } + iic_info_ptr->status = DEV_ENABLED; + iic_info_ptr->cur_state = IIC_FREE; + iic_info_ptr->err_state = IIC_ERR_NONE; + iic_info_ptr->next_cond = IIC_MODE_STOP; + iic_info_ptr->extra = NULL; + + iic_ctrl_ptr->iic_tx_over = 0; + iic_ctrl_ptr->iic_rx_over = 0; + iic_ctrl_ptr->int_status = 0; + memset(&(iic_ctrl_ptr->dw_iic_rxbuf), 0, sizeof(DW_IIC_BUFFER)); + iic_ctrl_ptr->dw_iic_rxbuf.buf = &(iic_info_ptr->rx_buf); + /** install iic interrupt into system */ + dw_iic_disable_interrupt(iic_info_ptr); + int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler); + memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS)); + +error_exit: + return ercd; +} + +/** + * \brief Close a DesignWare IIC device + * \param[in] iic_obj iic device object pointer + * \retval E_OK Close successfully without any issues(including secenary that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_iic_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ +int32_t dw_iic_close (DEV_IIC *iic_obj) +{ + int32_t ercd = E_OK; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_OK); + /* END OF ERROR CHECK */ + + iic_info_ptr->opn_cnt --; + if (iic_info_ptr->opn_cnt == 0) { + dw_iic_disable_interrupt(iic_info_ptr); + dw_iic_abort_tx(iic_obj); + dw_iic_abort_rx(iic_obj); + memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS)); + dw_iic_disable_device(iic_info_ptr); + iic_info_ptr->status = DEV_DISABLED; + iic_info_ptr->next_cond = IIC_MODE_STOP; + iic_info_ptr->extra = NULL; + } else { + ercd = E_OPNED; + } + +error_exit: + return ercd; +} + +/** + * \brief Control iic by ctrl command + * \param[in] iic_obj iic device object pointer + * \param[in] ctrl_cmd \ref DEVICE_HAL_IIC_CTRLCMD "control command", to change or get some thing related to iic + * \param[in,out] param parameters that maybe argument of the command, + * or return values of the command, must not be NULL + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ +int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param) +{ + int32_t ercd = E_OK; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); + /* END OF ERROR CHECK */ + + uint32_t val32; /** to receive unsigned int value */ + DEV_BUFFER *devbuf; + + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); + DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); + + /* check whether current device is disabled */ + if ((iic_info_ptr->status & DEV_ENABLED) == 0) { + /** When device is disabled, + * only IIC_CMD_ENA_DEV, IIC_CMD_DIS_DEV, IIC_CMD_GET_STATUS, IIC_CMD_RESET + * are available, other commands will return E_SYS + */ + if ((ctrl_cmd != IIC_CMD_ENA_DEV) && \ + (ctrl_cmd != IIC_CMD_DIS_DEV) && \ + (ctrl_cmd != IIC_CMD_GET_STATUS) && \ + (ctrl_cmd != IIC_CMD_RESET) ) { + return E_SYS; + } + } + + switch (ctrl_cmd) { + /* Commmon commands for both master and slave mode */ + case IIC_CMD_GET_STATUS: + DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = iic_info_ptr->status; + break; + case IIC_CMD_ENA_DEV: + dw_iic_enable_device(iic_info_ptr); + break; + case IIC_CMD_DIS_DEV: + dw_iic_disable_device(iic_info_ptr); + break; + case IIC_CMD_RESET: + dw_iic_reset_device(iic_info_ptr); + break; + case IIC_CMD_FLUSH_TX: + dw_iic_flush_tx(iic_reg_ptr); + break; + case IIC_CMD_FLUSH_RX: + dw_iic_flush_rx(iic_reg_ptr); + break; + case IIC_CMD_SET_ADDR_MODE: + val32 = (uint32_t)param; + DW_IIC_CHECK_EXP((val32==IIC_7BIT_ADDRESS) || (val32==IIC_10BIT_ADDRESS), E_PAR); + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + dw_iic_set_mstaddr_mode(iic_reg_ptr, val32); + } else { + dw_iic_set_slvaddr_mode(iic_reg_ptr, val32); + } + iic_info_ptr->addr_mode = val32; + break; + case IIC_CMD_GET_RXAVAIL: + DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_iic_get_rxavail(iic_ctrl_ptr); + break; + case IIC_CMD_GET_TXAVAIL: + DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_iic_get_txavail(iic_ctrl_ptr); + break; + case IIC_CMD_SET_TXCB: + DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + iic_info_ptr->iic_cbs.tx_cb = param; + break; + case IIC_CMD_SET_RXCB: + DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + iic_info_ptr->iic_cbs.rx_cb = param; + break; + case IIC_CMD_SET_ERRCB: + DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + iic_info_ptr->iic_cbs.err_cb = param; + break; + case IIC_CMD_ABORT_TX: + dw_iic_abort_tx(iic_obj); + if ((iic_info_ptr->mode == DEV_MASTER_MODE) \ + && (iic_info_ptr->cur_state == IIC_IN_TX)) { + iic_info_ptr->cur_state = IIC_FREE; + } + break; + case IIC_CMD_ABORT_RX: + dw_iic_abort_rx(iic_obj); + if ((iic_info_ptr->mode == DEV_MASTER_MODE) \ + && (iic_info_ptr->cur_state == IIC_IN_RX)) { + iic_info_ptr->cur_state = IIC_FREE; + } + break; + case IIC_CMD_SET_TXINT: + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX); + } + val32 = (uint32_t)param; + if (val32 == 0) { + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); + iic_info_ptr->cur_state = IIC_FREE; + } else { + iic_info_ptr->cur_state = IIC_IN_TX; + dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_SND); + } + break; + case IIC_CMD_SET_RXINT: + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX); + } + val32 = (uint32_t)param; + if (val32 == 0) { + iic_info_ptr->cur_state = IIC_FREE; + dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + } else { + iic_info_ptr->cur_state = IIC_IN_RX; + dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_RCV); + } + break; + case IIC_CMD_SET_TXINT_BUF: + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX); + } + DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + iic_info_ptr->tx_buf = *devbuf; + iic_info_ptr->tx_buf.ofs = 0; + } else { + iic_info_ptr->tx_buf.buf = NULL; + iic_info_ptr->tx_buf.len = 0; + iic_info_ptr->tx_buf.ofs = 0; + } + break; + case IIC_CMD_SET_RXINT_BUF: + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX); + } + DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + iic_info_ptr->rx_buf = *devbuf; + iic_info_ptr->rx_buf.ofs = 0; + iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0; + iic_ctrl_ptr->dw_iic_rxbuf.len = devbuf->len; + } else { + iic_info_ptr->rx_buf.buf = NULL; + iic_info_ptr->rx_buf.len = 0; + iic_info_ptr->rx_buf.ofs = 0; + iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0; + iic_ctrl_ptr->dw_iic_rxbuf.len = 0; + } + break; + + /* Master mode only commands */ + case IIC_CMD_MST_SET_SPEED_MODE: + DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + val32 = (uint32_t)param; + DW_IIC_CHECK_EXP((val32>=IIC_SPEED_STANDARD) && (val32<=IIC_SPEED_ULTRA), E_PAR); + dw_iic_set_speedmode(iic_reg_ptr, val32); + iic_info_ptr->speed_mode = val32; + break; + case IIC_CMD_MST_SET_TAR_ADDR: + DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { + val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK; + } else { + val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK; + } + if (val32 != iic_info_ptr->tar_addr) { + dw_iic_set_taraddr(iic_reg_ptr, val32); + iic_info_ptr->tar_addr = val32; + } + break; + case IIC_CMD_MST_SET_NEXT_COND: + DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + val32 = (uint32_t)param; + DW_IIC_CHECK_EXP((val32==IIC_MODE_STOP) || (val32==IIC_MODE_RESTART), E_PAR); + iic_info_ptr->next_cond = (uint32_t)param; + break; + + /* Slave mode only commands */ + case IIC_CMD_SLV_SET_SLV_ADDR: + DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT); + if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { + val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK; + } else { + val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK; + } + dw_iic_set_slvaddr(iic_reg_ptr, val32); + iic_info_ptr->slv_addr = val32; + break; + case IIC_CMD_SLV_GET_SLV_STATE: + DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT); + DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((uint32_t *)param) = dw_iic_get_slv_state(iic_reg_ptr); + break; + + default: + ercd = E_NOSPT; + break; + } + +error_exit: + return ercd; +} + +/** + * \brief poll transmit data through DesignWare IIC as master or slave + * \param[in] iic_obj iic device object pointer + * \param[in] data data that need to send (data must be uint8_t type) + * \param[in] len data length need to send + * \retval >0 Byte count that was successfully sent for poll method, + * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_CTX Device is still in transfer state + * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled + */ +int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); + DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS); + DW_IIC_CHECK_EXP(data!=NULL, E_PAR); + DW_IIC_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + int32_t i = 0; + uint32_t last_cond = 0; /* Last data for transmit, STOP or RESTART */ + int32_t error_state = IIC_ERR_NONE; + const uint8_t *p_charbuf = (const uint8_t *)data; + + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); + + if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode transmit data */ + if (iic_info_ptr->next_cond == IIC_MODE_STOP) { + last_cond = IC_DATA_CMD_STOP; + } else { + last_cond = IC_DATA_CMD_RESTART; + } + + /* Try to transmit 0 -> (len-1) data */ + len = len - 1; /* Last data write differently */ + while (i < len) { + error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i]), IC_DATA_CMD_NONE); + if (error_state != IIC_ERR_NONE) { + break; + } + i ++; + } + /* Try to transmit the last data with STOP or RESTART condition */ + if (error_state == IIC_ERR_NONE) { + error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[len]), last_cond); + if (error_state == IIC_ERR_NONE) { + i = i + 1; /* Add last data into send count */ + } + } + } else { /* Slave mode transmit data */ + while (i < len) { + error_state = dw_iic_slv_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i])); + if (error_state != IIC_ERR_NONE) { + break; + } + i ++; + } + } + iic_info_ptr->err_state = error_state; + ercd = i; + +error_exit: + return ercd; +} + +/** + * \brief read data through DesignWare IIC + * \param[in] iic_obj iic device object pointer + * \param[out] data data that need to read (data must be uint8_t type) + * \param[in] len data count need to read + * \retval >0 Byte count that was successfully received for poll method, + * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". + * \retval E_OBJ Device object is not valid or not exists + * \retval E_CTX Device is still in transfer state + * \retval E_PAR Parameter is not valid + * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled + */ +int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); + DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS); + DW_IIC_CHECK_EXP(data!=NULL, E_PAR); + DW_IIC_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + int32_t i = 0; + uint32_t last_cond = 0; /* Last data for receive, STOP or RESTART */ + uint32_t val32 = 0; + int32_t error_state = IIC_ERR_NONE; + uint8_t *p_charbuf = (uint8_t *)data; + + DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); + + if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode receive data */ + if (iic_info_ptr->next_cond == IIC_MODE_STOP) { + last_cond = IC_DATA_CMD_STOP; + } else { + last_cond = IC_DATA_CMD_RESTART; + } + + /* Try to receive 0 -> (len-1) data */ + len = len - 1; /* Last data write differently */ + while (i < len) { + error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, IC_DATA_CMD_NONE); + if (error_state != IIC_ERR_NONE) { + break; + } else { + p_charbuf[i] = (uint8_t)val32; + } + i ++; + } + /* Try to receive the last data with STOP or RESTART condition */ + if (error_state == IIC_ERR_NONE) { + error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, last_cond); + if (error_state == IIC_ERR_NONE) { + p_charbuf[len] = (uint8_t)val32; + i = i + 1; /* Add last data into send count */ + } + } + } else { /* Slave mode receive data */ + while (i < len) { + error_state = dw_iic_slv_read_data(iic_ctrl_ptr, &val32); + if (error_state != IIC_ERR_NONE) { + break; + } else { + p_charbuf[i] = (uint8_t)val32; + } + i ++; + } + } + iic_info_ptr->err_state = error_state; + ercd = i; + +error_exit: + return ercd; +} + +/** + * \brief DesignWare IIC interrupt processing routine + * \param[in] iic_info_ptr DEV_IIC *iic_obj + * \param[in] ptr extra information + */ +void dw_iic_isr(DEV_IIC *iic_obj, void *ptr) +{ + int32_t ercd = E_OK; + DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); + + /* START ERROR CHECK */ + VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); + /* END OF ERROR CHECK */ + + if (iic_info_ptr->mode == DEV_MASTER_MODE) { + if (iic_info_ptr->cur_state == IIC_IN_TX) { + dw_iic_mst_int_write(iic_obj); + } else { + dw_iic_mst_int_read(iic_obj); + } + } else { + dw_iic_slv_int_process(iic_obj); + } + +error_exit: + return; +} +/** @} end of group DEVICE_DW_IIC_IMPLEMENT */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic.h new file mode 100644 index 0000000000..55c551a67e --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/iic/dw_iic.h @@ -0,0 +1,242 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-30 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \brief designware iic driver header file + * \ingroup DEVICE_DW_IIC + */ + +#ifndef _DW_IIC_H_ +#define _DW_IIC_H_ + +#include "device/device_hal/inc/dev_iic.h" + +#include "inc/arc/arc_exception.h" + + +/** + * If this header file is included, + * will indicate that this designware iic device + * is used + */ +#define DEVICE_USE_DESIGNWARE_IIC + +/** + * \defgroup DEVICE_DW_IIC_INFO DesignWare IIC Related Information + * \ingroup DEVICE_DW_IIC + * \brief Defines some macros of DesignWare IIC need. + * \details macros like, iic number + * @{ + */ +#define DW_IIC_MASTER_SUPPORTED (0x1) /*!< Support Designware IIC Master Mode */ +#define DW_IIC_SLAVE_SUPPORTED (0x2) /*!< Support Designware IIC Slave Mode */ +/*!< Support Designware IIC Both Master and Slave Mode */ +#define DW_IIC_BOTH_SUPPORTED (DW_IIC_MASTER_SUPPORTED|DW_IIC_SLAVE_SUPPORTED) +/** @} */ + +/** + * \defgroup DEVICE_DW_IIC_REGSTRUCT DesignWare IIC Register Structure + * \ingroup DEVICE_DW_IIC + * \brief contains definitions of DesignWare IIC register structure. + * \details detailed description of DesignWare IIC register information + * @{ + */ +/** + * \brief DesignWare IIC register structure + * \details Detailed struct description of DesignWare IIC + * block register information, implementation of dev_iic_info::iic_regs + */ +typedef volatile struct dw_iic_reg { + uint32_t IC_CON; /*!< (0x00) : IIC control */ + uint32_t IC_TAR; /*!< (0x04) : IIC target address */ + uint32_t IC_SAR; /*!< (0x08) : IIC slave address */ + uint32_t IC_HS_MADDR; /*!< (0x0c) : IIC HS Master Mode Code address */ + uint32_t IC_DATA_CMD; /*!< (0x10) : IIC Rx/Tx Data Buffer and Command */ + uint32_t IC_SS_SCL_HCNT; /*!< (0x14) : Standard Speed IIC clock SCL High Count */ + uint32_t IC_SS_SCL_LCNT; /*!< (0x18) : Standard Speed IIC clock SCL Low Count */ + uint32_t IC_FS_SCL_HCNT; /*!< (0x1c) : Fast Speed IIC clock SCL Low Count */ + uint32_t IC_FS_SCL_LCNT; /*!< (0x20) : Fast Speed IIC clock SCL Low Count */ + uint32_t IC_HS_SCL_HCNT; /*!< (0x24) : High Speed IIC clock SCL Low Count */ + uint32_t IC_HS_SCL_LCNT; /*!< (0x28) : High Speed IIC clock SCL Low Count */ + uint32_t IC_INTR_STAT; /*!< (0x2c) : IIC Interrupt Status */ + uint32_t IC_INTR_MASK; /*!< (0x30) : IIC Interrupt Mask */ + uint32_t IC_RAW_INTR_STAT; /*!< (0x34) : IIC Raw Interrupt Status */ + uint32_t IC_RX_TL; /*!< (0x38) : IIC Receive FIFO Threshold */ + uint32_t IC_TX_TL; /*!< (0x3c) : IIC Transmit FIFO Threshold */ + uint32_t IC_CLR_INTR; /*!< (0x40) : Clear combined and Individual Interrupts */ + uint32_t IC_CLR_RX_UNDER; /*!< (0x44) : Clear RX_UNDER Interrupt */ + uint32_t IC_CLR_RX_OVER; /*!< (0x48) : Clear RX_OVER Interrupt */ + uint32_t IC_CLR_TX_OVER; /*!< (0x4c) : Clear TX_OVER Interrupt */ + uint32_t IC_CLR_RD_REQ; /*!< (0x50) : Clear RQ_REQ Interrupt */ + uint32_t IC_CLR_TX_ABRT; /*!< (0x54) : Clear TX_ABRT Interrupt */ + uint32_t IC_CLR_RX_DONE; /*!< (0x58) : Clear RX_DONE Interrupt */ + uint32_t IC_CLR_ACTIVITY; /*!< (0x5c) : Clear ACTIVITY Interrupt */ + uint32_t IC_CLR_STOP_DET; /*!< (0x60) : Clear STOP_DET Interrupt */ + uint32_t IC_CLR_START_DET; /*!< (0x64) : Clear START_DET Interrupt */ + uint32_t IC_CLR_GEN_CALL; /*!< (0x68) : Clear GEN_CALL Interrupt */ + uint32_t IC_ENABLE; /*!< (0x6c) : IIC Enable */ + uint32_t IC_STATUS; /*!< (0x70) : IIC Status */ + uint32_t IC_TXFLR; /*!< (0x74) : Transmit FIFO Level Register */ + uint32_t IC_RXFLR; /*!< (0x78) : Receive FIFO Level Register */ + uint32_t IC_SDA_HOLD; /*!< (0x7c) : SDA Hold Time Length Reg */ + uint32_t IC_TX_ABRT_SOURCE; /*!< (0x80) : IIC Transmit Abort Status Reg */ + uint32_t IC_SLV_DATA_NACK_ONLY; /*!< (0x84) : Generate SLV_DATA_NACK Register */ + uint32_t IC_DMA_CR; /*!< (0x88) : DMA Control Register */ + uint32_t IC_DMA_TDLR; /*!< (0x8c) : DMA Transmit Data Level */ + uint32_t IC_DMA_RDLR; /*!< (0x90) : DMA Receive Data Level */ + uint32_t IC_SDA_SETUP; /*!< (0x94) : SDA Setup Register */ + uint32_t IC_ACK_GENERAL_CALL; /*!< (0x98) : ACK General Call Register */ + uint32_t IC_ENABLE_STATUS; /*!< (0x9c) : Enable Status Register */ + uint32_t IC_FS_SPKLEN; /*!< (0xa0) : ISS and FS spike suppression limit */ + uint32_t IC_HS_SPKLEN; /*!< (0xa4) : HS spike suppression limit */ + uint32_t RESERVED[19]; /*!< (0xa8) : Reserved */ + uint32_t IC_COMP_PARAM_1; /*!< (0xf4) : Component Parameter Register */ + uint32_t IC_COMP_VERSION; /*!< (0xf8) : Component Version ID Reg */ + uint32_t IC_COMP_TYPE; /*!< (0xfc) : Component Type Reg */ +} DW_IIC_REG, *DW_IIC_REG_PTR; +/** @} */ + +/** Spike Suppression Limit Configurations */ +typedef struct dw_iic_spklen { + uint32_t fs_spklen; /*!< value for IC_FS_SPKLEN, Tsp for fast mode is 50ns */ + uint32_t hs_spklen; /*!< value for IC_HS_SPKLEN, Tsp for high-speed mode is 10ns */ +} DW_IIC_SPKLEN, *DW_IIC_SPKLEN_PTR; + +/** IIC Clock SCL High and Low Count Configurations for Different Speed */ +typedef struct dw_iic_scl_cnt { + uint32_t ss_scl_hcnt; /*!< value for IC_SS_SCL_HCNT */ + uint32_t ss_scl_lcnt; /*!< value for IC_SS_SCL_LCNT */ + uint32_t fs_scl_hcnt; /*!< value for IC_FS_SCL_HCNT */ + uint32_t fs_scl_lcnt; /*!< value for IC_FS_SCL_LCNT */ + uint32_t hs_scl_hcnt; /*!< value for IC_HS_SCL_HCNT */ + uint32_t hs_scl_lcnt; /*!< value for IC_HS_SCL_LCNT */ +} DW_IIC_SCL_CNT, *DW_IIC_SCL_CNT_PTR; + +#define DW_IIC_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */ +#define DW_IIC_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */ +#define DW_IIC_TXINT_ENABLE (1<<1) /*!< designware interrupt enabled for control transmit process */ +#define DW_IIC_RXINT_ENABLE (1<<2) /*!< designware interrupt enabled for control transmit process */ + +typedef struct dw_iic_buffer { + DEV_BUFFER *buf; + uint32_t ofs; + uint32_t len; +} DW_IIC_BUFFER, *DW_IIC_BUFFER_PTR; + +/** + * \brief DesignWare IIC control structure definition + * \details implement of dev_iic_info::iic_ctrl + */ +typedef struct dw_iic_ctrl { + DW_IIC_REG *dw_iic_regs; /*!< iic device registers */ + /* Variables which should be set during object implementation */ + uint32_t support_modes; /*!< supported iic modes */ + uint32_t tx_fifo_len; /*!< transmit fifo length */ + uint32_t rx_fifo_len; /*!< receive fifo length */ + uint32_t iic_master_code; /*!< value for IC_HS_MADDR */ + uint32_t retry_cnt; /*!< retry count for TX or RX */ + uint32_t intno; /*!< iic interrupt vector number */ + INT_HANDLER dw_iic_int_handler; /*!< iic interrupt handler */ + DW_IIC_SPKLEN iic_spklen; /*!< iic spike suppression length settings */ + DW_IIC_SCL_CNT iic_scl_cnt; /*!< iic scl count settings */ + /* Variables which always change during iic operation */ + uint32_t int_status; /*!< iic interrupt status */ + uint32_t iic_tx_over; /*!< iic tx overflow count */ + uint32_t iic_rx_over; /*!< iic rx overflow count */ + DW_IIC_BUFFER dw_iic_rxbuf; /*!< iic read buffer for receive data */ +} DW_IIC_CTRL, *DW_IIC_CTRL_PTR; + +/*!< One possible value for \ref dw_iic_ctrl::retry_cnt */ +#define DW_IIC_MAX_RETRY_COUNT (100000) + +#if DW_IIC_USE_IC_CLK_MHZ == 100 /*!< 100MHz */ +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; + +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +#if DW_IIC_USE_HS_BUS_LOADING_100PF +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10}; +#else +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20}; +#endif + +#elif DW_IIC_USE_IC_CLK_MHZ == 50 /* 50MHz */ +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; + +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +#if DW_IIC_USE_HS_BUS_LOADING_100PF +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x8}; +#else +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x10}; +#endif + +#else /* Default 100MHz */ +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; + +/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ +#if DW_IIC_USE_HS_BUS_LOADING_100PF +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10}; +#else +static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20}; +#endif + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup DEVICE_DW_IIC_FUNCDLR DesignWare IIC Function Declaration + * \ingroup DEVICE_DW_IIC + * \brief Contains declarations of designware iic functions. + * \details This are only used in iic object implementation source file + * @{ + */ +extern int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param); +extern int32_t dw_iic_close (DEV_IIC *iic_obj); +extern int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param); +extern int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len); +extern int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len); +extern void dw_iic_isr(DEV_IIC *iic_obj, void *ptr); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* _DW_IIC_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h new file mode 100644 index 0000000000..f7ec0d27a2 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h @@ -0,0 +1,186 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-30 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_IIC + * \brief DesignWare IIC driver hardware description related header file + * \details detailed hardware related definitions of DesignWare IIC driver + */ + +#ifndef _DEVICE_DW_IIC_HAL_H_ +#define _DEVICE_DW_IIC_HAL_H_ + +#include "device/designware/iic/dw_iic_hal_cfg.h" + +/** Enable Designware IIC */ +#define DW_IIC_ENABLE (1) +/** Disable Designware IIC */ +#define DW_IIC_DISABLE (0) + +/** Stop Condition issue after this byte */ +#define IC_DATA_CMD_STOP (1 << 9) +/** Restart Condition issue after this byte */ +#define IC_DATA_CMD_RESTART (1 << 10) +/** No Restart or stop condition after this byte */ +#define IC_DATA_CMD_NONE (0) + +/** Perform a write request */ +#define IC_DATA_CMD_WRITE_REQ (0) +/** Perform a read request */ +#define IC_DATA_CMD_READ_REQ (1 << 8) + +/** Fields of IC_CON register */ +/* DW_APB I2C IP Config Dependencies. */ +#if DW_IIC_ALLOW_RESTART +#define IC_CON_RESTART_EN (1 << 5) +#else +#define IC_CON_RESTART_EN (0x00) +#endif + +/* Master Addressing Mode Config */ +#if DW_IIC_MST_10_BIT_ADDR_SUPPORT +#define MST_10_BIT_ADDR_MODE (1 << 4) +#define IC_10BITADDR_MASTER (1 << 12) +#else +#define MST_10_BIT_ADDR_MODE (0x00) +#define IC_10BITADDR_MASTER (0x00) +#endif + +/* Slave Addressing Mode Config */ +#if DW_IIC_SLV_10_BIT_ADDR_SUPPORT +#define SLV_10_BIT_ADDR_MODE (1 << 3) +#else +#define SLV_10_BIT_ADDR_MODE (0x00) +#endif + +#if DW_IIC_SPECIAL_START_BYTE +#define IC_TAR_SPECIAL (1 << 11) +#define IC_TAR_GC_OR_START (1 << 10) +#else +#define IC_TAR_SPECIAL (0x00) +#define IC_TAR_GC_OR_START (0x00) +#endif + +/** 7bit IIC address mask for target address register */ +#define IC_TAR_7BIT_ADDR_MASK (0x7F) +/** 7bit IIC address mask for slave address register */ +#define IC_SAR_7BIT_ADDR_MASK (0x7F) +/** 10bit IIC address mask for target address register */ +#define IC_TAR_10BIT_ADDR_MASK (0x3FF) +/** 10bit IIC address mask for slave address register */ +#define IC_SAR_10BIT_ADDR_MASK (0x3FF) + +/** Speed modes of IC_CON */ +#define IC_CON_SPEED_MASK (0x6) +#define IC_CON_SPEED_STANDARD (0x2) +#define IC_CON_SPEED_FAST (0x4) +#define IC_CON_SPEED_HIGH (0x6) +/** Working mode of IC_CON */ +#define IC_CON_MST_SLV_MODE_MASK (0x41) +#define IC_CON_ENA_MASTER_MODE (0x41) +#define IC_CON_ENA_SLAVE_MODE (0) + +/* IIC interrupt control */ +#define IC_INT_DISABLE_ALL (0x0) +#define IC_INT_ENABLE_ALL (0x7FF) +/* Interrupt Register Fields */ +#define IC_INTR_STAT_GEN_CALL (1 << 11) +#define IC_INTR_STAT_START_DET (1 << 10) +#define IC_INTR_STAT_STOP_DET (1 << 9) +#define IC_INTR_STAT_ACTIVITY (1 << 8) +#define IC_INTR_STAT_RX_DONE (1 << 7) +#define IC_INTR_STAT_TX_ABRT (1 << 6) +#define IC_INTR_STAT_RD_REQ (1 << 5) +#define IC_INTR_STAT_TX_EMPTY (1 << 4) +#define IC_INTR_STAT_TX_OVER (1 << 3) +#define IC_INTR_STAT_RX_FULL (1 << 2) +#define IC_INTR_STAT_RX_OVER (1 << 1) +#define IC_INTR_STAT_RX_UNDER (1 << 0) + +/* Interrupt enable mask as master */ +#define IC_INT_MST_TX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_TX_OVER|IC_INTR_STAT_TX_ABRT) +#define IC_INT_MST_RX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER|IC_INTR_STAT_TX_ABRT) + +/* Interrupt enable mask as master */ +#define IC_INT_SLV_COMMON_ENABLE (IC_INTR_STAT_START_DET|IC_INTR_STAT_STOP_DET) +#define IC_INT_SLV_TX_ENABLE (IC_INTR_STAT_RD_REQ|IC_INTR_STAT_TX_ABRT) +#define IC_INT_SLV_RX_ENABLE (IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER) + +/* IC_ENABLE_STATUS Bits */ +#define IC_ENABLE_STATUS_IC_EN (1 << 0) +#define IC_ENABLE_STATUS_SLV_DIS (1 << 1) +#define IC_ENABLE_STATUS_SLV_RX_LOST (1 << 2) + +/* IIC TX & RX threshold settings */ +#define IIC_TX_THRESHOLD (0) +#define IIC_RX_THRESHOLD (0) + +/* DW_APB IIC (DW_IC_STATUS) Status Register Fields. */ +#define IC_STATUS_ACTIVITY (0x01) +#define IC_STATUS_TFNF (0x02) /* (1 << 1) */ +#define IC_STATUS_TFE (0x04) /* (1 << 2) */ +#define IC_STATUS_RFNE (0x08) /* (1 << 3) */ +#define IC_STATUS_RFF (0x10) /* (1 << 4) */ +#define IC_STATUS_MASTER_ACT (0x20) /* (1 << 5) */ +#define IC_STATUS_SLAVE_ACT (0x40) /* (1 << 6) */ + +/* IC_TX_ABRT_SOURCE Register Bit Fields */ +#define IC_TX_ABRT_7B_ADDR_NOACK (1 << 0) +#define IC_TX_ABRT_10ADDR1_NOACK (1 << 1) +#define IC_TX_ABRT_10ADDR2_NOACK (1 << 2) +#define IC_TX_ABRT_TXDATA_NOACK (1 << 3) +#define IC_TX_ABRT_GCALL_NOACK (1 << 4) +#define IC_TX_ABRT_GCALL_READ (1 << 5) +#define IC_TX_ABRT_HS_ACKDET (1 << 6) +#define IC_TX_ABRT_SBYTE_ACKDET (1 << 7) +#define IC_TX_ABRT_HS_NORSTRT (1 << 8) +#define IC_TX_ABRT_SBYTE_NORSTRT (1 << 9) +#define IC_TX_ABRT_10B_RD_NORSTRT (1 << 10) +#define IC_TX_ABRT_MASTER_DIS (1 << 11) +#define IC_TX_ABRT_ARB_LOST (1 << 12) +#define IC_TX_ABRT_SLVFLUSH_TXFIFO (1 << 13) +#define IC_TX_ABRT_SLV_ARBLOST (1 << 14) +#define IC_TX_ABRT_SLVRD_INTX (1 << 15) + +/* Combined bits for iic abort source as master */ +#define IIC_MST_ABRT_ADDR_NOACK (IC_TX_ABRT_7B_ADDR_NOACK|IC_TX_ABRT_10ADDR1_NOACK|IC_TX_ABRT_10ADDR1_NOACK) +#define IIC_MST_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST) +#define IIC_MST_ABRT_DATA_NOACK (IC_TX_ABRT_TXDATA_NOACK) + +/* Combined bits for iic abort source as slave */ +#define IIC_SLV_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST|IC_TX_ABRT_SLV_ARBLOST) + +/** @} */ + +#endif /* _DEVICE_DW_IIC_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h new file mode 100644 index 0000000000..1073162176 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h @@ -0,0 +1,82 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-07-01 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_IIC + * \brief DesignWare IIC driver hardware description + * related header file configuration file + * \details configuration file to enable or disable some function of iic + */ + +#ifndef _DEVICE_DW_IIC_HAL_CFG_H_ +#define _DEVICE_DW_IIC_HAL_CFG_H_ + +#ifndef DW_IIC_ALLOW_RESTART +#define DW_IIC_ALLOW_RESTART (1) /*!< allow restart configuration */ +#endif + +#ifdef DW_IIC_SPECIAL_START_BYTE +#define DW_IIC_SPECIAL_START_BYTE (0) /*!< SPECIAL bit enable in IC_TAR */ +#endif + +#ifndef DW_IIC_MST_10_BIT_ADDR_SUPPORT +#define DW_IIC_MST_10_BIT_ADDR_SUPPORT (1) /*!< enable 10-bit address mode */ +#endif + +#ifdef DW_IIC_SLV_10_BIT_ADDR_SUPPORT +#define DW_IIC_SLV_10_BIT_ADDR_SUPPORT (1) /*!< slave 10-bit addressing mode */ +#endif + +#ifndef DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT +#define DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT (0) /*!< Dynamic target address update support */ +#endif + +#ifndef DW_IIC_DISABLE_MAX_T_POLL_CNT +#define DW_IIC_DISABLE_MAX_T_POLL_CNT (1250) /*!< Timeout count, approximate to be 25us in 50MHz CPU @ Standard mode */ +#endif + +#ifndef DW_IIC_CALC_FIFO_LEN_ENABLE +#define DW_IIC_CALC_FIFO_LEN_ENABLE (1) /*!< Default enable calculate fifo length */ +#endif + +#ifndef DW_IIC_USE_IC_CLK_MHZ +#define DW_IIC_USE_IC_CLK_MHZ (50) /*!< Default use 50MHz IC_CLK */ +#endif + +#ifndef DW_IIC_USE_HS_BUS_LOADING_100PF +#define DW_IIC_USE_HS_BUS_LOADING_100PF (1) /*!< Use bus loading 100pf */ +#endif + +#endif /* _DEVICE_DW_IIC_HAL_CFG_H_ */ + diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi.c b/bsp/synopsys/embarc/device/designware/spi/dw_spi.c new file mode 100644 index 0000000000..bea413b411 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/spi/dw_spi.c @@ -0,0 +1,1337 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-25 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_DW_SPI Designware SPI Driver + * \ingroup DEVICE_DW + * \brief Designware SPI Driver Implementation + */ + +/** + * \file + * \brief DesignWare SPI driver implementation based on device hal layer definition (\ref dev_spi.h) + * \ingroup DEVICE_DW_SPI + */ +#include + +#include "inc/embARC_toolchain.h" +#include "inc/embARC_error.h" + +#include "inc/arc/arc_exception.h" + +#include "device/designware/spi/dw_spi_hal.h" +#include "device/designware/spi/dw_spi.h" + +/** + * \defgroup DEVICE_DW_SPI_DEFINES DesignWare SPI Driver Macros + * \ingroup DEVICE_DW_SPI + * \brief DesignWare SPI driver macros used in spi driver + * @{ + */ +/** check expressions used in DesignWare SPI driver implementation */ +#define DW_SPI_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) + +/** convert DesignWare frequence to divisor */ +#define DW_SPI_FREQ2DV(perifreq, spifreq) ((perifreq) / (spifreq)) + +#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK +/** valid check of spi info object */ +#define VALID_CHK_SPI_INFO_OBJECT(spiinfo_obj_ptr) { \ + DW_SPI_CHECK_EXP((spiinfo_obj_ptr)!=NULL, E_OBJ); \ + DW_SPI_CHECK_EXP(((spiinfo_obj_ptr)->spi_ctrl)!=NULL, E_OBJ); \ + } +#endif + +/** + * \defgroup DEVICE_DW_SPI_DEF_CBR DesignWare SPI Interrupt Callback Routine Select Marcos + * \ingroup DEVICE_DW_SPI_DEFINES + * \brief DesignWare SPI interrupt callback routines select macros definitions + * @{ + */ +#define DW_SPI_RDY_SND (1U) /*!< ready to send callback */ +#define DW_SPI_RDY_RCV (2U) /*!< ready to receive callback */ +#define DW_SPI_RDY_XFER (3U) /*!< ready to transfer callback */ +/** @} */ + +/** @} */ + +/** + * \defgroup DEVICE_DW_SPI_STATIC DesignWare SPI Driver Static Functions + * \ingroup DEVICE_DW_SPI + * \brief Static or inline functions, variables for DesignWare SPI handle spi operations, + * only used in this file. + * @{ + */ + +/** Disable designware spi device */ +Inline void dw_spi_disable(DW_SPI_REG *spi_reg_ptr) +{ +/** disable spi operations, then program spi control regs is possible */ + spi_reg_ptr->SSIENR = DW_SPI_SSI_DISABLE; +} +/** Enable designware spi device */ +Inline void dw_spi_enable(DW_SPI_REG *spi_reg_ptr) +{ + spi_reg_ptr->SSIENR = DW_SPI_SSI_ENABLE; +} + +/** Clear all designware spi interrupt */ +Inline void dw_spi_clear_interrupt_all(DW_SPI_REG *spi_reg_ptr) +{ + (void)spi_reg_ptr->ICR; +} + +/** test whether spi is busy, busy return 1, else 0 */ +Inline int32_t dw_spi_busy(DW_SPI_REG *spi_reg_ptr) +{ + return ((spi_reg_ptr->SR & DW_SPI_SR_BUSY) != 0); +} +/** test whether spi is ready to send, 1 ready, 0 not ready */ +Inline int32_t dw_spi_putready(DW_SPI_REG *spi_reg_ptr) +{ + return ((spi_reg_ptr->SR & DW_SPI_SR_TFNF) != 0); +} +/** test whether spi is read to receive, 1 ready, 0 not ready */ +Inline int32_t dw_spi_getready(DW_SPI_REG *spi_reg_ptr) +{ + return ((spi_reg_ptr->SR & DW_SPI_SR_RFNE) != 0); +} +/** write data to spi send fifo */ +Inline void dw_spi_putdata(DW_SPI_REG *spi_reg_ptr, int32_t data) +{ + spi_reg_ptr->DATAREG = (uint32_t)data; +} +/** read data from spi receive fifo, return data received */ +Inline int32_t dw_spi_getdata(DW_SPI_REG *spi_reg_ptr) +{ + return (int32_t)spi_reg_ptr->DATAREG; +} +/** + * \brief send data by spi when available, + * mostly used in interrupt method, non-blocked function + * \param[in] spi_reg_ptr spi register structure pointer + * \param[in] data data to be sent + * \retval E_OK send successfully + * \retval E_OBJ not ready to send data + */ +Inline int32_t dw_spi_snd_dat(DW_SPI_REG *spi_reg_ptr, int32_t data) +{ + if (dw_spi_putready(spi_reg_ptr)) { + dw_spi_putdata(spi_reg_ptr, data); + return E_OK; + } + return E_OBJ; +} +/** + * \brief receive one char from spi, + * mostly used in interrupt routine, non-blocked function + * \param[in] spi_reg_ptr spi register structure pointer + * \return data received by the spi + */ +Inline int32_t dw_spi_rcv_dat(DW_SPI_REG *spi_reg_ptr) +{ + return dw_spi_getdata(spi_reg_ptr); +} +/** + * \brief send char by spi in poll method, blocked function + * \param[in] spi_reg_ptr spi register structure pointer + * \param[in] data data to be sent + */ +Inline void dw_spi_psnd_dat(DW_SPI_REG *spi_reg_ptr, int32_t data) +{ + /** wait until spi is ready to send */ + while (!dw_spi_putready(spi_reg_ptr)); /* blocked */ + /** send char */ + dw_spi_putdata(spi_reg_ptr, data); +} +/** + * \brief receive one char from spi in poll method, blocked function + * \param[in] spi_reg_ptr spi register structure pointer + * \return data received by the spi + */ +Inline int32_t dw_spi_prcv_dat(DW_SPI_REG *spi_reg_ptr) +{ + /** wait until spi is ready to receive */ + while (!dw_spi_getready(spi_reg_ptr)); /* blocked */ + /** receive data */ + return dw_spi_getdata(spi_reg_ptr); +} + +/** Reset designware FIFO by disable spi device, then enable device */ +Inline void dw_spi_reset_fifo(DW_SPI_REG *spi_reg_ptr) +{ + dw_spi_disable(spi_reg_ptr); + dw_spi_enable(spi_reg_ptr); +} + +/** Enable designware spi bit interrupt with mask */ +Inline void dw_spi_unmask_interrupt(DW_SPI_REG *spi_reg_ptr, uint32_t mask) +{ + spi_reg_ptr->IMR |= mask; +} + +/** Disable designware spi bit interrupt with mask */ +Inline void dw_spi_mask_interrupt(DW_SPI_REG *spi_reg_ptr, uint32_t mask) +{ + spi_reg_ptr->IMR &= ~mask; +} + +/** Set designware spi device frequency */ +Inline void dw_spi_set_freq(DW_SPI_CTRL *spi_ctrl_ptr, uint32_t freq) +{ + uint32_t sck_divisor; + DW_SPI_REG *spi_reg_ptr = spi_ctrl_ptr->dw_spi_regs; + + dw_spi_disable(spi_reg_ptr); + + sck_divisor = DW_SPI_FREQ2DV(spi_ctrl_ptr->dw_apb_bus_freq, freq); + spi_reg_ptr->BAUDR = sck_divisor; + dw_spi_enable(spi_reg_ptr); +} + +/** Set designware spi device data frame size */ +static int32_t dw_spi_set_dfs(DW_SPI_REG *spi_reg_ptr, uint32_t dfs) +{ + uint32_t ctrl0_reg; + if ((dfs <= 3) || (dfs > 16)) return -1; + + dw_spi_disable(spi_reg_ptr); + ctrl0_reg = spi_reg_ptr->CTRLR0; + ctrl0_reg &= ~(DW_SPI_CTRLR0_DFS_MASK); + spi_reg_ptr->CTRLR0 = ctrl0_reg | (dfs-1); + dw_spi_enable(spi_reg_ptr); + + return 0; +} + +/** Choose proper designware spi clock mode setting value */ +Inline uint32_t dw_spi_select_clockmode(uint32_t clk_mode) +{ + return (clk_mode << DW_SPI_CTRLR0_SC_OFS); +} + +/** Set designware spi clock mode */ +Inline int32_t dw_spi_set_clockmode(DW_SPI_REG *spi_reg_ptr, uint32_t clk_mode) +{ + if (clk_mode > SPI_CPOL_1_CPHA_1) { + return -1; + } + dw_spi_disable(spi_reg_ptr); + spi_reg_ptr->CTRLR0 &= ~(DW_SPI_CTRLR0_SC_MASK); + spi_reg_ptr->CTRLR0 |= dw_spi_select_clockmode(clk_mode); + dw_spi_enable(spi_reg_ptr); + return 0; +} + +/** Select a spi slave with slv_line */ +Inline int32_t dw_spi_select_slave(DW_SPI_REG *spi_reg_ptr, uint32_t slv_line) +{ + /* check if spi busy */ + if (dw_spi_busy(spi_reg_ptr)) return -1; + + spi_reg_ptr->SER = 1<SER = 0; + return 0; +} + +Inline void dw_spi_flush_tx(DW_SPI_REG *spi_reg_ptr) +{ + dw_spi_reset_fifo(spi_reg_ptr); +} + +Inline void dw_spi_flush_rx(DW_SPI_REG *spi_reg_ptr) +{ + dw_spi_reset_fifo(spi_reg_ptr); +} + +/** Get TX FIFO Length. + * calculate spi fifo length using fifo threshold method + * If you attempt to set bits [7:0] of this register to + * a value greater than or equal to the depth of the FIFO, + * this field is not written and retains its current value. + */ +static uint32_t dw_spi_get_txfifo_len(DW_SPI_REG *spi_reg_ptr) +{ + uint32_t fifo_thr_lev_tmp, left, right, i; + + fifo_thr_lev_tmp = spi_reg_ptr->TXFTLR; + + if (fifo_thr_lev_tmp != 0) { + left = fifo_thr_lev_tmp; + } else { + left = DW_SPI_MIN_FIFO_LENGTH; + } + right = DW_SPI_MAX_FIFO_LENGTH + 1; + + for (i = left; i <= right; i++) { + spi_reg_ptr->TXFTLR = i; + if (spi_reg_ptr->TXFTLR != i) { + break; + } + } + spi_reg_ptr->TXFTLR = fifo_thr_lev_tmp; /* restore old fifo threshold */ + + return (i); +} + +/** Get RX FIFO Length */ +static uint32_t dw_spi_get_rxfifo_len(DW_SPI_REG *spi_reg_ptr) +{ + uint32_t fifo_thr_lev_tmp, left, right, i; + + fifo_thr_lev_tmp = spi_reg_ptr->RXFTLR; + + if (fifo_thr_lev_tmp != 0) { + left = fifo_thr_lev_tmp; + } else { + left = DW_SPI_MIN_FIFO_LENGTH; + } + right = DW_SPI_MAX_FIFO_LENGTH + 1; + + for (i = left; i <= right; i++) { + spi_reg_ptr->RXFTLR = i; + if (spi_reg_ptr->RXFTLR != i) { + break; + } + } + spi_reg_ptr->RXFTLR = fifo_thr_lev_tmp; /* restore old fifo threshold */ + + return (i); +} + +/** Init Designware SPI Hardware */ +static void dw_spi_hw_init(DW_SPI_CTRL *spi_ctrl_ptr, uint32_t clk_mode, uint32_t dfs) +{ + uint32_t ctrl0_reg = 0; + DW_SPI_REG *spi_reg_ptr = spi_ctrl_ptr->dw_spi_regs; + + dw_spi_disable(spi_reg_ptr); + + /* Clear interrupts */ + ctrl0_reg = spi_reg_ptr->ICR; + /* Mask all interrupts */ + spi_reg_ptr->IMR = 0; + + ctrl0_reg = DW_SPI_CTRLR0_FRF_MOTOROLA | DW_SPI_TMOD_TRANSMIT_RECEIVE \ + | dw_spi_select_clockmode(clk_mode) | (dfs - 1) | DW_SPI_CTRLR0_SLV_OE_ENABLE; + spi_reg_ptr->CTRLR0 = ctrl0_reg; + spi_reg_ptr->CTRLR1 = 0; + + /* deselect slaves */ + spi_reg_ptr->SER = 0; + + /* Set threshold values for both tx and rx */ + spi_reg_ptr->TXFTLR = 0; + spi_reg_ptr->RXFTLR = 0; + + dw_spi_enable(spi_reg_ptr); +} + +/** enable designware spi */ +static void dw_spi_enable_device(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + + if ((spi_info_ptr->status & DEV_ENABLED) == 0) { + dw_spi_enable(spi_reg_ptr); + spi_info_ptr->status |= DEV_ENABLED; + } +} + +/** disable designware spi */ +static void dw_spi_disable_device(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + + dw_spi_disable(spi_reg_ptr); + spi_info_ptr->status &= ~DEV_ENABLED; +} + + +/** + * \brief disable designware spi send or receive interrupt + * \param[in] DEV_SPI_INFO *spi_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static int32_t dw_spi_dis_cbr(DEV_SPI_INFO *spi_info_ptr, uint32_t cbrtn) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + int32_t ercd = E_OK; + + if ((spi_info_ptr->status & DW_SPI_IN_XFER) != 0) { /* only in transfer need do check */ + switch (cbrtn) { + case DW_SPI_RDY_SND: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX, E_CTX); + spi_info_ptr->status &= ~(DW_SPI_IN_TX); + break; + case DW_SPI_RDY_RCV: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX, E_CTX); + spi_info_ptr->status &= ~(DW_SPI_IN_RX); + break; + case DW_SPI_RDY_XFER: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER, E_CTX); + spi_info_ptr->status &= ~(DW_SPI_IN_XFER); + break; + default: + break; + } + } + + dw_spi_mask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); + + if (spi_ctrl_ptr->int_status & DW_SPI_GINT_ENABLE) { + int_disable(spi_ctrl_ptr->intno); + spi_ctrl_ptr->int_status &= ~DW_SPI_GINT_ENABLE; + } + +error_exit: + return ercd; +} + +/** + * \brief enable DesignWare SPI send or receive interrupt + * \param[in] DEV_SPI_INFO *spi_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static int32_t dw_spi_ena_cbr(DEV_SPI_INFO *spi_info_ptr, uint32_t cbrtn) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + int32_t ercd = E_OK; + + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == 0, E_CTX); + switch (cbrtn) { + case DW_SPI_RDY_SND: + spi_info_ptr->status |= DW_SPI_IN_TX; + break; + case DW_SPI_RDY_RCV: + spi_info_ptr->status |= DW_SPI_IN_RX; + break; + case DW_SPI_RDY_XFER: + spi_info_ptr->status |= DW_SPI_IN_XFER; + break; + default: + break; + } + dw_spi_unmask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); + + if ((spi_ctrl_ptr->int_status & DW_SPI_GINT_ENABLE) == 0) { + spi_ctrl_ptr->int_status |= DW_SPI_GINT_ENABLE; + int_enable(spi_ctrl_ptr->intno); + } + +error_exit: + return ercd; +} + +/** + * \brief enable designware spi interrupt + * \param spi_info_ptr spi information structure pointer + */ +static void dw_spi_enable_interrupt(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + + int_handler_install(spi_ctrl_ptr->intno, spi_ctrl_ptr->dw_spi_int_handler); + spi_ctrl_ptr->int_status |= DW_SPI_GINT_ENABLE; + int_enable(spi_ctrl_ptr->intno); /** enable spi interrupt */ +} +/** + * \brief disable designware spi interrupt + * \param spi_info_ptr spi information structure pointer + */ +static void dw_spi_disable_interrupt(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + + /** disable spi send&receive interrupt after disable spi interrupt */ + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); + /* disable spi interrupt */ + dw_spi_mask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); + spi_info_ptr->status &= ~DW_SPI_IN_XFER; + int_disable(spi_ctrl_ptr->intno); + spi_ctrl_ptr->int_status &= ~(DW_SPI_GINT_ENABLE); +} + +static void dw_spi_reset_device(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + + dw_spi_disable_device(spi_info_ptr); + dw_spi_disable_interrupt(spi_info_ptr); + dw_spi_clear_interrupt_all(spi_reg_ptr); + dw_spi_enable_device(spi_info_ptr); +} + +/** abort current interrupt transmit transfer */ +static int32_t dw_spi_abort_tx(DEV_SPI *spi_obj) +{ + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + int32_t ercd = E_OK; + + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX, E_CTX); + + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); + spi_info_ptr->status |= DEV_IN_TX_ABRT; + if (spi_info_ptr->spi_cbs.tx_cb != NULL) { + spi_info_ptr->spi_cbs.tx_cb(spi_obj); + } + spi_info_ptr->status &= ~(DEV_IN_TX_ABRT); + +error_exit: + return ercd; +} + +/** abort current interrupt receive transfer */ +static int32_t dw_spi_abort_rx(DEV_SPI *spi_obj) +{ + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + int32_t ercd = E_OK; + + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX, E_CTX); + + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); + spi_info_ptr->status |= DEV_IN_RX_ABRT; + if (spi_info_ptr->spi_cbs.rx_cb != NULL) { + spi_info_ptr->spi_cbs.rx_cb(spi_obj); + } + spi_info_ptr->status &= ~(DEV_IN_RX_ABRT); + +error_exit: + return ercd; +} + +/** abort current interrupt transfer */ +static int32_t dw_spi_abort_xfer(DEV_SPI *spi_obj) +{ + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + int32_t ercd = E_OK; + + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER, E_CTX); + + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); + spi_info_ptr->status |= DEV_IN_XFER_ABRT; + if (spi_info_ptr->spi_cbs.xfer_cb != NULL) { + spi_info_ptr->spi_cbs.xfer_cb(spi_obj); + } + spi_info_ptr->status &= ~(DEV_IN_XFER_ABRT); + +error_exit: + return ercd; +} + +/** Get available transmit fifo count */ +static int32_t dw_spi_get_txavail(DW_SPI_CTRL *spi_ctrl_ptr) +{ + int32_t tx_avail = 0; + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + +#if DW_SPI_CALC_FIFO_LEN_ENABLE + if (spi_ctrl_ptr->tx_fifo_len <= 1) { + if (dw_spi_putready(spi_reg_ptr) == 1) { + tx_avail = 1; + } else { + tx_avail = 0; + } + } else +#endif + { + tx_avail = spi_ctrl_ptr->tx_fifo_len - spi_reg_ptr->TXFLR; + } + return tx_avail; +} + +/** Get available receive fifo count */ +static int32_t dw_spi_get_rxavail(DW_SPI_CTRL *spi_ctrl_ptr) +{ + int32_t rx_avail = 0; + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + +#if DW_SPI_CALC_FIFO_LEN_ENABLE + if (spi_ctrl_ptr->rx_fifo_len <= 1) { + if (dw_spi_getready(spi_reg_ptr) == 1) { + rx_avail = 1; + } else { + rx_avail = 0; + } + } else +#endif + { + rx_avail = spi_reg_ptr->RXFLR; + } + return rx_avail; +} + +static uint32_t dw_spi_tx_max(DW_SPI_CTRL *spi_ctrl_ptr) +{ + uint32_t tx_left, tx_room; + DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); + + tx_left = (xfer->xfer_len - xfer->tx_idx) / xfer->nbytes; + tx_room = dw_spi_get_txavail(spi_ctrl_ptr); + + return (tx_left < tx_room) ? tx_left : tx_room; +} + +static uint32_t dw_spi_rx_max(DW_SPI_CTRL *spi_ctrl_ptr) +{ + uint32_t rx_left, rx_room; + DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); + + rx_left = (xfer->xfer_len - xfer->rx_idx) / xfer->nbytes; + rx_room = dw_spi_get_rxavail(spi_ctrl_ptr); + + return (rx_left < rx_room) ? rx_left : rx_room; +} + +Inline int32_t dw_spi_rx_end(DW_SPI_CTRL *spi_ctrl_ptr) +{ + DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); + + return (xfer->rx_idx >= xfer->xfer_len); +} + +Inline int32_t dw_spi_tx_end(DW_SPI_CTRL *spi_ctrl_ptr) +{ + DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); + + return (xfer->tx_idx >= xfer->xfer_len); +} + +/** 1 for end, 0 for not end */ +Inline int32_t dw_spi_xfer_end(DW_SPI_CTRL *spi_ctrl_ptr) +{ + return (dw_spi_tx_end(spi_ctrl_ptr) && dw_spi_rx_end(spi_ctrl_ptr)); +} + +static int32_t dw_spi_writer(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + DW_SPI_TRANSFER *dw_xfer = &(spi_ctrl_ptr->dw_xfer); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + uint32_t tx_max = dw_spi_tx_max(spi_ctrl_ptr); + int32_t tx_w; + uint32_t tx_cnt = tx_max; + + if (dw_xfer->tx_xfer == NULL) { + return 0; + } + while (tx_max) { + if (dw_xfer->tx_xfer->tx_idx >= dw_xfer->tx_xfer->tot_len) { + dw_xfer->tx_xfer = dw_xfer->tx_xfer->next; + if (dw_xfer->tx_xfer == NULL) { + break; + } + } + if ( (dw_xfer->tx_xfer->tx_idx >= dw_xfer->tx_xfer->tx_ofs) \ + && (dw_xfer->tx_xfer->tx_idx < dw_xfer->tx_xfer->tx_totlen)) { + if (dw_xfer->nbytes == 1) { + tx_w = (int32_t)(*(int8_t *)(dw_xfer->tx_xfer->tx_buf)); + } else { + tx_w = (int32_t)(*(int16_t *)(dw_xfer->tx_xfer->tx_buf)); + } + dw_xfer->tx_xfer->tx_buf += dw_xfer->nbytes; + } else { + tx_w = spi_info_ptr->dummy; + } + dw_spi_putdata(spi_reg_ptr, tx_w); + dw_xfer->tx_xfer->tx_idx += dw_xfer->nbytes; + dw_xfer->tx_idx += dw_xfer->nbytes; + tx_max --; + } + return ((tx_cnt-tx_max) * dw_xfer->nbytes); +} + +static int32_t dw_spi_reader(DEV_SPI_INFO *spi_info_ptr) +{ + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + DW_SPI_TRANSFER *dw_xfer = &(spi_ctrl_ptr->dw_xfer); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + uint32_t rx_max = dw_spi_rx_max(spi_ctrl_ptr); + int32_t rx_w; + uint32_t rx_cnt = rx_max; + + if (dw_xfer->rx_xfer == NULL) { + return 0; + } + while (rx_max) { + if (dw_xfer->rx_xfer->rx_idx >= dw_xfer->rx_xfer->tot_len) { + dw_xfer->rx_xfer = dw_xfer->rx_xfer->next; + if (dw_xfer->rx_xfer == NULL) { + break; + } + } + rx_w = dw_spi_getdata(spi_reg_ptr); + if ( (dw_xfer->rx_xfer->rx_idx >= dw_xfer->rx_xfer->rx_ofs) \ + && (dw_xfer->rx_xfer->rx_idx < dw_xfer->rx_xfer->rx_totlen) ) { + if (dw_xfer->nbytes == 1) { + *(int8_t *)(dw_xfer->rx_xfer->rx_buf) = rx_w; + } else { + *(int16_t *)(dw_xfer->rx_xfer->rx_buf) = rx_w; + } + dw_xfer->rx_xfer->rx_buf += dw_xfer->nbytes; + } + dw_xfer->rx_xfer->rx_idx += dw_xfer->nbytes; + dw_xfer->rx_idx += dw_xfer->nbytes; + rx_max --; + } + return ((rx_cnt-rx_max) * dw_xfer->nbytes); +} + +Inline uint32_t dw_spi_nbytes(uint32_t dfs) +{ + uint32_t nbytes = 1; + + if (dfs > 8) nbytes = 2; + return nbytes; +} + +static void dw_spi_init_transfer(DW_SPI_CTRL *spi_ctrl_ptr, DEV_SPI_TRANSFER *xfer, uint32_t dfs) +{ + DW_SPI_TRANSFER *dw_xfer= &(spi_ctrl_ptr->dw_xfer); + uint32_t tot_len = 0; + + dw_xfer->tx_xfer = xfer; + dw_xfer->rx_xfer = xfer; + dw_xfer->tx_idx = 0; + dw_xfer->rx_idx = 0; + dw_xfer->nbytes = dw_spi_nbytes(dfs); + + /** Calculate all transfer length */ + while (xfer) { + DEV_SPI_XFER_INIT(xfer); + tot_len += xfer->tot_len; + xfer = xfer->next; + } + dw_xfer->xfer_len = tot_len; +} + +/* Check buffer align status, 0 for aligned, -1 for not-aligned */ +static int32_t dw_spi_chk_xfer_aligned(DEV_SPI_TRANSFER *xfer, uint32_t dfs) +{ + uint32_t align_bytes = 1; + if (xfer == NULL) return -1; + + if (dfs > 8) { + align_bytes = 2; + } else { + return 0; + } + + while (xfer) { + /* check tx buffer align status */ + if (xfer->tx_len != 0) { + if (xfer->tx_len % align_bytes) return -1; + if (xfer->tx_ofs % align_bytes) return -1; + if (!CHECK_ALIGN_BYTES(xfer->tx_buf, align_bytes)) return -1; + } + /* check tx buffer align status */ + if (xfer->rx_len != 0) { + if (xfer->rx_len % align_bytes) return -1; + if (xfer->rx_ofs % align_bytes) return -1; + if (!CHECK_ALIGN_BYTES(xfer->rx_buf, align_bytes)) return -1; + } + xfer = xfer->next; + } + return 0; +} + +static uint32_t dw_spi_poll_transfer(DEV_SPI_INFO *spi_info_ptr) +{ + uint32_t len = 0; + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + + spi_info_ptr->status |= DEV_IN_XFER; + while (!dw_spi_xfer_end(spi_ctrl_ptr)) { + len += dw_spi_writer(spi_info_ptr); + len += dw_spi_reader(spi_info_ptr); + } + spi_info_ptr->status &= ~DEV_IN_XFER; + + return len>>1; +} + +/** @} */ + +/** + * \brief open a designware spi device + * \param[in] spi_obj spi object pointer + * \param[in] mode spi working mode (master or slave) + * \param[in] param parameter, for master, param is the freq, for slave, param is dfs + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_spi_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ +int32_t dw_spi_open (DEV_SPI *spi_obj, uint32_t mode, uint32_t param) +{ + int32_t ercd = E_OK; + uint32_t param2check; + uint32_t clk_mode, dfs_val; + uint32_t support_modes; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + DW_SPI_CHECK_EXP((mode==DEV_MASTER_MODE)||(mode==DEV_SLAVE_MODE), E_PAR); + if (mode == DEV_SLAVE_MODE) { /* clock mode should be in the enum structure */ + DW_SPI_CHECK_EXP((param>=SPI_CPOL_0_CPHA_0) && (param<=SPI_CPOL_1_CPHA_1), E_PAR); + } else { /* frequence should > 0 */ + DW_SPI_CHECK_EXP(param>0, E_PAR); + } + /* END OF ERROR CHECK */ + + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + + /* Check supported modes, master or slave */ + support_modes = spi_ctrl_ptr->support_modes; + DW_SPI_CHECK_EXP( (((support_modes)&DW_SPI_MASTER_SUPPORTED)&&(mode == DEV_MASTER_MODE)) || \ + (((support_modes)&DW_SPI_SLAVE_SUPPORTED)&&(mode == DEV_SLAVE_MODE)), E_NOSPT); + + /** Check opened before use case */ + if (spi_info_ptr->opn_cnt > 0) { + if (mode != spi_info_ptr->mode) { + /* current working mode is different from passing mode */ + return E_SYS; + } + if (mode == DEV_MASTER_MODE) { /* param is freq when as master */ + param2check = spi_info_ptr->freq; + } else { /* param is clk_mode when as slave */ + param2check = spi_info_ptr->clk_mode; + } + spi_info_ptr->opn_cnt ++; + if (param != param2check) { /* open with different speed mode */ + return E_OPNED; + } else { + return E_OK; + } + } + /* auto increase open count */ + spi_info_ptr->opn_cnt ++; + + /* Do FIFO Length get before init */ +#if DW_SPI_CALC_FIFO_LEN_ENABLE + spi_ctrl_ptr->tx_fifo_len = dw_spi_get_txfifo_len(spi_ctrl_ptr->dw_spi_regs); + spi_ctrl_ptr->rx_fifo_len = dw_spi_get_rxfifo_len(spi_ctrl_ptr->dw_spi_regs); +#endif + /* hardware init */ + spi_info_ptr->mode = mode; + clk_mode = SPI_CLK_MODE_DEFAULT; + dfs_val = SPI_DFS_DEFAULT; + if (mode == DEV_SLAVE_MODE) { + clk_mode = param; + } + spi_info_ptr->dfs = dfs_val; + spi_info_ptr->clk_mode = clk_mode; + dw_spi_hw_init(spi_ctrl_ptr, clk_mode, dfs_val); + if (mode == DEV_MASTER_MODE) { /* Deselect all slaves, and set frequence */ + dw_spi_deselect_slave(spi_ctrl_ptr->dw_spi_regs, 0); + dw_spi_set_freq(spi_ctrl_ptr, param); + spi_info_ptr->freq = param; + } + + spi_info_ptr->status = DEV_ENABLED; + spi_info_ptr->extra = NULL; + spi_info_ptr->slave = SPI_SLAVE_NOT_SELECTED; + spi_info_ptr->dummy = 0xff; + + spi_ctrl_ptr->int_status = 0; + dw_spi_init_transfer(spi_ctrl_ptr, NULL, dfs_val); + + /** install spi interrupt into system */ + dw_spi_disable_interrupt(spi_info_ptr); + int_handler_install(spi_ctrl_ptr->intno, spi_ctrl_ptr->dw_spi_int_handler); + memset(&(spi_info_ptr->xfer), 0, sizeof(DEV_SPI_TRANSFER)); + memset(&(spi_info_ptr->spi_cbs), 0, sizeof(DEV_SPI_CBS)); + +error_exit: + return ercd; +} + +/** + * \brief close a DesignWare SPI device + * \param[in] spi_obj spi object pointer + * \retval E_OK Close successfully without any issues(including scenario that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_spi_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ +int32_t dw_spi_close (DEV_SPI *spi_obj) +{ + int32_t ercd = E_OK; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_OK); + /* END OF ERROR CHECK */ + + spi_info_ptr->opn_cnt --; + if (spi_info_ptr->opn_cnt == 0) { + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + + dw_spi_disable_interrupt(spi_info_ptr); + dw_spi_abort_tx(spi_obj); + dw_spi_abort_rx(spi_obj); + memset(&(spi_info_ptr->xfer), 0, sizeof(DEV_SPI_TRANSFER)); + memset(&(spi_info_ptr->spi_cbs), 0, sizeof(DEV_SPI_CBS)); + memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); + dw_spi_disable_device(spi_info_ptr); + spi_info_ptr->status = DEV_DISABLED; + spi_info_ptr->extra = NULL; + } else { + ercd = E_OPNED; + } + +error_exit: + return ercd; +} + +/** + * \brief control spi by ctrl command + * \param[in] spi_obj spi object pointer + * \param[in] ctrl_cmd control command code to do specific spi work + * \param[in,out] param parameters used to control spi or return something + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ +int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param) +{ + int32_t ercd = E_OK; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); + /* END OF ERROR CHECK */ + + uint32_t val32; /** to receive unsigned int value */ + DEV_BUFFER *devbuf; + + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + DEV_SPI_TRANSFER *spi_xfer = &(spi_info_ptr->xfer); + + /* check whether current device is disabled */ + if ((spi_info_ptr->status & DEV_ENABLED) == 0) { + /** When device is disabled, + * only SPI_CMD_ENA_DEV, SPI_CMD_DIS_DEV, SPI_CMD_GET_STATUS, SPI_CMD_RESET + * are available, other commands will return E_SYS + */ + if ((ctrl_cmd != SPI_CMD_ENA_DEV) && \ + (ctrl_cmd != SPI_CMD_DIS_DEV) && \ + (ctrl_cmd != SPI_CMD_GET_STATUS) && \ + (ctrl_cmd != SPI_CMD_RESET) ) { + return E_SYS; + } + } + + switch (ctrl_cmd) { + /* Commmon commands for both master and slave mode */ + case SPI_CMD_GET_STATUS: + DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = spi_info_ptr->status; + break; + case SPI_CMD_SET_CLK_MODE: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + val32 = (uint32_t)param; + DW_SPI_CHECK_EXP((val32>=SPI_CPOL_0_CPHA_0) && (val32<=SPI_CPOL_1_CPHA_1), E_PAR); + if (dw_spi_set_clockmode(spi_reg_ptr, val32) == 0) { + spi_info_ptr->clk_mode = val32; + } else { + ercd = E_SYS; + } + break; + case SPI_CMD_ENA_DEV: + dw_spi_enable_device(spi_info_ptr); + break; + case SPI_CMD_DIS_DEV: + dw_spi_disable_device(spi_info_ptr); + break; + case SPI_CMD_RESET: + dw_spi_reset_device(spi_info_ptr); + break; + case SPI_CMD_FLUSH_TX: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + dw_spi_flush_tx(spi_reg_ptr); + break; + case SPI_CMD_FLUSH_RX: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + dw_spi_flush_rx(spi_reg_ptr); + break; + case SPI_CMD_SET_DFS: + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + val32 = (uint32_t)param; + DW_SPI_CHECK_EXP(val32>0, E_PAR); + if (dw_spi_set_dfs(spi_reg_ptr, val32) == 0) { + spi_info_ptr->dfs = val32; + } else { + ercd = E_SYS; + } + break; + case SPI_CMD_SET_DUMMY_DATA: + val32 = (uint32_t)param; + spi_info_ptr->dummy = val32; + break; + case SPI_CMD_GET_RXAVAIL: /* Notice in bytes unit */ + DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_spi_get_rxavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); + break; + case SPI_CMD_GET_TXAVAIL: /* Notice in bytes unit */ + DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_spi_get_txavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); + break; + case SPI_CMD_SET_TXCB: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + spi_info_ptr->spi_cbs.tx_cb = param; + break; + case SPI_CMD_SET_RXCB: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + spi_info_ptr->spi_cbs.rx_cb = param; + break; + case SPI_CMD_SET_XFERCB: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + spi_info_ptr->spi_cbs.xfer_cb = param; + break; + case SPI_CMD_SET_ERRCB: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + spi_info_ptr->spi_cbs.err_cb = param; + break; + case SPI_CMD_ABORT_TX: + ercd = dw_spi_abort_tx(spi_obj); + break; + case SPI_CMD_ABORT_RX: + ercd = dw_spi_abort_rx(spi_obj); + break; + case SPI_CMD_ABORT_XFER: + ercd = dw_spi_abort_xfer(spi_obj); + break; + case SPI_CMD_SET_TXINT: + val32 = (uint32_t)param; + if (val32 == 0) { + ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); + } else { + ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_SND); + } + break; + case SPI_CMD_SET_RXINT: + val32 = (uint32_t)param; + if (val32 == 0) { + ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); + } else { + ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_RCV); + } + break; + case SPI_CMD_SET_TXINT_BUF: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + DEV_SPI_XFER_SET_TXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); + DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, devbuf->len, 0); + DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); + dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); + } else { + DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); + DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); + DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); + dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); + } + break; + case SPI_CMD_SET_RXINT_BUF: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, devbuf->len, 0); + DEV_SPI_XFER_SET_RXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); + DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); + /* Check transfer align */ + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); + dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); + } else { + DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); + DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); + DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); + dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); + } + break; + case SPI_CMD_TRANSFER_POLLING: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + if (param != NULL) { + /* Check transfer align */ + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); + *spi_xfer = *((DEV_SPI_TRANSFER *)param); + dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); + /* Transfer data by poll */ + dw_spi_poll_transfer(spi_info_ptr); + } else { + ercd = E_PAR; + } + break; + case SPI_CMD_TRANSFER_INT: + DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + if (param != NULL) { + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + /* Check transfer align */ + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); + *spi_xfer = *((DEV_SPI_TRANSFER *)param); + dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); + /* Transfer data by interrupt */ + ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_XFER); + } else { + ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); + } + break; + + /* Master mode only commands */ + case SPI_CMD_MST_SET_FREQ: + DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + val32 = (uint32_t)param; + DW_SPI_CHECK_EXP(val32>0, E_PAR); + dw_spi_set_freq(spi_ctrl_ptr, val32); + spi_info_ptr->freq = val32; + break; + case SPI_CMD_MST_SEL_DEV: + DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + val32 = (uint32_t)param; + if (dw_spi_select_slave(spi_reg_ptr, val32) == 0) { + spi_info_ptr->slave = val32; + } else { + ercd = E_SYS; + } + break; + case SPI_CMD_MST_DSEL_DEV: + DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + val32 = (uint32_t)param; + if (dw_spi_deselect_slave(spi_reg_ptr, val32) == 0) { + spi_info_ptr->slave = SPI_SLAVE_NOT_SELECTED; + } else { + ercd = E_SYS; + } + break; + + /* Slave mode only commands */ + + + default: + ercd = E_NOSPT; + break; + } + +error_exit: + return ercd; +} + +/** + * \brief send data through DesignWare SPI + * \param[in] spi_obj spi object pointer + * \param[in] data pointer to data need to send by spi + * \param[in] len length of data to be sent + * \retval >0 Byte count that was successfully sent for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_CTX Device is still in transfer state + * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled + */ +int32_t dw_spi_write (DEV_SPI *spi_obj, const void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); + DW_SPI_CHECK_EXP(spi_info_ptr->status & DEV_ENABLED, E_SYS); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + DW_SPI_CHECK_EXP(data!=NULL, E_PAR); + DW_SPI_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + DEV_SPI_TRANSFER spi_xfer; + + /* Master and Slave transmit */ + DEV_SPI_XFER_SET_TXBUF(&spi_xfer, data, 0, len); + DEV_SPI_XFER_SET_RXBUF(&spi_xfer, NULL, len, 0); + DEV_SPI_XFER_SET_NEXT(&spi_xfer, NULL); + + /* Check transfer align */ + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(&spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); + + dw_spi_init_transfer(spi_ctrl_ptr, &spi_xfer, spi_info_ptr->dfs); + + ercd = dw_spi_poll_transfer(spi_info_ptr); + +error_exit: + return ercd; +} + +/** + * \brief read data through DesignWare SPI + * \param[in] spi_info_ptr spi information structure pointer + * \param[out] data data that need to read (data must be char type) + * \param[in] len data count need to read + * \retval >=0 data have been read + * \retval E_PAR arguments passed was wrong + * \retval E_OBJ spi has something error, nothing can be done + * \retval E_CLSED spi was closed, not available for control + * \retval <0 other error code not defined here + */ +int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); + DW_SPI_CHECK_EXP(spi_info_ptr->status & DEV_ENABLED, E_SYS); + DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); + DW_SPI_CHECK_EXP(data!=NULL, E_PAR); + DW_SPI_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + DEV_SPI_TRANSFER spi_xfer; + + /* Master and Slave transmit */ + DEV_SPI_XFER_SET_TXBUF(&spi_xfer, NULL, len, 0); + DEV_SPI_XFER_SET_RXBUF(&spi_xfer, data, 0, len); + DEV_SPI_XFER_SET_NEXT(&spi_xfer, NULL); + + /* Check transfer align */ + DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(&spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); + + dw_spi_init_transfer(spi_ctrl_ptr, &spi_xfer, spi_info_ptr->dfs); + + ercd = dw_spi_poll_transfer(spi_info_ptr); + +error_exit: + return ercd; +} + +/** + * \brief DesignWare SPI interrupt processing routine + * \param[in] spi_info_ptr DEV_SPI_INFO *spi_info_ptr + * \param[in] ptr extra information + */ +void dw_spi_isr(DEV_SPI *spi_obj, void *ptr) +{ + int32_t ercd = E_OK; + DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); + + /* START ERROR CHECK */ + VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); + /* END OF ERROR CHECK */ + + DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); + DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); + + uint32_t isr_status; + + isr_status = spi_reg_ptr->ISR; + + if (!isr_status) return; + if (spi_ctrl_ptr->dw_xfer.xfer_len == 0) { + dw_spi_disable_interrupt(spi_info_ptr); + } else { + if (isr_status & (DW_SPI_IMR_TXOIM|DW_SPI_IMR_RXOIM|DW_SPI_IMR_RXUIM)) { + dw_spi_clear_interrupt_all(spi_reg_ptr); + dw_spi_disable_interrupt(spi_info_ptr); + if (spi_info_ptr->spi_cbs.err_cb) { + spi_info_ptr->spi_cbs.err_cb(spi_obj); + } + memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); + } + dw_spi_reader(spi_info_ptr); + if (isr_status & DW_SPI_IMR_TXEIM) { + dw_spi_writer(spi_info_ptr); + } + if (dw_spi_xfer_end(spi_ctrl_ptr)) { + if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX) { + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); + if (spi_info_ptr->spi_cbs.tx_cb) { + spi_info_ptr->spi_cbs.tx_cb(spi_obj); + } + } else if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX) { + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); + if (spi_info_ptr->spi_cbs.rx_cb) { + spi_info_ptr->spi_cbs.rx_cb(spi_obj); + } + } else if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER) { + dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); + if (spi_info_ptr->spi_cbs.xfer_cb) { + spi_info_ptr->spi_cbs.xfer_cb(spi_obj); + } + } else { + dw_spi_disable_interrupt(spi_info_ptr); + } + memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); + } + } + +error_exit: + return; +} +/** @} */ /* DEVICE_DW_SPI_IMPLEMENT */ + +/** @} */ /* DEVICE_DW_SPI */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi.h new file mode 100644 index 0000000000..ef2faa90e6 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/spi/dw_spi.h @@ -0,0 +1,190 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-25 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \brief DesignWare SPI driver header file + * \ingroup DEVICE_DW_SPI + */ + +#ifndef _DEVICE_DW_SPI_H_ +#define _DEVICE_DW_SPI_H_ + +#include "device/device_hal/inc/dev_spi.h" + +/** + * if this header file is included, + * will indicate that this designware spi device + * is used + */ +#define DEVICE_USE_DESIGNWARE_SPI + +#define DW_SPI_IN_FREE (0) /*!< Currently not in spi transfer */ +#define DW_SPI_IN_XFER (DEV_IN_TX|DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi transfer */ +#define DW_SPI_IN_TX (DEV_IN_TX|DEV_IN_XFER) /*!< Currently in spi tx */ +#define DW_SPI_IN_RX (DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi rx */ + +#define DW_SPI_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */ +#define DW_SPI_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */ + +#define DW_SPI_MASTER_SUPPORTED (0x1) /*!< Support Designware SPI Master Mode */ +#define DW_SPI_SLAVE_SUPPORTED (0x2) /*!< Support Designware SPI Slave Mode */ +/*!< Support Designware SPI Both Master and Slave Mode */ +#define DW_SPI_BOTH_SUPPORTED (DW_SPI_MASTER_SUPPORTED|DW_SPI_SLAVE_SUPPORTED) + +/** + * \defgroup DEVICE_DW_SPI_REGSTRUCT DesignWare SPI Register Structure + * \ingroup DEVICE_DW_SPI + * \brief contains definitions of DesignWare SPI register structure. + * \details detailed description of DesignWare SPI register information + * @{ + */ +/** + * \brief DesignWare SPI register structure + * \details Detailed struct description of DesignWare SPI + * block register information, implementation of dev_spi_info::spi_regs + */ +typedef volatile struct dw_spi_reg +{ + /*!< Control Register */ + /*!< SPI Control Register 0 (0x0) */ + uint32_t CTRLR0; + /*!< SPI Control Register 1 (0x4) */ + uint32_t CTRLR1; + /*!< Enable Register */ + /*!< SPI Enable Register (0x8) */ + uint32_t SSIENR; + /*!< SPI Microwire Control Register (0xC) */ + uint32_t MWCR; + /*!< SPI Slave Enable Register (0x10) */ + uint32_t SER; + /*!< SPI Baud Rate Select Register (0x14) */ + uint32_t BAUDR; + /*!< TX and RX FIFO Control Register */ + /*!< SPI Transmit FIFO Threshold Level Register (0x18) */ + uint32_t TXFTLR; + /*!< SPI Receive FIFO Threshold Level Register (0x1C) */ + uint32_t RXFTLR; + /*!< SPI Transmit FIFO Level Register (0x20) */ + uint32_t TXFLR; + /*!< SPI Receive FIFO Level Register (0x24) */ + uint32_t RXFLR; + /*!< SPI Status Register (0x28) */ + uint32_t SR; + /*!< Interrupt Enable/Disable/Control Registers */ + /*!< SPI Interrupt Mask Register (0x2C) */ + uint32_t IMR; + /*!< SPI Interrupt Status Register (0x30) */ + uint32_t ISR; + /*!< SPI Raw Interrupt Status Register (0x34) */ + uint32_t RISR; + /*!< SPI Transmit FIFO Overflow Interrupt Clear Register (0x38) */ + uint32_t TXOICR; + /*!< SPI Receive FIFO Overflow Interrupt Clear Register (0x3C) */ + uint32_t RXOICR; + /*!< SPI Receive FIFO Underflow Interrupt Clear Register (0x40) */ + uint32_t RXUICR; + /*!< SPI Multi-Master Interrupt Clear Register (0x44) */ + uint32_t MSTICR; + /*!< SPI Interrupt Clear Register (0x48) */ + uint32_t ICR; + /*!< DMA Control Register (0x4C) */ + uint32_t DMACR; + /*!< DMA Transmit Data Level (0x50) */ + uint32_t DMATDLR; + /*!< DMA Receive Data Level (0x54) */ + uint32_t DMARDLR; + /*!< SPI Identification Register (0x58) */ + uint32_t IDR; + /*!< SPI CoreKit ID Register (Value after Reset : 0x3332322A) (0x5C) */ + uint32_t SSI_VER_ID; + /*!< Data Register */ + /*!< SPI DATA Register for both Read and Write (0x60) */ + uint32_t DATAREG; +} DW_SPI_REG, *DW_SPI_REG_PTR; +/** @} */ + +/** Designware SPI Message Transfer */ +typedef struct dw_spi_transfer { + uint32_t xfer_len; + uint32_t tx_idx; + uint32_t rx_idx; + uint32_t nbytes; + DEV_SPI_TRANSFER *tx_xfer; + DEV_SPI_TRANSFER *rx_xfer; +} DW_SPI_TRANSFER, *DW_SPI_TRANSFER_PTR; + +/** + * \brief DesignWare SPI control structure definition + * \details implement of dev_spi_info::dev_spi_info + */ +typedef struct dw_spi_ctrl { + DW_SPI_REG *dw_spi_regs; /*!< spi register */ + /* Variables which should be set during object implementation */ + uint32_t support_modes; /*!< supported spi modes */ + uint32_t intno; /*!< interrupt no */ + uint32_t dw_apb_bus_freq; /*!< spi ip apb bus frequency */ + uint32_t tx_fifo_len; /*!< transmit fifo length */ + uint32_t rx_fifo_len; /*!< receive fifo length */ + INT_HANDLER dw_spi_int_handler; /*!< spi interrupt handler */ + /* Variables which always change during iic operation */ + uint32_t int_status; /*!< iic interrupt status */ + DW_SPI_TRANSFER dw_xfer; /*!< designware spi transfer */ +} DW_SPI_CTRL, *DW_SPI_CTRL_PTR; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup DEVICE_DW_SPI_FUNCDLR DesignWare SPI Function Declaration + * \ingroup DEVICE_DW_SPI + * \brief contains declarations of designware spi functions. + * \details This are only used in \ref dw_spi_obj.c + * @{ + */ +extern int32_t dw_spi_open (DEV_SPI *spi_obj, uint32_t mode, uint32_t param); +extern int32_t dw_spi_close (DEV_SPI *spi_obj); +extern int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param); +extern int32_t dw_spi_write (DEV_SPI *spi_obj, const void *data, uint32_t len); +extern int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len); +extern void dw_spi_isr(DEV_SPI *spi_obj, void *ptr); +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* _DEVICE_DW_SPI_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h new file mode 100644 index 0000000000..b1a233c699 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h @@ -0,0 +1,141 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-25 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_SPI + * \brief DesignWare SPI driver hardware description related header file + * \details detailed hardware related definitions of DesignWare SPI driver + */ + +#ifndef _DEVICE_DW_SPI_HAL_H_ +#define _DEVICE_DW_SPI_HAL_H_ + +#include "device/designware/spi/dw_spi_hal_cfg.h" + +/* DW APB SPI bit definitions */ + +/** + * \name DesignWare SPI HAL CTRL0 Macros + * \brief DesignWare SPI hal ctrl0 macros, + * include dfs, scph, scppl, tmod, etc + * @{ + */ +#define DW_SPI_CTRLR0_DFS_MASK (0xf) + +#define DW_SPI_CTRLR0_SC_OFS (6) +#define DW_SPI_CTRLR0_SC_MASK (0xC0) +#define DW_SPI_CTRLR0_SCPH_HIGH (0x40) +#define DW_SPI_CTRLR0_SCPH_LOW (0) +#define DW_SPI_CTRLR0_SCPOL_HIGH (0x80) +#define DW_SPI_CTRLR0_SCPOL_LOW (0) + +#define DW_SPI_CTRLR0_TMOD_MASK (0x300) +#define DW_SPI_TMOD_TRANSMIT_RECEIVE (0) +#define DW_SPI_TMOD_TRANSMIT_ONLY (0x100) +#define DW_SPI_TMOD_RECEIVE_ONLY (0x200) +#define DW_SPI_TMOD_EEPROM_READ_ONLY (0x300) + +#define DW_SPI_CTRLR0_FRF_MOTOROLA (0x0) +#define DW_SPI_CTRLR0_FRF_TI (0x10) +#define DW_SPI_CTRLR0_FRF_MICROWIRE (0x20) + +#define DW_SPI_CTRLR0_SLV_OE_DISABLE (1<<10) +#define DW_SPI_CTRLR0_SLV_OE_ENABLE (0) + + +/** @} */ + +/** + * \name DesignWare SPI HAL ISR Flags + * \brief DesignWare SPI hal Interrupt Status Flags + * @{ + */ +#define DW_SPI_TX_OVERFLOW_ERROR (0x2) +#define DW_SPI_RX_UNDERFLOW_ERROR (0x4) +#define DW_SPI_RX_OVERFLOW_ERROR (0x8) + +#define DW_SPI_ISR_RX_FIFO_INT_MASK (0x10) +#define DW_SPI_ISR_TX_FIFO_INT_MASK (0x1) +#define DW_SPI_ISR_TX_OVERFLOW_INT_MASK (0x2) +#define DW_SPI_ISR_RX_UNDERFLOW_INT_MASK (0x4) +#define DW_SPI_ISR_RX_OVERFLOW_INT_MASK (0x8) +/** @} */ + +/** + * \name DesignWare SPI HAL SR Flags + * \brief DesignWare SPI hal Status Flags + * @{ + */ +#define DW_SPI_SR_DCOL (0x40) +#define DW_SPI_SR_TXE (0x20) +#define DW_SPI_SR_RFF (0x10) +#define DW_SPI_SR_RFNE (0x8) +#define DW_SPI_SR_TFE (0x4) +#define DW_SPI_SR_TFNF (0x2) +#define DW_SPI_SR_BUSY (0x1) +/** @} */ + +/** + * \name DesignWare SPI HAL SSI Enable Macros + * \brief DesignWare SPI hal ssi enable macros + * @{ + */ +/* Macros */ +#define DW_SPI_SSI_ENABLE (1) /*!< SSI Enable */ +#define DW_SPI_SSI_DISABLE (0) /*!< SSI Disable */ +/** @} */ + +/** + * \name DesignWare SPI HAL IMR Macros + * \brief DesignWare SPI hal interrupt mask macros + * @{ + */ +#define DW_SPI_IMR_MSTIM (0x20) /*!< Multi-Master Contention Interrupt Mask */ +#define DW_SPI_IMR_RXFIM (0x10) /*!< Receive FIFO Full Interrupt Mask */ +#define DW_SPI_IMR_RXOIM (0x08) /*!< Receive FIFO Overflow Interrupt Mask */ +#define DW_SPI_IMR_RXUIM (0x04) /*!< Receive FIFO Underflow Interrupt Mask */ +#define DW_SPI_IMR_TXOIM (0x02) /*!< Transmit FIFO Overflow Interrupt Mask */ +#define DW_SPI_IMR_TXEIM (0x01) /*!< Transmit FIFO Empty Interrupt Mask */ + +#define DW_SPI_IMR_XFER (DW_SPI_IMR_TXEIM|DW_SPI_IMR_RXFIM|DW_SPI_IMR_TXOIM|DW_SPI_IMR_RXOIM|DW_SPI_IMR_RXUIM) +/** @} */ + +#define DW_SPI_SSI_IDLE (1) +#define DW_SPI_SPI_TRANSMIT (1) +#define DW_SPI_SPI_RECEIVE (2) +#define DW_SPI_SSI_MASTER (1) +#define DW_SPI_SSI_SLAVE (0) + + +#endif /* _DEVICE_DW_SPI_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h new file mode 100644 index 0000000000..d6caf71466 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h @@ -0,0 +1,58 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2015-09-09 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_SPI + * \brief DesignWare SPI driver hardware description + * related header file configuration file + * \details configuration file to enable or disable some function of spi + */ + +#ifndef _DEVICE_DW_SPI_HAL_CFG_H_ +#define _DEVICE_DW_SPI_HAL_CFG_H_ + +#ifndef DW_SPI_CALC_FIFO_LEN_ENABLE +#define DW_SPI_CALC_FIFO_LEN_ENABLE (1) /*!< Defaultly enable calculate fifo length */ +#endif + +#ifndef DW_SPI_MAX_FIFO_LENGTH +#define DW_SPI_MAX_FIFO_LENGTH (256) /*!< Max FIFO depth for designware SPI device */ +#endif + +#ifndef DW_SPI_MIN_FIFO_LENGTH +#define DW_SPI_MIN_FIFO_LENGTH (2) /*!< Min FIFO depth for designware SPI device */ +#endif + +#endif /* _DEVICE_DW_SPI_HAL_CFG_H_ */ + diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart.c b/bsp/synopsys/embarc/device/designware/uart/dw_uart.c new file mode 100644 index 0000000000..999ee751e0 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/uart/dw_uart.c @@ -0,0 +1,956 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-20 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_DW_UART Designware UART Driver + * \ingroup DEVICE_DW + * \brief Designware UART Driver Implementation + */ + +/** + * \file + * \ingroup DEVICE_DW_UART + * \brief DesignWare UART driver implementation based on device hal layer definition (\ref dev_uart.h) + */ +#include + +#include "inc/embARC_toolchain.h" +#include "inc/embARC_error.h" + +#include "inc/arc/arc_exception.h" + +#include "device/designware/uart/dw_uart_hal.h" +#include "device/designware/uart/dw_uart.h" + + +/** + * \name DesignWare UART Driver Macros + * \brief DesignWare UART driver macros used in uart driver + * @{ + */ +/** check expressions used in DesignWare UART driver implementation */ +#define DW_UART_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) + +#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK +/** valid check of uart info object */ +#define VALID_CHK_UART_INFO_OBJECT(uartinfo_obj_ptr) { \ + DW_UART_CHECK_EXP((uartinfo_obj_ptr)!=NULL, E_OBJ); \ + DW_UART_CHECK_EXP(((uartinfo_obj_ptr)->uart_ctrl)!=NULL, E_OBJ); \ + } +#endif + +/** convert DesignWare baudrate to divisor */ +#define DW_UART_BAUD2DIV(perifreq, baud) ((perifreq) / ((baud)*16)) + +/** + * \name DesignWare UART Interrupt Callback Routine Select Marcos + * \brief DesignWare UART interrupt callback routines select macros definitions + * @{ + */ +#define DW_UART_RDY_SND (1U) /*!< ready to send callback */ +#define DW_UART_RDY_RCV (2U) /*!< ready to receive callback */ +/** @} */ + +/** @} */ + +/** + * \defgroup DEVICE_DW_UART_STATIC DesignWare UART Driver Static Functions + * \ingroup DEVICE_DW_UART + * \brief Static or inline functions, variables for DesignWare UART handle uart operations, + * only used in this file + * @{ + */ +const uint8_t dw_uart_databits[] = { \ + DW_UART_LCR_WORD_LEN5, DW_UART_LCR_WORD_LEN6, \ + DW_UART_LCR_WORD_LEN7, DW_UART_LCR_WORD_LEN8}; +const uint8_t dw_uart_parity[] = { + DW_UART_LCR_PARITY_NONE, DW_UART_LCR_PARITY_ODD, + DW_UART_LCR_PARITY_EVEN, DW_UART_LCR_PARITY_MASK, + DW_UART_LCR_PARITY_SPACE +}; +const uint8_t dw_uart_stopbits[] = { + DW_UART_LCR_1_STOP_BIT, DW_UART_LCR_1D5_STOP_BIT, + DW_UART_LCR_2_STOP_BIT +}; + +/** test whether uart is ready to send, 1 ready, 0 not ready */ +Inline int32_t dw_uart_putready(DW_UART_REG *uart_reg_ptr) +{ + return ((uart_reg_ptr->USR & DW_UART_USR_TFNF) != 0); +} +/** test whether uart is ready to receive, 1 ready, 0 not ready */ +Inline int32_t dw_uart_getready(DW_UART_REG *uart_reg_ptr) +{ + return ((uart_reg_ptr->USR & DW_UART_USR_RFNE) != 0); +} +/** write char to uart send fifo */ +Inline void dw_uart_putchar(DW_UART_REG *uart_reg_ptr, char chr) +{ + uart_reg_ptr->DATA = chr; +} +/** read data from uart receive fifo, return data received */ +Inline int32_t dw_uart_getchar(DW_UART_REG *uart_reg_ptr) +{ + return (int32_t)uart_reg_ptr->DATA; +} +/** + * \brief send char by uart when available, + * mostly used in interrupt method, non-blocked function + * \param[in] uart_reg_ptr uart register structure pointer + * \param[in] chr char to be sent + * \retval 0 send successfully + * \retval -1 not ready to send data + */ +Inline int32_t dw_uart_snd_chr(DW_UART_REG *uart_reg_ptr, char chr) +{ + if (dw_uart_putready(uart_reg_ptr)) { + dw_uart_putchar(uart_reg_ptr, chr); + return 0; + } + return -1; +} +/** + * \brief receive one char from uart, + * mostly used in interrupt routine, non-blocked function + * \param[in] uart_reg_ptr uart register structure pointer + * \return data received by the uart + */ +Inline int32_t dw_uart_rcv_chr(DW_UART_REG *uart_reg_ptr) +{ + return dw_uart_getchar(uart_reg_ptr); +} +/** + * \brief send char by uart in poll method, blocked function + * \param[in] uart_reg_ptr uart register structure pointer + * \param[in] chr char to be sent + */ +Inline void dw_uart_psnd_chr(DW_UART_REG *uart_reg_ptr, char chr) +{ + /** wait until uart is ready to send */ + while (!dw_uart_putready(uart_reg_ptr)); /* blocked */ + /** send char */ + dw_uart_putchar(uart_reg_ptr, chr); +} +/** + * \brief receive one char from uart in poll method, blocked function + * \param[in] uart_reg_ptr uart register structure pointer + * \return data received by the uart + */ +Inline int32_t dw_uart_prcv_chr(DW_UART_REG *uart_reg_ptr) +{ + /** wait until uart is ready to receive */ + while (!dw_uart_getready(uart_reg_ptr)); /* blocked */ + /** receive data */ + return dw_uart_getchar(uart_reg_ptr); +} + +/** Get TX FIFO Length */ +Inline uint32_t dw_uart_get_txfifo_len(DW_UART_REG *uart_reg_ptr) +{ + uint32_t txfifolen; + uint32_t uart_cpr; + + uart_cpr = uart_reg_ptr->CPR; + if (uart_cpr & DW_UART_CPR_FIFO_STAT) { + txfifolen = ((uart_cpr & DW_UART_CPR_FIFO_MODE) >> DW_UART_CPR_FIFO_MODE_OFS) << 4; + } else { + txfifolen = 0; + } + + return txfifolen; +} + +/** Get RX FIFO Length */ +Inline uint32_t dw_uart_get_rxfifo_len(DW_UART_REG *uart_reg_ptr) +{ + uint32_t rxfifolen; + uint32_t uart_cpr; + + uart_cpr = uart_reg_ptr->CPR; + if (uart_cpr & DW_UART_CPR_FIFO_STAT) { + rxfifolen = ((uart_cpr & DW_UART_CPR_FIFO_MODE) >> DW_UART_CPR_FIFO_MODE_OFS) << 4; + } else { + rxfifolen = 0; + } + + return rxfifolen; +} + +/** + * \brief set designware uart DPS value + * \param uart_reg_ptr uart register structure + * \param dps data bits/parity bit/stop bits parameter + * \retval 0 Set ok + * \retval !0 Set failed + */ +static int32_t dw_uart_set_dps(DW_UART_REG *uart_reg_ptr, UART_DPS_FORMAT *dps) +{ + uint32_t dps_value = 0; + + if (dps == NULL) return -1; + /* data bits check */ + if ((dps->databits < 5) || (dps->databits > 8)) return -1; + /* stop bits check */ + if (dps->stopbits > UART_STPBITS_TWO) return -1; + /* parity bit type check */ + if (dps->parity > UART_PARITY_SPACE) return -1; + + dps_value |= (uint32_t)dw_uart_databits[dps->databits-5]; + dps_value |= (uint32_t)dw_uart_stopbits[dps->stopbits]; + dps_value |= (uint32_t)dw_uart_parity[dps->parity]; + + /* clear dps bits */ + uart_reg_ptr->LCR &= (~DW_UART_LCR_DPS_MASK); + /* set dps bits */ + uart_reg_ptr->LCR |= dps_value; + + return 0; +} + +/** + * \brief set designware uart baudrate + * \param uart_reg_ptr uart register structure + * \param baud_divisor uart baudrate divisor + */ +static void dw_uart_set_baud(DW_UART_REG *uart_reg_ptr, uint32_t baud_divisor) +{ + /* enable uart baudrate update */ + uart_reg_ptr->LCR |= DW_UART_LCR_DLAB; + /** + * setting uart baudrate registers + */ + uart_reg_ptr->DATA = baud_divisor & 0xff; /*!< DLL */ + uart_reg_ptr->IER = (baud_divisor>>8) & 0xff; /*!< DLH */ + /** disable DLAB */ + uart_reg_ptr->LCR &= ~(DW_UART_LCR_DLAB); +} + +/** + * \brief Do uart software reset + * \param uart_reg_ptr uart register structure + */ +Inline void dw_uart_software_reset(DW_UART_REG *uart_reg_ptr) +{ + uart_reg_ptr->SRR = DW_UART_SRR_UR|DW_UART_SRR_RFR|DW_UART_SRR_XFR; + while(uart_reg_ptr->USR & DW_UART_USR_BUSY); /* wait until software reset completed */ +} + +/** + * \brief set designware uart baudrate + * \param uart_reg_ptr uart register structure + * \param hwfc uart hardware flow control type + * \note Need to set corresponding pin functions + */ +static void dw_uart_set_hwfc(DW_UART_REG *uart_reg_ptr, UART_HW_FLOW_CONTROL hwfc) +{ + if (hwfc == UART_FC_NONE) { + uart_reg_ptr->MCR &= ~(DW_UART_MCR_AFCE|DW_UART_MCR_RTS); + } + if ((hwfc == UART_FC_RTS) || (hwfc == UART_FC_BOTH)) { + uart_reg_ptr->MCR |= (DW_UART_MCR_AFCE|DW_UART_MCR_RTS); + } + if ((hwfc == UART_FC_CTS) || (hwfc == UART_FC_BOTH)) { + uart_reg_ptr->MCR |= (DW_UART_MCR_AFCE); + } +} + +Inline void dw_uart_set_break(DW_UART_REG *uart_reg_ptr) +{ + uart_reg_ptr->LCR |= DW_UART_LCR_BREAK; +} + +Inline void dw_uart_clr_break(DW_UART_REG *uart_reg_ptr) +{ + uart_reg_ptr->LCR &= ~DW_UART_LCR_BREAK; +} + +/** + * \brief init designware uart with selected baud + * \param[in] uart_reg_ptr uart register structure pointer + * \param[in] baud_divisor baudrate divisor + */ +static void dw_uart_init(DW_UART_REG *uart_reg_ptr, uint32_t baud_divisor, UART_DPS_FORMAT *dps, UART_HW_FLOW_CONTROL hwfc) +{ + dw_uart_software_reset(uart_reg_ptr); + + dw_uart_set_hwfc(uart_reg_ptr, hwfc); + dw_uart_set_dps(uart_reg_ptr, dps); + dw_uart_set_baud(uart_reg_ptr, baud_divisor); + + uart_reg_ptr->IIR = 0x1; /** enable uart fifo (FCR IIR is the same) */ + uart_reg_ptr->IER = 0x0; /** disable all uart interrupt */ +} + +/** + * \brief set designware uart baudrate + * \param uart_info_ptr uart information structure pointer + */ +static void dw_uart_flush_output(DEV_UART_INFO *uart_info_ptr) +{ + uint32_t i; + char *p_charbuf; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + if (uart_info_ptr->tx_buf.buf != NULL) { + p_charbuf = (char *)(uart_info_ptr->tx_buf.buf); + for (i = uart_info_ptr->tx_buf.ofs; i < uart_info_ptr->tx_buf.len; i ++) { + dw_uart_psnd_chr(uart_reg_ptr, p_charbuf[i]); + } + /* clear transmit buffer */ + uart_info_ptr->tx_buf.buf = NULL; + uart_info_ptr->tx_buf.len = 0; + uart_info_ptr->tx_buf.ofs = 0; + } + /* wait until transmit fifo is empty */ + while ((uart_reg_ptr->USR & DW_UART_USR_TFE) == 0); + while (uart_reg_ptr->USR & DW_UART_USR_BUSY); +} + +/** + * \brief disable designware uart send or receive interrupt + * \param[in] DEV_UART_INFO *uart_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static void dw_uart_dis_cbr(DEV_UART_INFO *uart_info_ptr, uint32_t cbrtn) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + switch (cbrtn) { + case DW_UART_RDY_SND: + uart_reg_ptr->IER &= ~DW_UART_IER_XMIT_EMPTY; + uart_ctrl_ptr->int_status &= ~DW_UART_TXINT_ENABLE; + break; + case DW_UART_RDY_RCV: + uart_reg_ptr->IER &= ~DW_UART_IER_DATA_AVAIL; + uart_ctrl_ptr->int_status &= ~DW_UART_RXINT_ENABLE; + break; + default: + break; + } + if (uart_ctrl_ptr->int_status & DW_UART_GINT_ENABLE) { + if ((uart_ctrl_ptr->int_status & (DW_UART_RXINT_ENABLE|DW_UART_TXINT_ENABLE)) == 0) { + int_disable(uart_ctrl_ptr->intno); + uart_ctrl_ptr->int_status &= ~DW_UART_GINT_ENABLE; + } + } +} + +/** + * \brief enable DesignWare UART send or receive interrupt + * \param[in] DEV_UART_INFO *uart_info_ptr + * \param[in] cbrtn control code of callback routine of send or receive + */ +static void dw_uart_ena_cbr(DEV_UART_INFO *uart_info_ptr, uint32_t cbrtn) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + switch (cbrtn) { + case DW_UART_RDY_SND: + uart_ctrl_ptr->int_status |= DW_UART_TXINT_ENABLE; + uart_reg_ptr->IER |= DW_UART_IER_XMIT_EMPTY; + break; + case DW_UART_RDY_RCV: + uart_ctrl_ptr->int_status |= DW_UART_RXINT_ENABLE; + uart_reg_ptr->IER |= DW_UART_IER_DATA_AVAIL; + break; + default: + break; + } + if ((uart_ctrl_ptr->int_status & DW_UART_GINT_ENABLE) == 0) { + if (uart_ctrl_ptr->int_status & (DW_UART_RXINT_ENABLE|DW_UART_TXINT_ENABLE)) { + uart_ctrl_ptr->int_status |= DW_UART_GINT_ENABLE; + int_enable(uart_ctrl_ptr->intno); + } + } +} + +/** + * \brief enable designware uart interrupt + * \param uart_info_ptr uart information structure pointer + */ +static void dw_uart_enable_interrupt(DEV_UART_INFO *uart_info_ptr) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + + int_handler_install(uart_ctrl_ptr->intno, uart_ctrl_ptr->dw_uart_int_handler); + uart_ctrl_ptr->int_status |= DW_UART_GINT_ENABLE; + int_enable(uart_ctrl_ptr->intno); /** enable uart interrupt */ +} +/** + * \brief disable designware uart interrupt + * \param uart_info_ptr uart information structure pointer + */ +static void dw_uart_disable_interrupt(DEV_UART_INFO *uart_info_ptr) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + + /** disable uart send&receive interrupt after disable uart interrupt */ + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); + /* disable uart interrupt */ + int_disable(uart_ctrl_ptr->intno); + uart_ctrl_ptr->int_status &= ~(DW_UART_GINT_ENABLE|DW_UART_TXINT_ENABLE|DW_UART_RXINT_ENABLE); +} + +/** enable designware uart */ +static void dw_uart_enable_device(DEV_UART_INFO *uart_info_ptr) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + if ((uart_info_ptr->status & DEV_ENABLED) == 0) { + dw_uart_set_baud(uart_reg_ptr, uart_info_ptr->baudrate); + uart_info_ptr->status |= DEV_ENABLED; + } +} + +/** disable designware uart */ +static void dw_uart_disable_device(DEV_UART_INFO *uart_info_ptr) +{ + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + if ((uart_info_ptr->status & DEV_ENABLED) == DEV_ENABLED) { + dw_uart_set_baud(uart_reg_ptr, 0); + uart_info_ptr->status &= ~DEV_ENABLED; + } +} + +/** abort current interrupt transmit transfer */ +static void dw_uart_abort_tx(DEV_UART *uart_obj) +{ + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + + if (uart_ctrl_ptr->int_status & DW_UART_TXINT_ENABLE) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); + uart_info_ptr->status |= DEV_IN_TX_ABRT; + if (uart_info_ptr->uart_cbs.tx_cb != NULL) { + uart_info_ptr->uart_cbs.tx_cb(uart_obj); + } + uart_info_ptr->status &= ~(DEV_IN_TX_ABRT); + } +} + +/** abort current interrupt receive transfer */ +static void dw_uart_abort_rx(DEV_UART *uart_obj) +{ + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + + if (uart_ctrl_ptr->int_status & DW_UART_RXINT_ENABLE) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); + uart_info_ptr->status |= DEV_IN_RX_ABRT; + if (uart_info_ptr->uart_cbs.rx_cb != NULL) { + uart_info_ptr->uart_cbs.rx_cb(uart_obj); + } + uart_info_ptr->status &= ~(DEV_IN_RX_ABRT); + } +} + +/** Get available transmit fifo count */ +static int32_t dw_uart_get_txavail(DW_UART_CTRL *uart_ctrl_ptr) +{ + int32_t tx_avail = 0; + DW_UART_REG *uart_reg_ptr = (DW_UART_REG *)(uart_ctrl_ptr->dw_uart_regbase); + + if (uart_ctrl_ptr->tx_fifo_len <= 1) { + if (dw_uart_putready(uart_reg_ptr) == 1) { + tx_avail = 1; + } else { + tx_avail = 0; + } + } else { + tx_avail = uart_ctrl_ptr->tx_fifo_len - uart_reg_ptr->TFL; + } + return tx_avail; +} + +/** Get available receive fifo count */ +static int32_t dw_uart_get_rxavail(DW_UART_CTRL *uart_ctrl_ptr) +{ + int32_t rx_avail = 0; + DW_UART_REG *uart_reg_ptr = (DW_UART_REG *)(uart_ctrl_ptr->dw_uart_regbase); + + if (uart_ctrl_ptr->rx_fifo_len <= 1) { + if (dw_uart_getready(uart_reg_ptr) == 1) { + rx_avail = 1; + } else { + rx_avail = 0; + } + } else { + rx_avail = uart_reg_ptr->RFL; + } + return rx_avail; +} + + +/** @} end of group DEVICE_DW_UART_STATIC */ + +/** + * \brief open a designware uart device + * \param[in] uart_obj uart object structure pointer + * \param[in] baud baudrate to initialized + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different baudrate, then return E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ +int32_t dw_uart_open (DEV_UART *uart_obj, uint32_t baud) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + DW_UART_CHECK_EXP(baud>0, E_PAR); + /* END OF ERROR CHECK */ + + uart_info_ptr->opn_cnt ++; + if (uart_info_ptr->opn_cnt > 1) { /* opened before */ + if (baud == uart_info_ptr->baudrate) { /* baudrate is the same */ + return E_OK; + } else { /* open with different baudrate */ + return E_OPNED; + } + } + + int32_t baud_divisor = 0; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + /* Get FIFO Length */ + uart_ctrl_ptr->tx_fifo_len = dw_uart_get_txfifo_len(uart_reg_ptr); + uart_ctrl_ptr->rx_fifo_len = dw_uart_get_rxfifo_len(uart_reg_ptr); + + /** init uart */ + uart_info_ptr->baudrate = baud; + baud_divisor = DW_UART_BAUD2DIV(uart_ctrl_ptr->dw_apb_bus_freq, baud); + uart_info_ptr->dps_format = dps_format_default; + uart_info_ptr->hwfc = hwfc_default; + dw_uart_init(uart_reg_ptr, baud_divisor, &(uart_info_ptr->dps_format), uart_info_ptr->hwfc); + + uart_info_ptr->status = DEV_ENABLED; + uart_info_ptr->extra = NULL; + + /** + * uart interrupt related init + */ + dw_uart_disable_interrupt(uart_info_ptr); + /** install uart interrupt into system */ + int_handler_install(uart_ctrl_ptr->intno, uart_ctrl_ptr->dw_uart_int_handler); + + memset(&(uart_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(uart_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(uart_info_ptr->uart_cbs), 0, sizeof(DEV_UART_CBS)); + +error_exit: + return ercd; +} + +/** + * \brief close a DesignWare UART device + * \param[in] uart_obj uart object structure pointer + * \retval E_OK Open successfully without any issues + * \retval E_OPNED Device is still opened, the device opn_cnt decreased by 1 + * \retval E_OBJ Device object is not valid + */ +int32_t dw_uart_close (DEV_UART *uart_obj) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_OK); + /* END OF ERROR CHECK */ + + uart_info_ptr->opn_cnt --; + if (uart_info_ptr->opn_cnt == 0) { + dw_uart_disable_interrupt(uart_info_ptr); + dw_uart_abort_tx(uart_obj); + dw_uart_abort_rx(uart_obj); + dw_uart_flush_output(uart_info_ptr); + memset(&(uart_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(uart_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); + memset(&(uart_info_ptr->uart_cbs), 0, sizeof(DEV_UART_CBS)); + dw_uart_disable_device(uart_info_ptr); + uart_info_ptr->status = 0; + uart_info_ptr->extra = NULL; + } else { + ercd = E_OPNED; + } + +error_exit: + return ercd; +} + +/** + * \brief control uart by ctrl command + * \param[in] uart_obj uart object structure pointer + * \param[in] ctrl_cmd control command code to do specific uart work + * \param[in,out] param parameters used to control uart or return something + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_DIS Device is disabled + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ +int32_t dw_uart_control (DEV_UART *uart_obj, uint32_t ctrl_cmd, void *param) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); + /* END OF ERROR CHECK */ + + uint32_t val32; /** to receive unsigned int value */ + int32_t baud_divisor = 0; + DEV_BUFFER *devbuf; + UART_DPS_FORMAT *dps_ptr; + UART_HW_FLOW_CONTROL hwfc_local; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + /* check whether current device is disabled */ + if ((uart_info_ptr->status & DEV_ENABLED) == 0) { + /** When device is disabled, + * only UART_CMD_ENA_DEV, UART_CMD_DIS_DEV, UART_CMD_GET_STATUS + * are available, other commands will return E_SYS + */ + if ((ctrl_cmd != UART_CMD_ENA_DEV) && \ + (ctrl_cmd != UART_CMD_DIS_DEV) && \ + (ctrl_cmd != UART_CMD_GET_STATUS) ) { + return E_SYS; + } + } + + switch (ctrl_cmd) { + case UART_CMD_SET_BAUD: + val32 = (uint32_t)param; + DW_UART_CHECK_EXP(val32>0, E_PAR); + if (val32 != uart_info_ptr->baudrate) { + baud_divisor = DW_UART_BAUD2DIV(uart_ctrl_ptr->dw_apb_bus_freq, val32); + dw_uart_set_baud(uart_reg_ptr, baud_divisor); + uart_info_ptr->baudrate = val32; + } + break; + case UART_CMD_GET_STATUS: + DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = uart_info_ptr->status; + break; + case UART_CMD_ENA_DEV: + dw_uart_enable_device(uart_info_ptr); + break; + case UART_CMD_DIS_DEV: + dw_uart_disable_device(uart_info_ptr); + break; + case UART_CMD_FLUSH_OUTPUT: + dw_uart_flush_output(uart_info_ptr); + break; + case UART_CMD_GET_RXAVAIL: + DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_uart_get_rxavail(uart_ctrl_ptr); + break; + case UART_CMD_GET_TXAVAIL: + DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); + *((int32_t *)param) = dw_uart_get_txavail(uart_ctrl_ptr); + break; + case UART_CMD_BREAK_SET: + dw_uart_set_break(uart_reg_ptr); + break; + case UART_CMD_BREAK_CLR: + dw_uart_clr_break(uart_reg_ptr); + break; + case UART_CMD_SET_DPS_FORMAT: + DW_UART_CHECK_EXP(param!=NULL, E_PAR); + dps_ptr = (UART_DPS_FORMAT *)param; + if (dw_uart_set_dps(uart_reg_ptr, dps_ptr) == 0) { + uart_info_ptr->dps_format = *dps_ptr; + } else { + ercd = E_PAR; + } + break; + case UART_CMD_SET_HWFC: + hwfc_local = (UART_HW_FLOW_CONTROL)param; + DW_UART_CHECK_EXP(((hwfc_local>=UART_FC_NONE) && (hwfc_local<=UART_FC_BOTH)), E_PAR); + dw_uart_set_hwfc(uart_reg_ptr, hwfc_local); + uart_info_ptr->hwfc = hwfc_local; + break; + case UART_CMD_SET_TXCB: + DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + uart_info_ptr->uart_cbs.tx_cb = param; + break; + case UART_CMD_SET_RXCB: + DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + uart_info_ptr->uart_cbs.rx_cb = param; + break; + case UART_CMD_SET_ERRCB: + DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + uart_info_ptr->uart_cbs.err_cb = param; + break; + case UART_CMD_ABORT_TX: + dw_uart_abort_tx(uart_obj); + break; + case UART_CMD_ABORT_RX: + dw_uart_abort_rx(uart_obj); + break; + case UART_CMD_SET_TXINT: + val32 = (uint32_t)param; + if (val32 == 0) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); + } else { + dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_SND); + } + break; + case UART_CMD_SET_RXINT: + val32 = (uint32_t)param; + if (val32 == 0) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); + } else { + dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_RCV); + } + break; + case UART_CMD_SET_TXINT_BUF: + DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + uart_info_ptr->tx_buf = *devbuf; + uart_info_ptr->tx_buf.ofs = 0; + } else { + uart_info_ptr->tx_buf.buf = NULL; + uart_info_ptr->tx_buf.len = 0; + uart_info_ptr->tx_buf.ofs = 0; + } + break; + case UART_CMD_SET_RXINT_BUF: + DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); + if (param != NULL) { + devbuf = (DEV_BUFFER *)param; + uart_info_ptr->rx_buf = *devbuf; + uart_info_ptr->rx_buf.ofs = 0; + } else { + uart_info_ptr->rx_buf.buf = NULL; + uart_info_ptr->rx_buf.len = 0; + uart_info_ptr->rx_buf.ofs = 0; + } + break; + default: + ercd = E_NOSPT; + break; + } + +error_exit: + return ercd; +} + +/** + * \brief send data through DesignWare UART + * \param[in] uart_obj uart object structure pointer + * \param[in] data data that need to send (data must be char type) + * \param[in] len data length need to send + * \retval >0 Byte count that was successfully sent for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Can't write data to hardware due to hardware issues + */ +int32_t dw_uart_write (DEV_UART *uart_obj, const void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); + DW_UART_CHECK_EXP(uart_info_ptr->status & DEV_ENABLED, E_SYS); + DW_UART_CHECK_EXP(data!=NULL, E_PAR); + DW_UART_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + int32_t i = 0; + const char *p_charbuf = (const char *)data; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + while (i < len) { + dw_uart_psnd_chr(uart_reg_ptr, p_charbuf[i++]); + } + ercd = i; + +error_exit: + return ercd; +} + +/** + * \brief read data through DesignWare UART + * \param[in] uart_obj uart object structure pointer + * \param[out] data data that need to read (data must be char type) + * \param[in] len data count need to read + * \retval >0 Byte count that was successfully sent for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled + */ +int32_t dw_uart_read (DEV_UART *uart_obj, void *data, uint32_t len) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); + DW_UART_CHECK_EXP(uart_info_ptr->status & DEV_ENABLED, E_SYS); + DW_UART_CHECK_EXP(data!=NULL, E_PAR); + DW_UART_CHECK_EXP(len>0, E_PAR); + /* END OF ERROR CHECK */ + + int32_t i = 0; + char *p_charbuf = (char *)data; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + while (i < len) { + p_charbuf[i++] = dw_uart_prcv_chr(uart_reg_ptr); + } + ercd = i; + +error_exit: + return ercd; +} + +/** + * \brief DesignWare UART interrupt processing routine + * \param[in] uart_obj uart object structure pointer + * \param[in] ptr extra information + */ +void dw_uart_isr (DEV_UART *uart_obj, void *ptr) +{ + int32_t ercd = E_OK; + DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); + + /* START ERROR CHECK */ + VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); + /* END OF ERROR CHECK */ + + uint32_t uart_int_status; /** uart interrupt status */ + volatile uint32_t temp; /** read error status to clear interrupt */ + DEV_BUFFER *buf_ptr; + char *p_charbuf; + + DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); + DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); + + /** get uart interrupt status */ + uart_int_status = (uart_reg_ptr->IIR) & DW_UART_IIR_INT_ID_MASK; + + switch (uart_int_status) { + case DW_UART_IIR_MDM_STATUS: + temp = (volatile uint32_t)(uart_reg_ptr->MSR); + break; + case DW_UART_IIR_LINE_STATUS: + if (uart_info_ptr->uart_cbs.err_cb) { + uart_info_ptr->uart_cbs.err_cb(uart_info_ptr); + } + temp = (volatile uint32_t)(uart_reg_ptr->LSR); + break; + case DW_UART_IIR_XMIT_EMPTY: + buf_ptr = &(uart_info_ptr->tx_buf); + p_charbuf = (char *)buf_ptr->buf; + if (p_charbuf != NULL) { + while (dw_uart_putready(uart_reg_ptr)) { + dw_uart_putchar(uart_reg_ptr, p_charbuf[buf_ptr->ofs]); + buf_ptr->ofs ++; + if (buf_ptr->ofs >= buf_ptr->len) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); + if (uart_info_ptr->uart_cbs.tx_cb) { + uart_info_ptr->uart_cbs.tx_cb(uart_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + break; + } + } + } else { + if (uart_info_ptr->uart_cbs.tx_cb) { + uart_info_ptr->uart_cbs.tx_cb(uart_obj); + } + } + break; + case DW_UART_IIR_RX_TIMEOUT: + temp = dw_uart_getchar(uart_reg_ptr); + break; + case DW_UART_IIR_DATA_AVAIL: + buf_ptr = &(uart_info_ptr->rx_buf); + p_charbuf = (char *)buf_ptr->buf; + if (p_charbuf != NULL) { + while (dw_uart_getready(uart_reg_ptr)) { + p_charbuf[buf_ptr->ofs] = (char)dw_uart_getchar(uart_reg_ptr); + buf_ptr->ofs ++; + if (buf_ptr->ofs >= buf_ptr->len) { + dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); + if (uart_info_ptr->uart_cbs.rx_cb) { + uart_info_ptr->uart_cbs.rx_cb(uart_obj); + } + /* clear the send buffer pointer */ + memset(buf_ptr, 0, sizeof(DEV_BUFFER)); + break; + } + } + } else { + if (uart_info_ptr->uart_cbs.rx_cb) { + uart_info_ptr->uart_cbs.rx_cb(uart_obj); + } + } + break; + default: + temp = (volatile uint32_t)(uart_reg_ptr->USR); + break; + } + +error_exit: + return; +} diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart.h b/bsp/synopsys/embarc/device/designware/uart/dw_uart.h new file mode 100644 index 0000000000..366c4fccc2 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/uart/dw_uart.h @@ -0,0 +1,141 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-20 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_UART + * \brief DesignWare UART driver header file + * \details detailed definitions of designware uart driver + */ + +#ifndef _DW_UART_H_ +#define _DW_UART_H_ + +#include "device/device_hal/inc/dev_uart.h" + +#include "inc/arc/arc_exception.h" + +/** + * if this header file is included, + * will indicate that this designware uart device + * is used + */ +#define DEVICE_USE_DESIGNWARE_UART + +/** + * \name DesignWare UART Register Structure + * \brief contains definitions of DesignWare UART register structure. + * @{ + */ +/** + * \brief DesignWare UART register structure + * \details Detailed struct description of DesignWare UART + * block register information, implementation of dev_uart_info::uart_regs + */ +typedef volatile struct dw_uart_reg { + uint32_t DATA; /*!< data in/out and DLL */ + uint32_t IER; /*!< Interrupt enable register and DLH */ + uint32_t IIR; /*!< Interrupt Id register and FCR */ + uint32_t LCR; /*!< Line control Register */ + uint32_t MCR; /*!< Modem control register */ + uint32_t LSR; /*!< Line Status Register */ + uint32_t MSR; /*!< Modem status Register */ + uint32_t SCRATCHPAD; /*!< Uart scratch pad register */ + uint32_t LPDLL; /*!< Low Power Divisor Latch (Low) Reg */ + uint32_t LPDLH; /*!< Low Power Divisor Latch (High) Reg */ + uint32_t RES1[2]; /*!< Reserved */ + uint32_t SHR[16]; /*!< Shadow data register(SRBR and STHR) */ + uint32_t FAR; /*!< FIFO Access register */ + uint32_t TFR; /*!< Transmit FIFO Read */ + uint32_t RFW; /*!< Receive FIFO write */ + uint32_t USR; /*!< UART status register */ + uint32_t TFL; /*!< Transmit FIFO level */ + uint32_t RFL; /*!< Receive FIFO level */ + uint32_t SRR; /*!< Software reset register */ + uint32_t SRTS; /*!< Shadow request to send */ + uint32_t SBCR; /*!< Shadow break control */ + uint32_t SDMAM; /*!< Shadow DMA mode */ + uint32_t SFE; /*!< Shadow FIFO enable */ + uint32_t SRT; /*!< Shadow RCVR Trigger */ + uint32_t STET; /*!< Shadow TX empty register */ + uint32_t HTX; /*!< Halt TX */ + uint32_t DMASA; /*!< DMA Software ACK */ + uint32_t RES2[18]; /*!< Reserved */ + uint32_t CPR; /*!< Camponent parameter register */ + uint32_t UCV; /*!< UART Component Version */ + uint32_t CTR; /*!< Component typw register */ +} DW_UART_REG, *DW_UART_REG_PTR; +/** @} */ + +#define DW_UART_GINT_DISABLED (0) /*!< designware interrupt disabled for control uart irq/fiq */ +#define DW_UART_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control uart irq/fiq */ +#define DW_UART_TXINT_ENABLE (1<<1) /*!< designware interrupt enabled for control transmit process */ +#define DW_UART_RXINT_ENABLE (1<<2) /*!< designware interrupt enabled for control transmit process */ + +/** + * \brief DesignWare UART control structure definition + * \details implement of dev_uart_info::uart_ctrl + */ +typedef struct dw_uart_ctrl { + uint32_t dw_uart_regbase; /*!< uart ip register base */ + uint32_t dw_apb_bus_freq; /*!< uart ip apb bus frequency */ + uint32_t intno; /*!< uart interrupt vector number */ + INT_HANDLER dw_uart_int_handler; /*!< uart interrupt handler */ + uint32_t tx_fifo_len; /*!< transmit fifo length, set by user in object implementation */ + uint32_t rx_fifo_len; /*!< receive fifo length, set by user in object implementation */ + uint32_t int_status; /*!< interrupt status for designware uart */ +} DW_UART_CTRL, *DW_UART_CTRL_PTR; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name DesignWare UART Function Declaration + * \brief contains declarations of designware uart functions. + * \details This are only used in uart object implementation source file + * @{ + */ +extern int32_t dw_uart_open (DEV_UART *uart_obj, uint32_t baud); +extern int32_t dw_uart_close (DEV_UART *uart_obj); +extern int32_t dw_uart_control (DEV_UART *uart_obj, uint32_t ctrl_cmd, void *param); +extern int32_t dw_uart_write (DEV_UART *uart_obj, const void *data, uint32_t len); +extern int32_t dw_uart_read (DEV_UART *uart_obj, void *data, uint32_t len); +extern void dw_uart_isr(DEV_UART *uart_obj, void *ptr); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DW_UART_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h b/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h new file mode 100644 index 0000000000..367894df99 --- /dev/null +++ b/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h @@ -0,0 +1,253 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-20 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup DEVICE_DW_IIC + * \brief DesignWare UART driver hardware description related header file + * \details detailed hardware related definitions of DesignWare UART driver + */ + +#ifndef _DEVICE_DW_UART_HAL_H_ +#define _DEVICE_DW_UART_HAL_H_ + +/* DW APB UART bit definitions */ + +/** + * \name DesignWare UART HAL IER Marcos + * \brief DesignWare UART hal IER related macros + * @{ + */ +/* IER */ +#define DW_UART_IER_DATA_AVAIL (0x01) +#define DW_UART_IER_XMIT_EMPTY (0x02) +#define DW_UART_IER_LINE_STATUS (0x04) +#define DW_UART_IER_MDM_STATUS (0x08) +#define DW_UART_IER_PTIME (0x80) +/** @} */ + +/** + * \name DesignWare UART HAL IIR Marcos + * \brief DesignWare UART hal IIR related macros + * @{ + */ +/* IIR */ +/* IIR READ */ +#define DW_UART_IIR_IP (0x01) +#define DW_UART_IIR_MASK (0x0E) +#define DW_UART_IIR_READ_FIFO_ENABLE (0xC0) + +/* Possible interrupt IIR_MASK values */ +#define DW_UART_IIR_MDM_STATUS (0x00) +#define DW_UART_IIR_XMIT_EMPTY (0x02) +#define DW_UART_IIR_DATA_AVAIL (0x04) +#define DW_UART_IIR_LINE_STATUS (0x06) +#define DW_UART_IIR_RX_TIMEOUT (0x0C) +#define DW_UART_IIR_INT_ID_MASK (0x0f) + +/* IIR WRITE */ +#define DW_UART_IIR_FIFO_ENABLE (0x01) +#define DW_UART_IIR_RCVR_FIFO_RESET (0x02) +#define DW_UART_IIR_XMIT_FIFO_RESET (0x04) +#define DW_UART_IIR_DMA_MODE_SELECT (0x08) +#define DW_UART_IIR_RCV_TRIGGER_MASK (0xC0) + +/* Values for IIR receive trigger */ +#define DW_UART_IIR_TRIGGER_LEVEL_1_CHAR (0x00) +#define DW_UART_IIR_TRIGGER_LEVEL_1_4_FULL (0x40) +#define DW_UART_IIR_TRIGGER_LEVEL_1_2_FULL (0x80) +#define DW_UART_IIR_TRIGGER_LEVEL_2_LESS_FULL (0xC0) +/** @} */ + +/** + * \name DesignWare UART HAL LCR Marcos + * \brief DesignWare UART hal LCR related macros + * @{ + */ +/* LCR */ +#define DW_UART_LCR_WORD_LEN_MASK (0x03) +#define DW_UART_LCR_STOP_BIT_MASK (0x04) +#define DW_UART_LCR_PARITY_MASK (0x38) +#define DW_UART_LCR_DPS_MASK (0x3F) +#define DW_UART_LCR_STICK_PARITY (0x20) +#define DW_UART_LCR_BREAK (0x40) +#define DW_UART_LCR_DLAB (0x80) + +/* Word length values */ +#define DW_UART_LCR_WORD_LEN5 (0x00) +#define DW_UART_LCR_WORD_LEN6 (0x01) +#define DW_UART_LCR_WORD_LEN7 (0x02) +#define DW_UART_LCR_WORD_LEN8 (0x03) + +/* stop bit values */ +#define DW_UART_LCR_1_STOP_BIT (0x00) +#define DW_UART_LCR_1D5_STOP_BIT (0x04) +#define DW_UART_LCR_2_STOP_BIT (0x04) + +/* Parity bit values */ +#define DW_UART_LCR_PARITY_NONE (0x00) +#define DW_UART_LCR_PARITY_ODD (0x08) +#define DW_UART_LCR_PARITY_EVEN (0x18) +#define DW_UART_LCR_PARITY_MARK (0x28) +#define DW_UART_LCR_PARITY_SPACE (0x38) + +/** @} */ + +/** + * \name DesignWare UART HAL MCR Marcos + * \brief DesignWare UART hal MCR related macros + * @{ + */ +/* MCR */ +#define DW_UART_MCR_DTR (0x01) +#define DW_UART_MCR_RTS (0x02) +#define DW_UART_MCR_LOOPBACK (0x10) +#define DW_UART_MCR_AFCE (0x20) +#define DW_UART_MCR_SIRE (0x40) +/** @} */ + +/** + * \name DesignWare UART HAL LSR Marcos + * \brief DesignWare UART hal LSR related macros + * @{ + */ +/* LSR */ +#define DW_UART_LSR_DR (0x01) +#define DW_UART_LSR_OVERRUN (0x02) +#define DW_UART_LSR_PARITYERR (0x04) +#define DW_UART_LSR_FRAMEERR (0x08) +#define DW_UART_LSR_BREAKRCVD (0x10) +#define DW_UART_LSR_TXD_EMPTY (0x20) +#define DW_UART_LSR_TX_STATUS (0x40) +#define DW_UART_LSR_RX_FIFOERR (0x80) +/** @} */ + +/** + * \name DesignWare UART HAL MSR Marcos + * \brief DesignWare UART hal MSR related macros + * @{ + */ +/* MSR */ +#define DW_UART_MSR_DCTS (0x01) +#define DW_UART_MSR_DDSR (0x02) +#define DW_UART_MSR_TERI (0x04) +#define DW_UART_MSR_DDCD (0x08) +#define DW_UART_MSR_CTS (0x10) +#define DW_UART_MSR_DSR (0x20) +#define DW_UART_MSR_RIC (0x40) +#define DW_UART_MSR_DCD (0x80) +/** @} */ + +/** + * \name DesignWare UART HAL FCR Marcos + * \brief DesignWare UART hal FCR related macros + * @{ + */ +/* FCR */ +#define DW_UART_FCR_FEN (0x01) +#define DW_UART_FCR_RFR (0x02) +#define DW_UART_FCR_TFR (0x04) +#define DW_UART_FCR_DMS (0x08) +#define DW_UART_FCR_RTL (0xC0) +/** @} */ + +/** + * \name DesignWare UART HAL USR Marcos + * \brief DesignWare UART hal USR related macros + * @{ + */ +/* USR */ +#define DW_UART_USR_BUSY (0x01) +#define DW_UART_USR_TFNF (0x02) +#define DW_UART_USR_TFE (0x04) +#define DW_UART_USR_RFNE (0x08) +#define DW_UART_USR_RFF (0x10) +/** @} */ + +/** + * \name DesignWare UART HAL SFE Marcos + * \brief DesignWare UART hal SFE related macros + * @{ + */ +/* SFE */ +#define DW_UART_SFE_SHADOW_FIFO_ENABLE (0x01) +/** @} */ + +/** + * \name DesignWare UART HAL SRR Marcos + * \brief DesignWare UART hal SRR related macros + * @{ + */ +/* SRR */ +#define DW_UART_SRR_UR (0x01) +#define DW_UART_SRR_RFR (0x02) +#define DW_UART_SRR_XFR (0x04) +/** @} */ + +/** + * \name DesignWare UART HAL SRT Marcos + * \brief DesignWare UART hal SRT related macros + * @{ + */ +/* SRT */ +#define DW_UART_SRT_TRIGGER_LEVEL_1_CHAR (0x00) +#define DW_UART_SRT_TRIGGER_LEVEL_1_4_FULL (0x01) +#define DW_UART_SRT_TRIGGER_LEVEL_1_2_FULL (0x02) +#define DW_UART_SRT_TRIGGER_LEVEL_2_LESS_FULL (0x03) +/** @} */ + +/** + * \name DesignWare UART HAL STET Marcos + * \brief DesignWare UART hal STET related macros + * @{ + */ +/* STET*/ +#define DW_UART_STET_FIFO_EMPTY (0x00) +#define DW_UART_STET_2_CHARS_IN_FIFO (0x01) +#define DW_UART_STET_1_4_FULL (0x02) +#define DW_UART_STET_1_2_FULL (0x03) +/** @} */ + +/** + * \name DesignWare UART HAL CPR Marcos + * \brief DesignWare UART hal CPR related macros + * @{ + */ +/* CPR*/ +#define DW_UART_CPR_FIFO_STAT (1<<10) +#define DW_UART_CPR_FIFO_MODE_OFS (16) +#define DW_UART_CPR_FIFO_MODE_MASK (0xFF) +#define DW_UART_CPR_FIFO_MODE (0xFF0000) +/** @} */ + +#endif /* _DEVICE_DW_UART_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h new file mode 100644 index 0000000000..623d54a611 --- /dev/null +++ b/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h @@ -0,0 +1,173 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-16 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_HAL_COMMON Common Device Layer Definitions + * \ingroup DEVICE_HAL_DEF + * \brief common definitions for device layer (\ref dev_common.h) + * + * @{ + * + * \file + * \brief header file to define common definitions for device layer + * \details Here in this file provide definitions that need by other + * devices in device layer + */ + +#ifndef _DEVICE_HAL_COMMON_H_ +#define _DEVICE_HAL_COMMON_H_ + +#include + +/** + * \defgroup DEVICE_HAL_COMMON_DEVSTATE Common Device State + * \ingroup DEVICE_HAL_COMMON + * \brief definitions for device state + * \details here defines macros for device open/close, + * device working good/error, used in + * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, + * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO + * @{ + */ +/* + * macros for device open and close state + */ +#define DEV_CLOSED (0) /*!< Indicate that device was closed */ +#define DEV_OPENED (1) /*!< Indicate that the device was opened */ + +/* + * macros for device good and error state + */ +#define DEV_GOOD (0) /*!< Indicate device is good */ +#define DEV_ERROR (1) /*!< Indicate device error */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_COMMON_DEVMTHD Common Device Working Method + * \ingroup DEVICE_HAL_COMMON + * \brief definitions for device working method(interrupt or poll) + * \details here defines macros for working method, + * interrupt or poll method,used in + * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, + * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO + * @{ + */ +/* + * macros for device working method + */ +#define DEV_POLL_METHOD (0) /*!< Indicate that the device running in poll method */ +#define DEV_INTERRUPT_METHOD (1) /*!< Indicate that the device running in interrupt method */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_COMMON_DEVMODE Common Device Working Mode + * \ingroup DEVICE_HAL_COMMON + * \brief definitions for device working mode(master or slave) + * \details here defines macros for working mode, + * Master or Slave mode,used in + * \ref DEV_HAL_IIC, \ref DEV_HAL_SPI. + * @{ + */ +/* + * macros for device working mode + */ +#define DEV_MASTER_MODE (0) /*!< Indicate that the device working as master */ +#define DEV_SLAVE_MODE (1) /*!< Indicate that the device working as slave */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_COMMON_DEVSTATUS Common Device Status + * \ingroup DEVICE_HAL_COMMON + * \brief definitions for device status, 1 bit for 1 function + * @{ + */ +#define DEV_DISABLED (0) /*!< Bit 0 for device enabled state, disabled */ +#define DEV_ENABLED (1<<0) /*!< Bit 0 for device enabled state, enabled */ +#define DEV_IN_TX (1<<1) /*!< Bit 1 for device in transmit state */ +#define DEV_IN_RX (1<<2) /*!< Bit 2 for device in receive state */ +#define DEV_IN_XFER (1<<3) /*!< Bit 3 for device in transfer state */ +#define DEV_IN_TX_ABRT (1<<4) /*!< Bit 4 for device in transmit abort state */ +#define DEV_IN_RX_ABRT (1<<5) /*!< Bit 5 for device in receive abort state */ +#define DEV_IN_XFER_ABRT (1<<6) /*!< Bit 6 for device in transfer abort state */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_COMMON_DEFCMD Common Device Defining Command + * \ingroup DEVICE_HAL_COMMON + * \brief definitions for defining command code + * \details here defines macros to define command code, + * in system code, use \ref DEV_SET_SYSCMD to define command code. + * in user code, use \ref DEV_SET_USRCMD to define command code. + * So that there will be no conflicts in system and user defined command code. + * this used used in + * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, + * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO, + * and in user code + * @{ + */ +/* + * macros for control command base + */ +#define DEV_SYS_CMDBSE (0x00000000) /*!< default system device control command base(defined by embARC) */ +#define DEV_USR_CMDBSE (0x80000000) /*!< default user device control command base(defined by user) in user implementing */ +#define DEV_SET_SYSCMD(cmd) (DEV_SYS_CMDBSE|(cmd)) /*!< set device system control command */ +#define DEV_SET_USRCMD(cmd) (DEV_USR_CMDBSE|(cmd)) /*!< set device user control command */ + +#define CONV2VOID(param) ((void *)(param)) /*!< convert param into void * type */ +/** @} */ + +/** + * Common Device Buffer Structure + */ +typedef struct dev_buffer { + void *buf; /*!< buffer pointer */ + uint32_t len; /*!< buffer length in bytes */ + uint32_t ofs; /*!< current offset in buffer */ +} DEV_BUFFER; + +/** Init device buffer */ +#define DEV_BUFFER_INIT(devbuf, buffer, size) { \ + (devbuf)->buf = (void *)(buffer); \ + (devbuf)->len = (uint32_t)(size); \ + (devbuf)->ofs = (uint32_t)(0); \ + } + +/** + * Device callback function typedef. + * This is usually used in device callback settings, + * and \ptr should be the device object pointer, + * such as DEV_IIC * */ +typedef void (*DEV_CALLBACK) (void *ptr); + +/** @} */ +#endif /* _DEVICE_HAL_COMMON_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h new file mode 100644 index 0000000000..290fd313a2 --- /dev/null +++ b/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h @@ -0,0 +1,424 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-17 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_HAL_GPIO GPIO Device HAL Interface + * \ingroup DEVICE_HAL_DEF + * \brief definitions for gpio device hardware layer (\ref dev_gpio.h) + * \details provide interfaces for gpio driver to implement + * Here is a diagram for the gpio interface. + * + * \htmlonly + *
+ *
+ * GPIO Device HAL Interface Diagram + *

GPIO Device HAL Interface Diagram

+ *
+ *
+ * \endhtmlonly + * + * @{ + * + * \file + * \brief gpio device hardware layer definitions + * \details Provide common definitions for gpio device, + * then the software developer can develop gpio driver + * following these definitions, and the applications + * can directly call this definition to realize functions + * + */ + +#ifndef _DEVICE_HAL_GPIO_H_ +#define _DEVICE_HAL_GPIO_H_ + +#include "device/device_hal/inc/dev_common.h" + +/** + * \defgroup DEVICE_HAL_GPIO_DEFDIR GPIO Port Direction Definition + * \ingroup DEVICE_HAL_GPIO + * \brief Define macros to indicate gpio directions + * @{ + */ +/* + * defines for gpio directions + */ +#define GPIO_DIR_INPUT (0) /*!< gpio works as input */ +#define GPIO_DIR_OUTPUT (1) /*!< gpio works as output */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_GPIO_CTRLCMD GPIO Device Control Commands + * \ingroup DEVICE_HAL_GPIO + * \brief Definitions for gpio control command, used in \ref dev_gpio::gpio_control "GPIO IO Control" + * \details These commands defined here can be used in user code directly. + * - Parameters Usage + * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values + * - For passing parameters for a structure, please use pointer to pass values + * - For getting some data, please use pointer to store the return data + * - Common Return Values + * - \ref E_OK, Control device successfully + * - \ref E_CLSED, Device is not opened + * - \ref E_OBJ, Device object is not valid or not exists + * - \ref E_PAR, Parameter is not valid for current control command + * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled + * - \ref E_NOSPT, Control command is not supported or not valid + * @{ + */ +/** + * Set the \ref dev_gpio_info::direction "direction" of masked bits of gpio port into \ref GPIO_DIR_INPUT "input" + * - Param type : uint32_t + * - Param usage : 1 in each bit will be masked. + * - Return value explanation : + */ +#define GPIO_CMD_SET_BIT_DIR_INPUT DEV_SET_SYSCMD(0) +/** + * Set the \ref dev_gpio_info::direction "direction" of masked bits of gpio port into \ref GPIO_DIR_OUTPUT "output" + * - Param type : uint32_t + * - Param usage : 1 in each bit will be masked. + * - Return value explanation : + */ +#define GPIO_CMD_SET_BIT_DIR_OUTPUT DEV_SET_SYSCMD(1) +/** + * Get \ref dev_gpio_info::direction "gpio port direction". + * - Param type : uint32_t + * - Param usage : 1 bit for 1 bit of gpio port, 0 for input, 1 for output + * - Return value explanation : + */ +#define GPIO_CMD_GET_BIT_DIR DEV_SET_SYSCMD(2) +/** + * Set gpio interrupt configuration for each bit. + * - Param type : \ref DEV_GPIO_INT_CFG * + * - Param usage : store gpio interrupt configuration for each bit. + * - Return value explanation : + */ +#define GPIO_CMD_SET_BIT_INT_CFG DEV_SET_SYSCMD(3) +/** + * Get gpio interrupt configuration for each bit. + * - Param type : \ref DEV_GPIO_INT_CFG * + * - Param usage : First set int_bit_mask in DEV_GPIO_INT_CFG structure to + * the mask of which bit of GPIO you want to get. And the interrupt configuration + * will be stored in the structure DEV_GPIO_INT_CFG, each bit stand for each bit of port. + * - Return value explanation : + */ +#define GPIO_CMD_GET_BIT_INT_CFG DEV_SET_SYSCMD(4) +/** + * Set gpio service routine for each bit. + * - Param type : \ref DEV_GPIO_BIT_ISR * + * - Param usage : store gpio handler information for each bit, int handler's param will be DEV_GPIO *. + * - Return value explanation : + */ +#define GPIO_CMD_SET_BIT_ISR DEV_SET_SYSCMD(5) +/** + * Get gpio service routine for each bit. + * - Param type : \ref DEV_GPIO_BIT_ISR * + * - Param usage : By passing int_bit_ofs in DEV_GPIO_BIT_ISR, + * it will return interrupt handler for this bit and store it in int_bit_handler. + * - Return value explanation : + */ +#define GPIO_CMD_GET_BIT_ISR DEV_SET_SYSCMD(6) +/** + * Enable gpio interrupt of the masked bits. + * - Param type : uint32_t + * - Param usage : 1 in each bit will be masked. + * - Return value explanation : + */ +#define GPIO_CMD_ENA_BIT_INT DEV_SET_SYSCMD(7) +/** + * Disable gpio interrupt of the masked bits. + * - Param type : uint32_t + * - Param usage : 1 in each bit will be masked. + * - Return value explanation : + */ +#define GPIO_CMD_DIS_BIT_INT DEV_SET_SYSCMD(8) +/** + * Get \ref dev_gpio_info::method "gpio interrupt enable status". + * - Param type : uint32_t * + * - Param usage : 1 bit for 1 bit of gpio port, 0 for poll, 1 for interrupt + * - Return value explanation : + */ +#define GPIO_CMD_GET_BIT_MTHD DEV_SET_SYSCMD(9) +/* @} */ + +/** + * \defgroup DEVICE_HAL_GPIO_INT_CFG_SET GPIO Device Int Configuration Settings + * \ingroup DEVICE_HAL_GPIO + * \brief definition of gpio interrupt type + * @{ + */ + +/* GPIO Mask Defintions */ +/** Mask none bits of the max 32bits */ +#define GPIO_BITS_MASK_NONE (0) +/** Mask all bits of the max 32bits */ +#define GPIO_BITS_MASK_ALL (0XFFFFFFFF) + +/* GPIO Interrupt Type Related Definitions */ + +/** Level sensitive interrupt type for 1 bit */ +#define GPIO_INT_LEVEL_TRIG (0) +/** Edge sensitive interrupt type for 1 bit */ +#define GPIO_INT_EDGE_TRIG (1) +/** Level sensitive interrupt type for all 32 bits */ +#define GPIO_INT_LEVEL_TRIG_ALL (0) +/** Edge sensitive interrupt type for all 32 bits */ +#define GPIO_INT_EDGE_TRIG_ALL (0XFFFFFFFF) + +/* For bit settings */ +/** Set bit interrupt type of gpio into level sensitive */ +#define GPIO_INT_BIT_LEVEL_TRIG(bit_ofs) (GPIO_INT_LEVEL_TRIG<<(bit_ofs)) +/** Set bit interrupt type of gpio into edge sensitive */ +#define GPIO_INT_BIT_EDGE_TRIG(bit_ofs) (GPIO_INT_EDGE_TRIG<<(bit_ofs)) +/* For bits settings */ +/** Set interrupt type of masked bits of gpio into level sensitive */ +#define GPIO_INT_BITS_LEVEL_TRIG(bit_mask) (GPIO_INT_LEVEL_TRIG_ALL&(bit_mask)) +/** Set bit interrupt type of gpio into edge sensitive */ +#define GPIO_INT_BITS_EDGE_TRIG(bit_mask) (GPIO_INT_EDGE_TRIG_ALL&(bit_mask)) + +/* GPIO Interrupt Polarity Related Definitions */ + +/** GPIO Interrupt polarity type enum */ +typedef enum gpio_int_polarity { + /* Polarity for 1 bit */ + GPIO_INT_ACTIVE_LOW = 0, /*!< Active low for level-sensitive interrupt for 1 bit */ + GPIO_INT_FALLING_EDGE = 0, /*!< Falling-edge for edge-sensitive interrupt for 1 bit */ + GPIO_INT_ACTIVE_HIGH = 1, /*!< Active high for level-sensitive interrupt for 1 bit */ + GPIO_INI_RISING_EDGE = 1, /*!< Rising-edge for edge-sensitive interrupt for 1 bit */ + /* Polartiy for all 32 bits */ + GPIO_INT_ACTIVE_LOW_ALL = 0, /*!< Active low for level-sensitive interrupt for all bits */ + GPIO_INT_FALLING_EDGE_ALL = 0, /*!< Falling-edge for edge-sensitive interrupt for all bits */ + GPIO_INT_ACTIVE_HIGH_ALL = 0XFFFFFFFF, /*!< Active high for level-sensitive interrupt for all bits */ + GPIO_INI_RISING_EDGE_ALL = 0XFFFFFFFF /*!< Rising-edge for edge-sensitive interrupt for all bits */ +} GPIO_INT_POLARITY; + +/* For bit settings */ +/** Set bit polarity of gpio into active low */ +#define GPIO_INT_BIT_POL_ACT_LOW(bit_ofs) (GPIO_INT_ACTIVE_LOW<<(bit_ofs)) +/** Set bit polarity of gpio into active high */ +#define GPIO_INT_BIT_POL_ACT_HIGH(bit_ofs) (GPIO_INT_ACTIVE_HIGH<<(bit_ofs)) +/** Set bit polarity of gpio into falling edge */ +#define GPIO_INT_BIT_POL_FALL_EDGE(bit_ofs) (GPIO_INT_FALLING_EDGE<<(bit_ofs)) +/** Set bit polarity of gpio into rising edge */ +#define GPIO_INT_BIT_POL_RISE_EDGE(bit_ofs) (GPIO_INI_RISING_EDGE<<(bit_ofs)) + +/* For bits settings */ +/** Set polarity of masked bits of gpio into active low */ +#define GPIO_INT_BITS_POL_ACT_LOW(bit_mask) (GPIO_INT_ACTIVE_LOW_ALL&(bit_mask)) +/** Set polarity of masked bits of gpio into active high */ +#define GPIO_INT_BITS_POL_ACT_HIGH(bit_mask) (GPIO_INT_ACTIVE_HIGH_ALL&(bit_mask)) +/** Set polarity of masked bits of gpio into falling edge */ +#define GPIO_INT_BITS_POL_FALL_EDGE(bit_mask) (GPIO_INT_FALLING_EDGE_ALL&(bit_mask)) +/** Set polarity of masked bits of gpio into rising edge */ +#define GPIO_INT_BITS_POL_RISE_EDGE(bit_mask) (GPIO_INI_RISING_EDGE_ALL&(bit_mask)) + +/* GPIO Interrupt Debounce Related Definitions */ + +/* For bit settings */ +/** Disable debounce circuitry for 1 bit */ +#define GPIO_INT_NO_DEBOUNCE (0) +/** Enable debounce circuitry for 1 bit */ +#define GPIO_INT_DEBOUNCE (1) + +/* For bits settings */ +/** Disable debounce circuitry for all bits */ +#define GPIO_INT_NO_DEBOUNCE_ALL (0) +/** Enable debounce circuitry for all bits */ +#define GPIO_INT_DEBOUNCE_ALL (0XFFFFFFFF) + +/* For bit settings */ +/** Set bit interrupt debounce of gpio into enabled */ +#define GPIO_INT_BIT_ENA_DEBOUNCE(bit_ofs) (GPIO_INT_DEBOUNCE<<(bit_ofs)) +/** Set bit interrupt debounce of gpio into disabled */ +#define GPIO_INT_BIT_DIS_DEBOUNCE(bit_ofs) (GPIO_INT_NO_DEBOUNCE<<(bit_ofs)) +/* For bits settings */ +/** Set bit interrupt debounce of gpio into enabled */ +#define GPIO_INT_BITS_ENA_DEBOUNCE(bit_mask) (GPIO_INT_DEBOUNCE_ALL&(bit_mask)) +/** Set bit interrupt debounce of gpio into disabled */ +#define GPIO_INT_BITS_DIS_DEBOUNCE(bit_mask) (GPIO_INT_NO_DEBOUNCE_ALL&(bit_mask)) + +/** GPIO interrupt configuration */ +typedef struct dev_gpio_int_cfg { + uint32_t int_bit_mask; /*!< interrupt bit mask for gpio */ + uint32_t int_bit_type; /*!< \ref GPIO_INT_LEVEL_TRIG "level sensitive" or \ref GPIO_INT_EDGE_TRIG "edge sensitive" for each gpio bit */ + uint32_t int_bit_polarity; /*!< active high or low, refer to \ref GPIO_INT_POLARITY for each gpio bit */ + uint32_t int_bit_debounce; /*!< \ref GPIO_INT_DEBOUNCE "enable" or \ref GPIO_INT_NO_DEBOUNCE "disable" debounce logic for each gpio bit */ +} DEV_GPIO_INT_CFG, * DEV_GPIO_INT_CFG_PTR; + +/** Default interrupt configuration for all gpio bits */ +static const DEV_GPIO_INT_CFG gpio_int_cfg_default = \ + {GPIO_BITS_MASK_ALL, GPIO_INT_LEVEL_TRIG_ALL, \ + GPIO_INT_ACTIVE_LOW_ALL, GPIO_INT_NO_DEBOUNCE_ALL}; + +/** GPIO interrupt handler or Interrupt Service Routine(ISR) */ +typedef void (*DEV_GPIO_HANDLER) (void *ptr); + +/** interrupt handler for each port bit */ +typedef struct dev_gpio_bit_isr { + uint32_t int_bit_ofs; /*!< int bit offset */ + DEV_GPIO_HANDLER int_bit_handler; /*!< interrupt handler */ +} DEV_GPIO_BIT_ISR, * DEV_GPIO_BIT_ISR_PTR; +/* @} */ + +/** + * \defgroup DEVICE_HAL_GPIO_DEVSTRUCT GPIO Device Interface Definition + * \ingroup DEVICE_HAL_GPIO + * \brief contains definitions of gpio device structure. + * \details This structure will be used in user implemented code, which was called + * \ref DEVICE_IMPL "Device Driver Implement Layer" for gpio to use in implementation code. + * Application developer should use the GPIO API provided here to access to GPIO devices. + * BSP developer should follow the API definition to implement GPIO device drivers. + * @{ + */ +/** + * \brief gpio information struct definition + * \details informations about gpio open count, working status + * gpio registers and control block, gpio io direction and interrupt/poll for each bit of gpio + * \note Only available for gpio with max 32bits + */ +typedef struct dev_gpio_info { + void *gpio_ctrl; /*!< gpio control related pointer, implemented by bsp developer, and this should be set during gpio object implementation */ + uint32_t opn_cnt; /*!< gpio open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ + uint32_t direction; /*!< each bit direction of this GPIO, default all \ref GPIO_DIR_INPUT "input" for first open */ + uint32_t method; /*!< int/poll method for each bit of GPIO, 0 for poll, 1 for interrupt, default all \ref DEV_POLL_METHOD "poll" for first open */ + void * extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, + this should be NULL for first open and you can \ref DEV_GPIO_INFO_SET_EXTRA_OBJECT "set" + or \ref DEV_GPIO_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ +} DEV_GPIO_INFO, * DEV_GPIO_INFO_PTR; +/** Set extra information pointer of gpio info */ +#define DEV_GPIO_INFO_SET_EXTRA_OBJECT(gpio_info_ptr, extra_info) (gpio_info_ptr)->extra = (void *)(extra_info) +/** Get extra information pointer of gpio info */ +#define DEV_GPIO_INFO_GET_EXTRA_OBJECT(gpio_info_ptr) ((gpio_info_ptr)->extra) + +/** Method of all gpio bits set to poll */ +#define DEV_GPIO_BITS_MTHD_POLL (0) +/** Method of all gpio bits set to interrupt */ +#define DEV_GPIO_BITS_MTHD_INTERRUPT (0xFFFFFFFF) +/** Default method of all gpio bits should be poll for first open */ +#define DEV_GPIO_BITS_MTHD_DEFAULT (DEV_GPIO_BITS_MTHD_POLL) + +/** + * \brief gpio device interface definition + * \details define gpio device interface, like gpio information structure, + * fuctions to open/close/control gpio, write or read data via gpio + * \note all this details are implemented by user in user porting code + */ +typedef struct dev_gpio { + DEV_GPIO_INFO gpio_info; /*!< gpio device information */ + int32_t (*gpio_open) (uint32_t dir); /*!< open gpio device with pre-defined gpio direction */ + int32_t (*gpio_close) (void); /*!< close gpio device */ + int32_t (*gpio_control) (uint32_t ctrl_cmd, void *param); /*!< control gpio device */ + int32_t (*gpio_write) (uint32_t val, uint32_t mask); /*!< write gpio device with val, only write the masked bits */ + int32_t (*gpio_read) (uint32_t *val, uint32_t mask); /*!< read gpio device val, only read the masked bits */ +} DEV_GPIO, * DEV_GPIO_PTR; + +/** + * \fn int32_t (* dev_gpio::gpio_open) (uint32_t dir) + * \details Open a gpio device with pre-defined io direction. + * \param[in] dir gpio direction for each bit + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_gpio_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ + +/** + * \fn int32_t (* dev_gpio::gpio_close) (void) + * \details Close an gpio device, just decrease the \ref dev_gpio_info::opn_cnt "opn_cnt", + * if \ref dev_gpio_info::opn_cnt "opn_cnt" equals 0, then close the device + * \retval E_OK Close successfully without any issues(including scenario that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_gpio_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ + +/** + * \fn int32_t (* dev_gpio::gpio_control) (uint32_t ctrl_cmd, void *param) + * \details Control an gpio device by \ref ctrl_cmd, with passed \ref param. + * you can control gpio device using predefined gpio control commands defined using \ref DEV_SET_SYSCMD + * (which must be implemented by bsp developer), such as \ref GPIO_CMD_SET_BIT_DIR_INPUT + * "change masked gpio direction to input", and \ref DEVICE_HAL_GPIO_CTRLCMD "more". + * And you can also control gpio device using your own specified commands defined using \ref DEV_SET_USRCMD, + * but these specified commands should be defined in your own gpio device driver implementation. + * \param[in] ctrl_cmd \ref DEVICE_HAL_GPIO_CTRLCMD "control command", to change or get some thing related to gpio + * \param[in,out] param parameters that maybe argument of the command, or return values of the command + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid, such as interrupt is not supported + */ + +/** + * \fn int32_t (* dev_gpio::gpio_write) (uint32_t val, uint32_t mask) + * \details Write gpio with \ref val, and only change the masked bits of gpio. + * \param[in] val the data that need to write to gpio + * \param[in] mask gpio bit mask + * \retval E_OK Write gpio with specified value successfully + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + */ + +/** + * \fn int32_t (* dev_gpio::gpio_read) (uint32_t *val, uint32_t mask) + * \details Read the masked gpio value + * \param[out] val pointer to data need to read from gpio + * \param[in] mask gpio bit mask + * \retval E_OK Read gpio data successfully + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + */ + +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief get an \ref dev_gpio "gpio device" by gpio device id. + * For how to use gpio device hal refer to \ref dev_gpio "Functions in gpio device structure" + * \param[in] gpio_id id of gpio, defined by user + * \retval !NULL pointer to an \ref dev_gpio "gpio device structure" + * \retval NULL failed to find the gpio device by \ref gpio_id + * \note need to implemented by user in user code + */ +extern DEV_GPIO_PTR gpio_get_dev(int32_t gpio_id); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* _DEVICE_HAL_GPIO_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h new file mode 100644 index 0000000000..14106671ff --- /dev/null +++ b/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h @@ -0,0 +1,526 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-16 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_HAL_IIC IIC Device HAL Interface + * \ingroup DEVICE_HAL_DEF + * \brief definitions for iic device hardware layer (\ref dev_iic.h) + * \details provide interfaces for iic driver to implement + * Here is a diagram for the iic interface. + * + * \htmlonly + *
+ *
+ * IIC Device HAL Interface Diagram + *

IIC Device HAL Interface Diagram

+ *
+ *
+ * \endhtmlonly + * + * @{ + * + * \file + * \brief iic device hardware layer definitions + * \details provide common definitions for iic device, + * then software developer can develop iic driver + * following this definitions, and the applications + * can directly call this definition to realize functions + */ + +#ifndef _DEVICE_HAL_IIC_H_ +#define _DEVICE_HAL_IIC_H_ + +#include "device/device_hal/inc/dev_common.h" + +/** + * \defgroup DEVICE_HAL_IIC_CFG IIC Related Configurations + * \ingroup DEVICE_HAL_IIC + * \brief Macros for IIC device related configurations. + * @{ + */ +/** IIC Bus possible speed modes */ +typedef enum iic_speed_mode { + IIC_SPEED_STANDARD = 0, /*!< Bidirectional, Standard-mode (Sm), with a bit rate up to 100 kbit/s */ + IIC_SPEED_FAST = 1, /*!< Bidirectional, Fast-mode (Fm), with a bit rate up to 400 kbit/s */ + IIC_SPEED_FASTPLUS = 2, /*!< Bidirectional, Fast-mode Plus (Fm+), with a bit rate up to 1 Mbit/s */ + IIC_SPEED_HIGH = 3, /*!< Bidirectional, High-speed mode (Hs-mode), with a bit rate up to 3.4 Mbit/s */ + IIC_SPEED_ULTRA = 4 /*!< Unidirectional(Write only), Ultra Fast-mode (UFm), with a bit rate up to 5 Mbit/s */ +} IIC_SPEED_MODE; + +/** IIC next Condition */ +typedef enum iic_next_condtion { + IIC_MODE_STOP = 0, /*!< Send a STOP condition after write/read operation */ + IIC_MODE_RESTART = 1 /*!< Send a RESTART condition after write/read operation */ +} IIC_NEXT_CONDTION; + +/** IIC Error State */ +typedef enum iic_error_state { + IIC_ERR_NONE = 0, /*!< Currently in iic device free state */ + IIC_ERR_LOST_BUS = 1, /*!< Master or slave lost bus during operation */ + IIC_ERR_ADDR_NOACK = 2, /*!< Slave address is sent but not addressed by any slave devices */ + IIC_ERR_DATA_NOACK = 3, /*!< Data in transfer is not acked when it should be acked */ + IIC_ERR_TIMEOUT = 4, /*!< Transfer timeout, no more data is received or sent */ + IIC_ERR_MSTSTOP = 5, /*!< Slave received a STOP condition from master device */ + IIC_ERR_UNDEF = 6 /*!< Undefined error cases */ +} IIC_ERROR_STATE; + +/** IIC Working State */ +typedef enum iic_working_state { + IIC_FREE = 0, /*!< Currently in iic device free state */ + IIC_IN_TX = 1, /*!< Currently in iic master transmit state */ + IIC_IN_RX = 2 /*!< Currently in iic master receive state */ +} IIC_WORKING_STATE; + +/** IIC Addressing Mode */ +typedef enum iic_address_mode { + IIC_7BIT_ADDRESS = 0, /*!< Use 7bit address mode */ + IIC_10BIT_ADDRESS = 1 /*!< Use 10bit address mode */ +} IIC_ADDRESS_MODE; + +/** IIC Slave State */ +typedef enum iic_slave_state { + IIC_SLAVE_STATE_FREE = 0, /*!< None state, in free */ + IIC_SLAVE_STATE_START = (1<<1), /*!< Start or Restart condition, clear it when read */ + IIC_SLAVE_STATE_STOP = (1<<2), /*!< Stop condition, clear it when read */ + IIC_SLAVE_STATE_RD_REQ = (1<<3), /*!< Read request from master, this will trigger the slave transmit callback */ + IIC_SLAVE_STATE_RD_DONE = (1<<4), /*!< Read request done from master, clear it when read */ + IIC_SLAVE_STATE_WR_REQ = (1<<5), /*!< Write request from master, this will trigger the slave receive callback */ + IIC_SLAVE_STATE_GC_REQ = (1<<6), /*!< General call request from master */ + IIC_SLAVE_STATE_ERROR = (1<<7) /*!< Error, clear it when read */ +} IIC_SLAVE_STATE; + +/** 7bit IIC address mask */ +#define IIC_7BIT_ADDRESS_MASK (0x7F) +/** 10bit IIC address mask */ +#define IIC_10BIT_ADDRESS_MASK (0x3FF) +/** @} */ + +/** + * \defgroup DEVICE_HAL_IIC_CTRLCMD IIC Device Control Commands + * \ingroup DEVICE_HAL_IIC + * \brief Definitions for iic control command, used in \ref dev_iic::iic_control "IIC IO Control" + * \details These commands defined here can be used in user code directly. + * - Parameters Usage + * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values + * - For passing parameters for a structure, please use pointer to pass values + * - For getting some data, please use pointer to store the return data + * - Common Return Values + * - \ref E_OK, Control device successfully + * - \ref E_CLSED, Device is not opened + * - \ref E_OBJ, Device object is not valid or not exists + * - \ref E_PAR, Parameter is not valid for current control command + * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled + * - \ref E_CTX, Control device failed, due to different reasons like in transfer state + * - \ref E_NOSPT, Control command is not supported or not valid + * @{ + */ + +/** Define IIC control commands for common usage */ +#define DEV_SET_IIC_SYSCMD(cmd) DEV_SET_SYSCMD((cmd)) +/** Define IIC control commands for master usage */ +#define DEV_SET_IIC_MST_SYSCMD(cmd) DEV_SET_SYSCMD(0x00004000|(cmd)) +/** Define IIC control commands for slave usage */ +#define DEV_SET_IIC_SLV_SYSCMD(cmd) DEV_SET_SYSCMD(0x00008000|(cmd)) + +/* ++++ Common commands for IIC Device ++++ */ +/** + * Get \ref dev_iic_info::status "current device status" + * - Param type : uint32_t * + * - Param usage : store result of current status + * - Return value explanation : + */ +#define IIC_CMD_GET_STATUS DEV_SET_IIC_SYSCMD(0) +/** + * Set \ref dev_iic_info::addr_mode "iic addressing mode". + * - Param type : uint32_t + * - Param usage : iic addressing mode, possible values can be found \ref IIC_ADDRESS_MODE "here" + * - Return value explanation : + */ +#define IIC_CMD_SET_ADDR_MODE DEV_SET_IIC_SYSCMD(1) +/** + * Set \ref dev_iic_cbs::tx_cb "iic transmit success callback" function + * when all required bytes are transmitted for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transmit success callback function for iic + * - Return value explanation : + */ +#define IIC_CMD_SET_TXCB DEV_SET_IIC_SYSCMD(2) +/** + * Set \ref dev_iic_cbs::rx_cb "iic receive success callback" function + * when all required bytes are received for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : receive success callback function for iic + * - Return value explanation : + */ +#define IIC_CMD_SET_RXCB DEV_SET_IIC_SYSCMD(3) +/** + * Set \ref dev_iic_cbs::err_cb "iic transfer error callback" function + * when something error happened for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transfer error callback function for iic + * - Return value explanation : + */ +#define IIC_CMD_SET_ERRCB DEV_SET_IIC_SYSCMD(4) +/** + * Set buffer for interrupt transmit, and it will set \ref dev_iic_info::tx_buf "tx_buf". + * - IIC master mode use case \n + * For master mode, if you set tx buffer to NULL, when tx interrupt is enabled and entered into tx interrupt, + * it will automatically disable the tx interrupt, so when you want to transfer something, you need to set the + * tx buffer to Non-NULL and enable tx interrupt, when the tx buffer is sent, it will disable the tx interrupt + * and call tx callback function if available. + * - IIC slave mode use case \n + * For slave mode, the tx buffer is not used, only tx callback function is used, and if tx callback is not set, + * then it will automatically disable the tx interrupt, if tx callback is set, it will call the tx callback function + * and you need to write or read in the tx callback function, to avoid meaningless waiting, you can use control command + * \ref IIC_CMD_GET_TXAVAIL to get how many bytes space existing in transmit fifo, and use iic_write to send the available + * bytes. + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set tx_buf to NULL + * - Return value explanation : + */ +#define IIC_CMD_SET_TXINT_BUF DEV_SET_IIC_SYSCMD(5) +/** + * Set buffer for interrupt receive, and it will set \ref dev_iic_info::rx_buf "rx_buf" + * - IIC master mode use case \n + * Similar to \ref IIC_CMD_SET_TXINT_BUF + * - IIC slave mode use case \n + * Similiar to \ref IIC_CMD_SET_TXINT_BUF + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set rx_buf to NULL + * - Return value explanation : + */ +#define IIC_CMD_SET_RXINT_BUF DEV_SET_IIC_SYSCMD(6) +/** + * Enable or disable transmit interrupt, + * for master mode, only one of tx and rx interrupt can be enabled, + * if tx interrupt is enabled, then rx interrupt can't be changed. + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define IIC_CMD_SET_TXINT DEV_SET_IIC_SYSCMD(7) +/** + * Enable or disable receive interrupt, + * for master mode, only one of tx and rx interrupt can be enabled, + * if rx interrupt is enabled, then tx interrupt can't be changed. + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define IIC_CMD_SET_RXINT DEV_SET_IIC_SYSCMD(8) +/** + * Abort current interrupt transmit operation if tx interrupt enabled, + * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_iic_info::status "status" variable, + * and call the transmit callback function, when tx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define IIC_CMD_ABORT_TX DEV_SET_IIC_SYSCMD(9) +/** + * Abort current interrupt receive operation if rx interrupt enabled, + * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_iic_info::status "status" variable, + * and call the receive callback function, when rx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define IIC_CMD_ABORT_RX DEV_SET_IIC_SYSCMD(10) +/** + * Do a software reset for IIC device, it will stop current transfer, + * and clear error state and bring device to normal state, set next condition to STOP + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define IIC_CMD_RESET DEV_SET_IIC_SYSCMD(11) +/** + * Flush iic device transmit buffer or fifo + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define IIC_CMD_FLUSH_TX DEV_SET_IIC_SYSCMD(12) +/** + * Flush iic device receive buffer or fifo + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define IIC_CMD_FLUSH_RX DEV_SET_IIC_SYSCMD(13) +/** + * Enable iic device + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define IIC_CMD_ENA_DEV DEV_SET_IIC_SYSCMD(14) +/** + * Disable iic device, when device is disabled, + * only \ref IIC_CMD_ENA_DEV, \ref IIC_CMD_DIS_DEV, + * \ref IIC_CMD_GET_STATUS and \ref IIC_CMD_RESET + * commands can be executed, other commands will return \ref E_SYS + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define IIC_CMD_DIS_DEV DEV_SET_IIC_SYSCMD(15) +/** + * Get how many bytes space in iic are available to transmit, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_iic::iic_write "iic_write" API to realize non-blocked write + * - Param type : int32_t * + * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available + * - Return value explaination : + */ +#define IIC_CMD_GET_TXAVAIL DEV_SET_IIC_SYSCMD(16) +/** + * Get how many bytes in iic are available to receive, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_iic::iic_read "iic_read" API to realize non-blocked read + * - Param type : int32_t * + * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available + * - Return value explanation : + */ +#define IIC_CMD_GET_RXAVAIL DEV_SET_IIC_SYSCMD(17) + +/* ++++ Master only commands for IIC Device ++++ */ +/** + * Set \ref dev_iic_info::speed_mode "iic speed mode". + * - Param type : uint32_t + * - Param usage : iic speed mode, possible values can be found \ref IIC_SPEED_MODE "here", + * and if passing mode is not supported, it will choose a lower supported speed mode + * - Return value explanation : + */ +#define IIC_CMD_MST_SET_SPEED_MODE DEV_SET_IIC_MST_SYSCMD(0) +/** + * Set next condition for following transmit or receive operation. + * For example, you can change next condition before iic_read or iic_write, + * then in iic_read/iic_write operation, it will send a STOP/RESTART condition + * after the last byte of this operation. For interrupt, this is similar. + * - Param type : uint32_t + * - Param usage : next condition can be \ref IIC_NEXT_CONDTION + * - Return value explanation : + */ +#define IIC_CMD_MST_SET_NEXT_COND DEV_SET_IIC_MST_SYSCMD(1) +/** + * Set target slave device address for selecting slave device + * - Param type : uint32_t + * - Param usage : target slave address value + * - Return value explanation : + */ +#define IIC_CMD_MST_SET_TAR_ADDR DEV_SET_IIC_MST_SYSCMD(2) + + +/* ++++ Slave only commands for IIC Device ++++ */ +/** + * Set slave address when working as slave iic device + * - Param type : uint32_t + * - Param usage : slave address value + * - Return value explanation : + */ +#define IIC_CMD_SLV_SET_SLV_ADDR DEV_SET_IIC_SLV_SYSCMD(0) +/** + * Get \ref iic_slave_state "slave state" when working as slave iic device + * - Param type : uint32_t * + * - Param usage : slave state + * - Return value explanation : + */ +#define IIC_CMD_SLV_GET_SLV_STATE DEV_SET_IIC_SLV_SYSCMD(1) + +/** @} */ + +/** + * \defgroup DEVICE_HAL_IIC_CALLBACK IIC Interrupt callback functions + * \ingroup DEVICE_HAL_IIC + * \brief callback function structure for IIC device + * @{ + */ +typedef struct dev_iic_cbs { + DEV_CALLBACK tx_cb; /*!< iic data transmit success required bytes callback */ + DEV_CALLBACK rx_cb; /*!< iic data receive success required bytes callback */ + DEV_CALLBACK err_cb; /*!< iic error callback */ +} DEV_IIC_CBS, *DEV_IIC_CBS_PTR; +/** @} */ + +/** + * \defgroup DEVICE_HAL_IIC_DEVSTRUCT IIC Device Structure + * \ingroup DEVICE_HAL_IIC + * \brief contains definitions of iic device structure. + * \details this structure will be used in user implemented code, which was called + * Device Driver Implement Layer for iic to realize in user code. + * @{ + */ +/** + * \brief iic information struct definition + * \details informations about iic open state, working state, + * baurate, iic registers, working method, interrupt number + */ +typedef struct dev_iic_info { + void *iic_ctrl; /*!< iic control related pointer, implemented by bsp developer, and this should be set during iic object implementation */ + uint32_t opn_cnt; /*!< iic open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ + uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ + uint32_t mode; /*!< current working mode, which can be \ref DEV_MASTER_MODE "master mode" or \ref DEV_SLAVE_MODE "slave mode" */ + uint32_t speed_mode; /*!< current working \ref IIC_SPEED_MODE "iic speed mode" */ + uint32_t cur_state; /*!< \ref IIC_WORKING_STATE "current working state for iic device", this should be \ref IIC_FREE for first open */ + uint32_t err_state; /*!< \ref IIC_ERROR_STATE "current error state for iic device", this should be \ref IIC_ERR_NONE for first open */ + uint32_t addr_mode; /*!< \ref IIC_ADDRESS_MODE "current addressing mode", this should be \ref IIC_7BIT_ADDRESS for first open */ + uint32_t slv_addr; /*!< slave address when working as slave iic device, this should be 0 for first open */ + uint32_t tar_addr; /*!< target slave device address when addressing that slave device, this should be 0 for first open */ + uint32_t next_cond; /*!< \ref IIC_NEXT_CONDTION "next condition for master transmit or receive", \ + possible values are STOP or RESTART, it should be STOP for first open */ + DEV_BUFFER tx_buf; /*!< transmit buffer via interrupt, this should be all zero for first open */ + DEV_BUFFER rx_buf; /*!< receive buffer via interrupt, this should be all zero for first open */ + DEV_IIC_CBS iic_cbs; /*!< iic callbacks, for both master and slave mode, this should be all NULL for first open */ + void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, + this should be NULL for first open and you can \ref DEV_IIC_INFO_SET_EXTRA_OBJECT "set" + or \ref DEV_IIC_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ +} DEV_IIC_INFO, * DEV_IIC_INFO_PTR; + +/** Set extra information pointer of iic info */ +#define DEV_IIC_INFO_SET_EXTRA_OBJECT(iic_info_ptr, extra_info) (iic_info_ptr)->extra = (void *)(extra_info) +/** Get extra information pointer of iic info */ +#define DEV_IIC_INFO_GET_EXTRA_OBJECT(iic_info_ptr) ((iic_info_ptr)->extra) + +/** + * \brief iic device interface definition + * \details define iic device interface, like iic information structure, + * fuctions to get iic info, open/close/control iic, send/receive data by iic + * \note all this details are implemented by user in user porting code + */ +typedef struct dev_iic { + DEV_IIC_INFO iic_info; /*!< iic device information */ + int32_t (*iic_open) (uint32_t mode, uint32_t param); /*!< open iic device in master/slave mode, \ + when in master mode, param stands for speed mode, \ + when in slave mode, param stands for slave address */ + int32_t (*iic_close) (void); /*!< close iic device */ + int32_t (*iic_control) (uint32_t ctrl_cmd, void *param);/*!< control iic device */ + int32_t (*iic_write) (const void *data, uint32_t len); /*!< send data by iic device (blocking method) */ + int32_t (*iic_read) (void *data, uint32_t len); /*!< read data from iic device (blocking method) */ +} DEV_IIC, * DEV_IIC_PTR; + +/** + * \fn int32_t (* dev_iic::iic_open) (uint32_t mode, uint32_t param) + * \details open an iic device with selected mode (master or slave) with defined \ref param + * \param[in] mode working mode (\ref DEV_MASTER_MODE "master" or \ref DEV_SLAVE_MODE "slave") + * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_iic_info::speed_mode "speed mode", + * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_iic_info::slv_addr "slave device 7bit address" + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_iic_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ + +/** + * \fn int32_t (* dev_iic::iic_close) (void) + * \details close an iic device, just decrease the \ref dev_iic_info::opn_cnt "opn_cnt", + * if \ref dev_iic_info::opn_cnt "opn_cnt" equals 0, then close the device + * \retval E_OK Close successfully without any issues(including scenario that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_iic_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ + +/** + * \fn int32_t (* dev_iic::iic_control) (uint32_t ctrl_cmd, void *param) + * \details control an iic device by \ref ctrl_cmd, with passed \ref param. + * you can control iic device using predefined iic control commands defined using \ref DEV_SET_SYSCMD + * (which must be implemented by bsp developer), such as \ref IIC_CMD_SET_SPEED "set iic speed mode", + * \ref IIC_CMD_FLUSH_TX "flush tx" and \ref DEVICE_HAL_IIC_CTRLCMD "more". + * And you can also control iic device using your own specified commands defined using \ref DEV_SET_USRCMD, + * but these specified commands should be defined in your own iic device driver implementation. + * \param[in] ctrl_cmd \ref DEVICE_HAL_IIC_CTRLCMD "control command", to change or get some thing related to iic + * \param[in,out] param parameters that maybe argument of the command, + * or return values of the command, must not be NULL + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ + +/** + * \fn int32_t (* dev_iic::iic_write) (const void *data, uint32_t len) + * \details send \ref data through iic with defined \ref len to slave device which slave address is \ref slv_addr. + * \param[in] data pointer to data need to send by iic + * \param[in] len length of data to be sent + * \retval >0 Byte count that was successfully sent for poll method, + * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_CTX Device is still in transfer state + * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled + */ + +/** + * \fn int32_t (* dev_iic::iic_read) (void *data, uint32_t len) + * \details receive \ref data of defined \ref len through iic from slave device which slave address is \ref slv_addr. + * \param[out] data pointer to data need to received by iic + * \param[in] len length of data to be received + * \retval >0 Byte count that was successfully received for poll method, + * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". + * \retval E_OBJ Device object is not valid or not exists + * \retval E_CTX Device is still in transfer state + * \retval E_PAR Parameter is not valid + * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled + */ +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief get an \ref dev_iic "iic device" by iic device id. + * For how to use iic device hal refer to \ref DEVICE_HAL_IIC_DEVSTRUCT "Functions in iic device structure" + * \param[in] iic_id id of iic, defined by user + * \retval !NULL pointer to an \ref dev_iic "iic device structure" + * \retval NULL failed to find the iic device by \ref iic_id + * \note need to implemented by user in user code + */ +extern DEV_IIC_PTR iic_get_dev(int32_t iic_id); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* _DEVICE_HAL_IIC_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h new file mode 100644 index 0000000000..4469654e54 --- /dev/null +++ b/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h @@ -0,0 +1,577 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-06-16 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_HAL_SPI SPI Device HAL Interface + * \ingroup DEVICE_HAL_DEF + * \brief definitions for spi device hardware layer (\ref dev_spi.h) + * \details provide interfaces for spi driver to implement + * Here is a diagram for the spi interface. + * + * \htmlonly + *
+ *
+ * SPI Device HAL Interface Diagram + *

SPI Device HAL Interface Diagram

+ *
+ *
+ * \endhtmlonly + * + * @{ + * + * \file + * \brief spi device hardware layer definitions + * \details provide common definitions for spi device, + * then software developer can develop spi driver + * following this definitions, and the applications + * can directly call this definition to realize functions + */ + +#ifndef _DEVICE_HAL_SPI_H_ +#define _DEVICE_HAL_SPI_H_ + +#include "device/device_hal/inc/dev_common.h" + + +/** + * \defgroup DEVICE_HAL_SPI_CTRLCMD SPI Device Control Commands + * \ingroup DEVICE_HAL_SPI + * \brief Definitions for spi control command, used in \ref dev_spi::spi_control "SPI IO Control" + * \details These commands defined here can be used in user code directly. + * - Parameters Usage + * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values + * - For passing parameters for a structure, please use pointer to pass values + * - For getting some data, please use pointer to store the return data + * - Common Return Values + * - \ref E_OK, Control device successfully + * - \ref E_CLSED, Device is not opened + * - \ref E_OBJ, Device object is not valid or not exists + * - \ref E_PAR, Parameter is not valid for current control command + * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled + * - \ref E_CTX, Control device failed, due to different reasons like in transfer state + * - \ref E_NOSPT, Control command is not supported or not valid + * - Usage Comment + * - For SPI poll or interrupt read/write/transfer operations, only 1 operation can be triggered. + * If there is a operation is running, any other operation will return \ref E_CTX + * - If SPI is in transfer, then the following operations may return \ref E_CTX. Like + * \ref SPI_CMD_SET_CLK_MODE, \ref SPI_CMD_SET_TXINT_BUF, \ref SPI_CMD_SET_RXINT_BUF, + * \ref SPI_CMD_SET_TXINT, \ref SPI_CMD_SET_RXINT, \ref SPI_CMD_ABORT_TX, \ref SPI_CMD_ABORT_RX, + * \ref SPI_CMD_FLUSH_TX, \ref SPI_CMD_FLUSH_RX, \ref SPI_CMD_SET_DFS, \ref SPI_CMD_TRANSFER_POLLING, + * \ref SPI_CMD_TRANSFER_INT, \ref SPI_CMD_ABORT_XFER, \ref SPI_CMD_MST_SEL_DEV, \ref SPI_CMD_MST_DSEL_DEV, + * \ref SPI_CMD_MST_SET_FREQ and \ref dev_spi::spi_write "SPI Poll Write" or \ref dev_spi::spi_read "SPI Poll Read". + * @{ + */ + +/** Define SPI control commands for common usage */ +#define DEV_SET_SPI_SYSCMD(cmd) DEV_SET_SYSCMD((cmd)) +/** Define SPI control commands for master usage */ +#define DEV_SET_SPI_MST_SYSCMD(cmd) DEV_SET_SYSCMD(0x00001000|(cmd)) +/** Define SPI control commands for slave usage */ +#define DEV_SET_SPI_SLV_SYSCMD(cmd) DEV_SET_SYSCMD(0x00002000|(cmd)) + + +/* ++++ Common commands for SPI Device ++++ */ +/** + * Get \ref dev_spi_info::status "current device status" + * - Param type : uint32_t * + * - Param usage : store result of current status + * - Return value explanation : + */ +#define SPI_CMD_GET_STATUS DEV_SET_SPI_SYSCMD(0) +/** + * set the \ref dev_spi_info::clk_mode "clock mode" of spi transfer + * - Param type : uint32_t + * - Param usage : spi clock mode to choose clock phase and clock polarity + * - Return value explanation : + */ +#define SPI_CMD_SET_CLK_MODE DEV_SET_SPI_SYSCMD(1) +/** + * set spi \ref dev_spi_info::dfs "data frame size" + * - Param type : uint32_t + * - Param usage : should > 0 + * - Return value explanation : If dfs is not supported, then return \ref E_SYS + */ +#define SPI_CMD_SET_DFS DEV_SET_SPI_SYSCMD(2) +/** + * set the \ref dev_spi_info::dummy "dummy data" during spi transfer + * - Param type : uint32_t + * - Param usage : dummy data to transfer + * - Return value explanation : + */ +#define SPI_CMD_SET_DUMMY_DATA DEV_SET_SPI_SYSCMD(3) +/** + * Set \ref dev_spi_cbs::tx_cb "spi transmit success callback" function + * when all required bytes are transmitted for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transmit success callback function for spi + * - Return value explanation : + */ +#define SPI_CMD_SET_TXCB DEV_SET_SPI_SYSCMD(4) +/** + * Set \ref dev_spi_cbs::rx_cb "spi receive success callback" function + * when all required bytes are received for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : receive success callback function for spi + * - Return value explanation : + */ +#define SPI_CMD_SET_RXCB DEV_SET_SPI_SYSCMD(5) +/** + * Set \ref dev_spi_cbs::xfer_cb "spi transfer success callback" function + * when all required transfer are done for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transfer success callback function for spi + * - Return value explanation : + */ +#define SPI_CMD_SET_XFERCB DEV_SET_SPI_SYSCMD(6) +/** + * Set \ref dev_spi_cbs::err_cb "spi transfer error callback" function + * when something error happened for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transfer error callback function for spi + * - Return value explanation : + */ +#define SPI_CMD_SET_ERRCB DEV_SET_SPI_SYSCMD(7) +/** + * Set buffer in interrupt transmit, and it will set \ref dev_spi_info::xfer "spi tranfer". + * - SPI master and slave mode use case \n + * For both master and slave mode, if you set tx buffer to NULL, when tx interrupt is enabled and entered into tx interrupt, + * it will automatically disable the tx interrupt, so when you want to transfer something, you need to set the + * tx buffer to Non-NULL and enable tx interrupt, when the tx buffer is sent, it will disable the tx interrupt + * and call tx callback function if available. + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set xfer to empty + * - Return value explanation : + */ +#define SPI_CMD_SET_TXINT_BUF DEV_SET_SPI_SYSCMD(8) +/** + * Set buffer in interrupt receive, and it will set \ref dev_spi_info::xfer "spi tranfer". + * - SPI master mode use case \n + * Similar to \ref SPI_CMD_SET_TXINT_BUF + * - SPI slave mode use case \n + * Similiar to \ref SPI_CMD_SET_TXINT_BUF + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set xfer to empty + * - Return value explanation : + */ +#define SPI_CMD_SET_RXINT_BUF DEV_SET_SPI_SYSCMD(9) +/** + * Enable or disable transmit interrupt, + * for master mode, only one of tx and rx interrupt can be enabled, + * if tx interrupt is enabled, then rx interrupt can't be enabled. + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define SPI_CMD_SET_TXINT DEV_SET_SPI_SYSCMD(10) +/** + * Enable or disable receive interrupt, + * for master mode, only one of tx and rx interrupt can be enabled, + * if rx interrupt is enabled, then tx interrupt can't be enabled. + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define SPI_CMD_SET_RXINT DEV_SET_SPI_SYSCMD(11) +/** + * start the transfer by polling + * - Param type : \ref DEV_SPI_TRANSFER * + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_TRANSFER_POLLING DEV_SET_SPI_SYSCMD(12) +/** + * start the transfer by interrupt + * - Param type : \ref DEV_SPI_TRANSFER * or NULL + * - Param usage : If NULL, it will disable transfer interrupt, if not NULL, it will enable transfer interrupt + * - Return value explanation : + */ +#define SPI_CMD_TRANSFER_INT DEV_SET_SPI_SYSCMD(13) +/** + * Abort current interrupt transmit operation if tx interrupt enabled, + * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_spi_info::status "status" variable, + * and call the transmit callback function, when tx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_ABORT_TX DEV_SET_SPI_SYSCMD(14) +/** + * Abort current interrupt receive operation if rx interrupt enabled, + * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_spi_info::status "status" variable, + * and call the receive callback function, when rx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_ABORT_RX DEV_SET_SPI_SYSCMD(15) +/** + * Abort current interrupt transfer operation if transfer is issued, + * it will disable transfer interrupt, and set \ref DEV_IN_XFER_ABRT + * in \ref dev_spi_info::status "status" variable, + * and call the transfer callback function, when xfer callback is finished, + * it will clear \ref DEV_IN_XFER_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_ABORT_XFER DEV_SET_SPI_SYSCMD(16) +/** + * Do a software reset for SPI device, it will stop current transfer, + * and clear error state and bring device to normal state, set next condition to STOP + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_RESET DEV_SET_SPI_SYSCMD(17) +/** + * Flush spi tx fifo, this will clear the data in tx fifo + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_FLUSH_TX DEV_SET_SPI_SYSCMD(18) +/** + * Flush spi rx fifo, this will clear the data in rx fifo + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define SPI_CMD_FLUSH_RX DEV_SET_SPI_SYSCMD(19) +/** + * Enable spi device + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define SPI_CMD_ENA_DEV DEV_SET_SPI_SYSCMD(20) +/** + * Disable spi device, when device is disabled, + * only \ref SPI_CMD_ENA_DEV, \ref SPI_CMD_DIS_DEV, + * \ref SPI_CMD_GET_STATUS and \ref SPI_CMD_RESET + * commands can be executed, other commands will return \ref E_SYS + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define SPI_CMD_DIS_DEV DEV_SET_SPI_SYSCMD(21) +/** + * Get how many bytes space in spi are available to transmit, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_spi::spi_write "spi_write" API to realize non-blocked write + * - Param type : int32_t * + * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available + * - Return value explanation : + */ +#define SPI_CMD_GET_TXAVAIL DEV_SET_SPI_SYSCMD(22) +/** + * Get how many bytes in spi are available to receive, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_spi::spi_read "spi_read" API to realize non-blocked read + * - Param type : int32_t * + * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available + * - Return value explanation : + */ +#define SPI_CMD_GET_RXAVAIL DEV_SET_SPI_SYSCMD(23) + + +/* ++++ Master only commands for SPI Device ++++ */ +/** + * select spi slave device + * - Param type : uint32_t + * - Param usage : the number of spi slave device to select + * - Return value explanation : return \ref E_SYS when selection can't be done, return \ref E_CTX during transfer + */ +#define SPI_CMD_MST_SEL_DEV DEV_SET_SPI_MST_SYSCMD(0) +/** + * de-select spi slave device + * - Param type : uint32_t + * - Param usage : the number of spi slave device to de-select + * - Return value explanation : return \ref E_SYS when selection can't be done, return \ref E_CTX during transfer + */ +#define SPI_CMD_MST_DSEL_DEV DEV_SET_SPI_MST_SYSCMD(1) + /** + * Set \ref dev_spi_info::freq "spi frequency". + * - Param type : uint32_t + * - Param usage : spi freq + * - Return value explanation : no return + */ +#define SPI_CMD_MST_SET_FREQ DEV_SET_SPI_MST_SYSCMD(2) + + +/* ++++ Slave only commands for SPI Device ++++ */ + +/* \todo add spi slave related CMDs */ + +/** @} */ + +/** + * \defgroup DEVICE_HAL_SPI_CALLBACK SPI Interrupt callback functions + * \ingroup DEVICE_HAL_SPI + * \brief callback function structure for SPI device + * @{ + */ +typedef struct dev_spi_cbs { + DEV_CALLBACK tx_cb; /*!< spi data transmit success required bytes callback */ + DEV_CALLBACK rx_cb; /*!< spi data receive success required bytes callback */ + DEV_CALLBACK err_cb; /*!< spi error callback */ + DEV_CALLBACK xfer_cb; /*!< transfer callback */ +} DEV_SPI_CBS, *DEV_SPI_CBS_PTR; +/** @} */ + +/** SPI Clock Mode */ +typedef enum spi_clk_mode { + SPI_CPOL_0_CPHA_0 = 0, /*!< Inactive state of serial clock is low, serial clock toggles in middle of first data bit */ + SPI_CPOL_0_CPHA_1 = 1, /*!< Inactive state of serial clock is low, serial clock toggles at start of first data bit */ + SPI_CPOL_1_CPHA_0 = 2, /*!< Inactive state of serial clock is high, serial clock toggles in middle of first data bit */ + SPI_CPOL_1_CPHA_1 = 3, /*!< Inactive state of serial clock is high, serial clock toggles at start of first data bit */ + + SPI_CLK_MODE_0 = SPI_CPOL_0_CPHA_0, /*!< Equal to \ref SPI_CPOL_0_CPHA_0 */ + SPI_CLK_MODE_1 = SPI_CPOL_0_CPHA_1, /*!< Equal to \ref SPI_CPOL_0_CPHA_1 */ + SPI_CLK_MODE_2 = SPI_CPOL_1_CPHA_0, /*!< Equal to \ref SPI_CPOL_1_CPHA_0 */ + SPI_CLK_MODE_3 = SPI_CPOL_1_CPHA_1 /*!< Equal to \ref SPI_CPOL_1_CPHA_1 */ +} SPI_CLK_MODE; + +#define SPI_CLK_MODE_DEFAULT SPI_CPOL_0_CPHA_0 /*!< Default SPI device clock mode */ + +/** + * \defgroup DEVICE_HAL_SPI_DEVSTRUCT SPI Device Structure + * \ingroup DEVICE_HAL_SPI + * \brief contains definitions of spi device structure. + * \details this structure will be used in user implemented code, which was called + * Device Driver Implement Layer for spi to realize in user code. + * @{ + */ +typedef struct dev_spi_transfer DEV_SPI_TRANSFER, *DEV_SPI_TRANSFER_PTR; +/** + * \brief spi read and write data structure used by \ref SPI_CMD_TRANSFER + * spi write then read data + * + */ +struct dev_spi_transfer { + DEV_SPI_TRANSFER *next; + /* Calc by software */ + /** tot_len = (tx_totlen>rx_totlen)?tx_totlen:rx_totlen */ + uint32_t tot_len; + /* Set by user */ + uint8_t *tx_buf; + uint32_t tx_ofs; + uint32_t tx_len; + uint8_t *rx_buf; + uint32_t rx_ofs; + uint32_t rx_len; + /* Should auto set to proper value during set buffer value */ + uint32_t tx_idx; + uint32_t tx_totlen; /** tx_totlen = tx_len + tx_ofs */ + uint32_t rx_idx; + uint32_t rx_totlen; /** rx_totlen = rx_len + rx_ofs */ +}; + +/** Set tx buffer of device spi transfer */ +#define DEV_SPI_XFER_SET_TXBUF(xfer, buf, ofs, len) { \ + (xfer)->tx_buf = (uint8_t *)(buf); \ + (xfer)->tx_len = (uint32_t)(len); \ + (xfer)->tx_ofs = (uint32_t)(ofs); \ + (xfer)->tx_idx = 0; \ + (xfer)->tx_totlen = ( (uint32_t)(len) \ + + (uint32_t)(ofs) ) ; \ + } + +/** Set rx buffer of device spi transfer */ +#define DEV_SPI_XFER_SET_RXBUF(xfer, buf, ofs, len) { \ + (xfer)->rx_buf = (uint8_t *)(buf); \ + (xfer)->rx_len = (uint32_t)(len); \ + (xfer)->rx_ofs = (uint32_t)(ofs); \ + (xfer)->rx_idx = 0; \ + (xfer)->rx_totlen = ( (uint32_t)(len) \ + + (uint32_t)(ofs) ) ; \ + } + +/** Calculate total length of current transfer without next transfer */ +#define DEV_SPI_XFER_CALC_TOTLEN(xfer) (xfer)->tot_len = \ + ((xfer)->tx_totlen > (xfer)->rx_totlen) ? (xfer)->tx_totlen : (xfer)->rx_totlen ; + +/** Set next SPI transfer */ +#define DEV_SPI_XFER_SET_NEXT(xfer, next_xfer) (xfer)->next = (next_xfer); + +/** Init spi transfer */ +#define DEV_SPI_XFER_INIT(xfer) { \ + (xfer)->tx_idx = 0; \ + (xfer)->rx_idx = 0; \ + (xfer)->tx_totlen = ((xfer)->tx_len \ + + (xfer)->tx_ofs) ; \ + (xfer)->rx_totlen = ((xfer)->rx_len \ + + (xfer)->rx_ofs) ; \ + DEV_SPI_XFER_CALC_TOTLEN(xfer); \ + } +/** + * \brief spi information struct definition + * \details informations about spi open state, working state, + * frequency, spi registers, working method, interrupt number + */ +typedef struct dev_spi_info { + void *spi_ctrl; /*!< spi control related */ + uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ + uint32_t freq; /*!< spi working baudrate */ + uint8_t mode; /*!< spi working mode (master/slave) */ + uint8_t clk_mode; /*!< spi clock phase and polarity, this should be \ref SPI_CLK_MODE_DEFAULT for first open */ + uint8_t opn_cnt; /*!< spi open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ + uint8_t slave; /*!< current selected slave device no, start from 0, this should be \ref SPI_SLAVE_NOT_SELECTED for first open */ + uint8_t dfs; /*!< data frame size, this should be \ref SPI_DFS_DEFAULT for first open */ + + DEV_SPI_TRANSFER xfer; /*!< spi transfer, this should be set to all zero for first open */ + DEV_SPI_CBS spi_cbs; /*!< spi callbacks, for both master and slave mode, this should be all NULL for first open */ + void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, + this should be NULL for first open and you can \ref DEV_SPI_INFO_SET_EXTRA_OBJECT "set" + or \ref DEV_SPI_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ + uint32_t dummy; /*!< dummy write data when send and receive, this should be \ref SPI_DUMMY_DEFAULT for first open */ +} DEV_SPI_INFO, * DEV_SPI_INFO_PTR; + +/** Set extra information pointer of spi info */ +#define DEV_SPI_INFO_SET_EXTRA_OBJECT(spi_info_ptr, extra_info) (spi_info_ptr)->extra = (void *)(extra_info) +/** Get extra information pointer of spi info */ +#define DEV_SPI_INFO_GET_EXTRA_OBJECT(spi_info_ptr) ((spi_info_ptr)->extra) + +#define SPI_DFS_DEFAULT 8 /*!< Default spi data frame size */ +#define SPI_SLAVE_NOT_SELECTED (0xFF) /*!< Slave is not selected */ +#define SPI_DUMMY_DEFAULT (0xFF) /*!< default dummy value for first open */ + +/** + * \brief spi device interface definition + * \details define spi device interface, like spi information structure, + * fuctions to get spi info, open/close/control spi, send/receive data by spi + * \note all this details are implemented by user in user porting code + */ +typedef struct dev_spi { + DEV_SPI_INFO spi_info; /*!< spi device information */ + int32_t (*spi_open) (uint32_t mode, uint32_t param); /*!< open spi device in master/slave mode, \ + when in master mode, param stands for frequency, \ + when in slave mode, param stands for clock mode */ + int32_t (*spi_close) (void); /*!< close spi device */ + int32_t (*spi_control) (uint32_t ctrl_cmd, void *param); /*!< control spi device */ + int32_t (*spi_write) (const void *data, uint32_t len); /*!< send data to spi device (blocking method) */ + int32_t (*spi_read) (void *data, uint32_t len); /*!< read data from spi device (blocking method) */ +} DEV_SPI, * DEV_SPI_PTR; + +/** + * \fn int32_t (* dev_spi::spi_open) (uint32_t mode, uint32_t param) + * \details open an spi device with selected mode (master or slave) with defined \ref param + * \param[in] mode working mode (\ref DEV_MASTER_MODE "master" or \ref DEV_SLAVE_MODE "slave") + * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_spi_info::freq "frequency", + * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_spi_info::clk_mode "slave clock mode" + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_spi_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ + +/** + * \fn int32_t (* dev_spi::spi_close) (void) + * \details close an spi device, just decrease the \ref dev_spi_info::opn_cnt "opn_cnt", + * if \ref dev_spi_info::opn_cnt "opn_cnt" equals 0, then close the device + * \retval E_OK Close successfully without any issues(including scenario that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_spi_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ + +/** + * \fn int32_t (* dev_spi::spi_control) (uint32_t ctrl_cmd, void *param) + * \details control an spi device by \ref ctrl_cmd, with passed \ref param. + * you can control spi device using predefined spi control commands defined using \ref DEV_SET_SYSCMD + * (which must be implemented by bsp developer), such as \ref SPI_CMD_MST_SET_FREQ "set spi master frequency", + * \ref SPI_CMD_FLUSH_TX "flush tx" and \ref DEVICE_HAL_SPI_CTRLCMD "more". + * And you can also control spi device using your own specified commands defined using \ref DEV_SET_USRCMD, + * but these specified commands should be defined in your own spi device driver implementation. + * \param[in] ctrl_cmd \ref DEVICE_HAL_SPI_CTRLCMD "control command", to change or get some thing related to spi + * \param[in,out] param parameters that maybe argument of the command, + * or return values of the command, must not be NULL + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ + +/** + * \fn int32_t (* dev_spi::spi_write) (const void *data, uint32_t len) + * \details send \ref data through spi with defined \ref len to slave device . + * \param[in] data pointer to data need to send by spi + * \param[in] len length of data to be sent + * \retval >0 Byte count that was successfully sent for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_CTX Device is still in transfer state + * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled + */ + +/** + * \fn int32_t (* dev_spi::spi_read) (void *data, uint32_t len) + * \details receive \ref data of defined \ref len through spi from slave device . + * \param[out] data pointer to data need to received by spi + * \param[in] len length of data to be received + * \retval >0 Byte count that was successfully received for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_CTX Device is still in transfer state + * \retval E_PAR Parameter is not valid + * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled + */ +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief get an \ref dev_spi "spi device" by spi device id. + * For how to use spi device hal refer to \ref dev_spi "Functions in spi device structure" + * \param[in] spi_id id of spi, defined by user + * \retval !NULL pointer to an \ref dev_spi "spi device structure" + * \retval NULL failed to find the spi device by \ref spi_id + * \note need to implemented by user in user code + */ +extern DEV_SPI_PTR spi_get_dev(int32_t spi_id); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* _DEVICE_HAL_SPI_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h new file mode 100644 index 0000000000..c8e17d6421 --- /dev/null +++ b/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h @@ -0,0 +1,475 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-16 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \defgroup DEVICE_HAL_UART UART Device HAL Interface + * \ingroup DEVICE_HAL_DEF + * \brief Definitions for uart device hardware layer (\ref dev_uart.h) + * \details Provide unified APIs for uart driver to implement. + * Here is a diagram for the uart interface. + * + * \htmlonly + *
+ *
+ * UART Device HAL Interface Diagram + *

UART Device HAL Interface Diagram

+ *
+ *
+ * \endhtmlonly + * + * ### Reference Links + * * [Serial Port](https://en.wikipedia.org/wiki/Serial_port) + * + * @{6 + * + * \file + * \brief uart device hardware layer definitions + * \details Provide common definitions for uart device, + * then software developer can develop uart driver + * following this definitions, and the applications + * can directly call this definition to realize functions + * + */ + +#ifndef _DEVICE_HAL_UART_H_ +#define _DEVICE_HAL_UART_H_ + +#include "device/device_hal/inc/dev_common.h" + +/** + * \defgroup DEVICE_HAL_UART_BAUD UART Device Baudrate Definitions + * \ingroup DEVICE_HAL_UART + * \brief Macros for uart baudrate. + * \details Definitions for baudrate from 4800 to 115200bps. + * @{ + */ +/* + * defines for uart baudrates + */ +#define UART_BAUDRATE_110 (110) /*!< uart baudrate 110bps */ +#define UART_BAUDRATE_300 (300) /*!< uart baudrate 300bps */ +#define UART_BAUDRATE_600 (600) /*!< uart baudrate 600bps */ +#define UART_BAUDRATE_1200 (1200) /*!< uart baudrate 1200bps */ +#define UART_BAUDRATE_2400 (2400) /*!< uart baudrate 2400bps */ +#define UART_BAUDRATE_4800 (4800) /*!< uart baudrate 4800bps */ +#define UART_BAUDRATE_9600 (9600) /*!< uart baudrate 9600bps */ +#define UART_BAUDRATE_14400 (14400) /*!< uart baudrate 14400bps */ +#define UART_BAUDRATE_19200 (19200) /*!< uart baudrate 19200bps */ +#define UART_BAUDRATE_38400 (38400) /*!< uart baudrate 38400bps */ +#define UART_BAUDRATE_57600 (57600) /*!< uart baudrate 57600bps */ +#define UART_BAUDRATE_115200 (115200) /*!< uart baudrate 115200bps */ +#define UART_BAUDRATE_230400 (230400) /*!< uart baudrate 230400bps */ +#define UART_BAUDRATE_460800 (460800) /*!< uart baudrate 460800bps */ +#define UART_BAUDRATE_921600 (921600) /*!< uart baudrate 921600bps */ +/** @} */ + +/** + * \defgroup DEVICE_HAL_UART_FORMAT UART Device Format Definitions + * \ingroup DEVICE_HAL_UART + * \brief Macros for uart format. + * \details Definitions for uart format like databits, parity, stopbits. + * @{ + */ +/** + * UART Device Parity Types Enum + */ +typedef enum { + UART_PARITY_NONE = 0, /*!< no parity bit */ + UART_PARITY_ODD = 1, /*!< odd parity bit */ + UART_PARITY_EVEN = 2, /*!< even parity bit */ + UART_PARITY_MARK = 3, /*!< mark parity bit, always logical 1 */ + UART_PARITY_SPACE = 4 /*!< space parity bit, always logical 0 */ +} UART_PARITY; + +/** + * UART Device Stop Bits Enum + */ +typedef enum { + UART_STPBITS_ONE = 0, /*!< 1 stop bit */ + UART_STPBITS_ONEHALF = 1, /*!< 1.5 stop bits */ + UART_STPBITS_TWO = 2 /*!< 2 stop bits */ +} UART_STOPBITS; + +/** + * UART DPS Format: databits/parity/stopbits + */ +typedef struct uart_dps_format { + uint32_t databits; /*!< data bits */ + UART_PARITY parity; /*!< parity bit type */ + UART_STOPBITS stopbits; /*!< stop bits */ +} UART_DPS_FORMAT; + +#define UART_DATABITS_DEFAULT 8 /*!< default data bits */ + +/** Default UART DPS format */ +static const UART_DPS_FORMAT dps_format_default = {UART_DATABITS_DEFAULT, UART_PARITY_NONE, UART_STPBITS_ONE}; +/** @} */ + +/** + * UART Device Hardware Flow Control Types Enum + */ +typedef enum { + UART_FC_NONE = 0, /*!< Non hardware flow control */ + UART_FC_RTS = 1, /*!< Request To Send */ + UART_FC_CTS = 2, /*!< Clear To Send */ + UART_FC_BOTH = 3 /*!< Both hardware flow control methods */ +} UART_HW_FLOW_CONTROL; +/** Default hardware flow control method */ +static const UART_HW_FLOW_CONTROL hwfc_default = UART_FC_NONE; + +/** + * \defgroup DEVICE_HAL_UART_CTRLCMD UART Device Control Commands + * \ingroup DEVICE_HAL_UART + * \brief Definitions for uart control command, used in \ref dev_uart::uart_control "UART IO Control" + * \details These commands defined here can be used in user code directly. + * - Parameters Usage + * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values + * - For passing parameters for a structure, please use pointer to pass values + * - For getting some data, please use pointer to store the return data + * - Common Return Values + * - \ref E_OK, Control device successfully + * - \ref E_CLSED, Device is not opened + * - \ref E_OBJ, Device object is not valid or not exists + * - \ref E_PAR, Parameter is not valid for current control command + * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled + * - \ref E_CTX, Control device failed, due to different reasons like in transfer state + * - \ref E_NOSPT, Control command is not supported or not valid + * @{ + */ +/** + * Set \ref dev_uart_info::baudrate "uart baudrate". + * - Param type : uint32_t + * - Param usage : uart baudrate, must above zero. Here is a list of \ref DEVICE_HAL_UART_BAUD "possible baudrates" + * - Return value explanation : + */ +#define UART_CMD_SET_BAUD DEV_SET_SYSCMD(0) +/** + * Get \ref dev_uart_info::status "current device status" + * - Param type : uint32_t * + * - Param usage : store result of current status + * - Return value explanation : + */ +#define UART_CMD_GET_STATUS DEV_SET_SYSCMD(1) +/** + * Enable uart device + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define UART_CMD_ENA_DEV DEV_SET_SYSCMD(2) +/** + * Disable uart device, when device is disabled, + * only \ref UART_CMD_ENA_DEV, \ref UART_CMD_DIS_DEV and + * \ref UART_CMD_GET_STATUS commands can be executed, + * other commands will return \ref E_SYS + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define UART_CMD_DIS_DEV DEV_SET_SYSCMD(3) +/** + * Flush uart device output + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define UART_CMD_FLUSH_OUTPUT DEV_SET_SYSCMD(4) +/** + * Get how many bytes space in uart are available to transmit, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_uart::uart_write "uart_write" API to realize non-blocked write + * - Param type : int32_t * + * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available + * - Return value explanation : + */ +#define UART_CMD_GET_TXAVAIL DEV_SET_SYSCMD(5) +/** + * Get how many bytes in uart are available to receive, + * this can be used in interrupt callback functions, + * cooperate with \ref dev_uart::uart_read "uart_read" API to realize non-blocked read + * - Param type : int32_t * + * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available + * - Return value explanation : + */ +#define UART_CMD_GET_RXAVAIL DEV_SET_SYSCMD(6) +/** + * Cause a break condition to be transmitted to the receiving device + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define UART_CMD_BREAK_SET DEV_SET_SYSCMD(7) +/** + * Clear break condition and return to normal + * - Param type : NULL + * - Param usage : param is not required + * - Return value explanation : + */ +#define UART_CMD_BREAK_CLR DEV_SET_SYSCMD(8) +/** + * Change uart \ref dev_uart_info::dps_format "D/P/S(Data/Parity/Stop) format" + * - Param type : \ref UART_DPS_FORMAT * + * - Param usage : uart dps format including databits, parity and stopbits + * - Return value explanation : + */ +#define UART_CMD_SET_DPS_FORMAT DEV_SET_SYSCMD(9) +/** + * Set uart device \ref dev_uart_info::hwfc "hardware flow control" + * - Param type : \ref UART_HW_FLOW_CONTROL + * - Param usage : uart dps format including databits, parity and stopbits + * - Return value explanation : + */ +#define UART_CMD_SET_HWFC DEV_SET_SYSCMD(10) +/** + * Set \ref dev_uart_cbs::tx_cb "uart transmit success callback" function + * when all required bytes are transmitted for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transmit success callback function for uart + * - Return value explanation : + */ +#define UART_CMD_SET_TXCB DEV_SET_SYSCMD(11) +/** + * Set \ref dev_uart_cbs::rx_cb "uart receive success callback" function + * when all required bytes are received for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : receive success callback function for uart + * - Return value explanation : + */ +#define UART_CMD_SET_RXCB DEV_SET_SYSCMD(12) +/** + * Set \ref dev_uart_cbs::err_cb "uart transfer error callback" function + * when something error happened for interrupt method + * - Param type : \ref DEV_CALLBACK * or NULL + * - Param usage : transfer error callback function for uart + * - Return value explanation : + */ +#define UART_CMD_SET_ERRCB DEV_SET_SYSCMD(13) +/** + * Set transmit buffer via interrupt, and it will set \ref dev_uart_info::tx_buf "tx_buf" + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set tx_buf to NULL + * - Return value explanation : + */ +#define UART_CMD_SET_TXINT_BUF DEV_SET_SYSCMD(14) +/** + * Set receive buffer via interrupt, and it will set \ref dev_uart_info::rx_buf "rx_buf" + * - Param type : DEV_BUFFER * or NULL + * - Param usage : buffer structure pointer, if param is NULL, then it will set rx_buf to NULL + * - Return value explanation : + */ +#define UART_CMD_SET_RXINT_BUF DEV_SET_SYSCMD(15) +/** + * Enable or disable transmit interrupt + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define UART_CMD_SET_TXINT DEV_SET_SYSCMD(16) +/** + * Enable or disable receive interrupt + * - Param type : uint32_t + * - Param usage : enable(none-zero) or disable(zero) flag + * - Return value explanation : + */ +#define UART_CMD_SET_RXINT DEV_SET_SYSCMD(17) +/** + * Abort current interrupt transmit operation if tx interrupt enabled, + * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_uart_info::status "status" variable, + * and call the transmit callback function, when tx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define UART_CMD_ABORT_TX DEV_SET_SYSCMD(18) +/** + * Abort current interrupt receive operation if rx interrupt enabled, + * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT + * in \ref dev_uart_info::status "status" variable, + * and call the receive callback function, when rx callback is finished, + * it will clear \ref DEV_IN_TX_ABRT and return + * - Param type : NULL + * - Param usage : + * - Return value explanation : + */ +#define UART_CMD_ABORT_RX DEV_SET_SYSCMD(19) + +/** @} */ + +/** + * \defgroup DEVICE_HAL_UART_CALLBACK UART Interrupt callback functions + * \ingroup DEVICE_HAL_UART + * \brief callback function structure for UART device + * @{ + */ +typedef struct dev_uart_cbs { + DEV_CALLBACK tx_cb; /*!< uart data transmit success required bytes callback */ + DEV_CALLBACK rx_cb; /*!< uart data receive success required bytes callback */ + DEV_CALLBACK err_cb; /*!< uart error callback */ +} DEV_UART_CBS, *DEV_UART_CBS_PTR; +/** @} */ + +/** + * \defgroup DEVICE_HAL_UART_DEVSTRUCT UART Device Interface Definition + * \ingroup DEVICE_HAL_UART + * \brief Contains definitions of uart device interface structure. + * \details This structure will be used in user implemented code, which was called + * \ref DEVICE_IMPL "Device Driver Implement Layer" for uart to use in implementation code. + * Application developer should use the UART API provided here to access to UART devices. + * BSP developer should follow the API definition to implement UART device drivers. + * @{ + */ +/** + * \brief UART information struct definition + * \details informations about uart open count, working status, + * baudrate, uart registers and ctrl structure, uart dps format + */ +typedef struct dev_uart_info { + void *uart_ctrl; /*!< uart control related pointer, implemented by bsp developer, and this should be set during uart object implementation */ + uint32_t opn_cnt; /*!< uart open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ + uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ + uint32_t baudrate; /*!< uart baud rate, this should be the value of baud passing by uart_open if first successfully opened */ + UART_DPS_FORMAT dps_format; /*!< D/P/S format settings for uart device, here is \ref dps_format_default "default settings for first open" */ + UART_HW_FLOW_CONTROL hwfc; /*!< UART hardware flow control, here is \ref hwfc_default "default hardware flow control settings for first open" */ + DEV_BUFFER tx_buf; /*!< transmit buffer via interrupt, this should be all zero for first open */ + DEV_BUFFER rx_buf; /*!< receive buffer via interrupt, this should be all zero for first open */ + DEV_UART_CBS uart_cbs; /*!< uart callbacks, callback arguments should be \ref DEV_UART * or NULL, this should be all NULL for first open */ + void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, + this should be NULL for first open and you can \ref DEV_UART_INFO_SET_EXTRA_OBJECT "set" + or \ref DEV_UART_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ +} DEV_UART_INFO, * DEV_UART_INFO_PTR; + +/** Set extra information pointer of uart info */ +#define DEV_UART_INFO_SET_EXTRA_OBJECT(uart_info_ptr, extra_info) (uart_info_ptr)->extra = (void *)(extra_info) +/** Get extra information pointer of uart info */ +#define DEV_UART_INFO_GET_EXTRA_OBJECT(uart_info_ptr) ((uart_info_ptr)->extra) + +/** + * \brief UART device interface definition + * \details Define uart device interface, like uart information structure, + * provide functions to open/close/control uart, send/receive data by uart + * \note All this details are implemented by user in user porting code + */ +typedef struct dev_uart { + DEV_UART_INFO uart_info; /*!< UART device information */ + int32_t (*uart_open) (uint32_t baud); /*!< Open uart device */ + int32_t (*uart_close) (void); /*!< Close uart device */ + int32_t (*uart_control) (uint32_t ctrl_cmd, void *param); /*!< Control uart device */ + int32_t (*uart_write) (const void *data, uint32_t len); /*!< Send data by uart device(blocked) */ + int32_t (*uart_read) (void *data, uint32_t len); /*!< Read data from uart device(blocked) */ +} DEV_UART, * DEV_UART_PTR; + +/** + * \fn int32_t (* dev_uart::uart_open) (uint32_t baud) + * \details open an uart device with defined baudrate + * \param[in] baud \ref DEVICE_HAL_UART_BAUD "initial baudrate of uart", must > 0 + * \retval E_OK Open successfully without any issues + * \retval E_OPNED If device was opened before with different parameters, + * then just increase the \ref dev_uart_info::opn_cnt "opn_cnt" and return \ref E_OPNED + * \retval E_OBJ Device object is not valid + * \retval E_PAR Parameter is not valid + * \retval E_NOSPT Open settings are not supported + */ + +/** + * \fn int32_t (* dev_uart::uart_close) (void) + * \details close an uart device, just decrease the \ref dev_uart_info::opn_cnt "opn_cnt", + * if \ref dev_uart_info::opn_cnt "opn_cnt" equals 0, then close the device + * \retval E_OK Close successfully without any issues(including scenario that device is already closed) + * \retval E_OPNED Device is still opened, the device \ref dev_uart_info::opn_cnt "opn_cnt" decreased by 1 + * \retval E_OBJ Device object is not valid + */ + +/** + * \fn int32_t (* dev_uart::uart_control) (uint32_t ctrl_cmd, void *param) + * \details control an uart device by \ref ctrl_cmd, with passed \ref param. + * you can control uart device using predefined uart control commands defined using \ref DEV_SET_SYSCMD + * (which must be implemented by bsp developer), such as \ref UART_CMD_SET_BAUD "change baudrate", + * \ref UART_CMD_FLUSH_OUTPUT "flush output" and \ref DEVICE_HAL_UART_CTRLCMD "more". + * And you can also control uart device using your own specified commands defined using \ref DEV_SET_USRCMD, + * but these specified commands should be defined in your own uart device driver implementation. + * \param[in] ctrl_cmd \ref DEVICE_HAL_UART_CTRLCMD "control command", to change or get some thing related to uart + * \param[in,out] param parameters that maybe argument of the command, or return values of the command + * \retval E_OK Control device successfully + * \retval E_CLSED Device is not opened + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid for current control command + * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled + * \retval E_CTX Control device failed, due to different reasons like in transfer state + * \retval E_NOSPT Control command is not supported or not valid + */ + +/** + * \fn int32_t (* dev_uart::uart_write) (const void *data, uint32_t len) + * \details send \ref data through uart with defined \ref len(blocked). + * \param[in] data pointer to data need to send by uart, must not be NULL + * \param[in] len length of data to be sent, must > 0 + * \retval >0 Byte count that was successfully sent for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled + */ + +/** + * \fn int32_t (* dev_uart::uart_read) (void *data, uint32_t len) + * \details receive \ref data of defined \ref len through uart(blocked). + * \param[out] data pointer to data need to received by uart, must not be NULL + * \param[in] len length of data to be received, must > 0 + * \retval >0 Byte count that was successfully received for poll method + * \retval E_OBJ Device object is not valid or not exists + * \retval E_PAR Parameter is not valid + * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled + */ +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief get an \ref dev_uart "uart device" by uart device id. + * For how to use uart device hal refer to \ref DEVICE_HAL_UART_DEVSTRUCT "Functions in uart device structure" + * \param[in] uart_id id of uart, defined by user + * \retval !NULL pointer to an \ref dev_uart "uart device structure" + * \retval NULL failed to find the uart device by \ref uart_id + * \note need to implemented by user in user code + */ +extern DEV_UART_PTR uart_get_dev(int32_t uart_id); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* _DEVICE_HAL_UART_H_ */ diff --git a/bsp/synopsys/embarc/inc/arc/arc.h b/bsp/synopsys/embarc/inc/arc/arc.h new file mode 100644 index 0000000000..91c0a3850e --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc.h @@ -0,0 +1,436 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-20 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_CORE_COMM + * \brief header file including common core definitions + */ + + /** + * \addtogroup ARC_HAL_CORE_COMM + * @{ + */ + + +#ifndef _ARC_HAL_CORE_H_ +#define _ARC_HAL_CORE_H_ + +#include "inc/arc/arc_feature_config.h" + +/** + * \name exception number definitions + * @{ + */ + +/* ARC exception number */ +#define EXC_NO_RESET (0) /*!< reset vector, the entry of power up and reset */ +#define EXC_NO_MEM_ERR (1) /*!< external memory bus error */ +#define EXC_NO_INS_ERR (2) /*!< illegal instruction or illegal instruction sequence */ +#define EXC_NO_MAC_CHK (3) /*!< machine check error */ +#define EXC_NO_TLB_MISS_I (4) /*!< instruction TLB missing exception, useless without MMU */ +#define EXC_NO_TLB_MISS_D (5) /*!< data TLB missing exception, useless without MMU */ +#define EXC_NO_PRO_VIO (6) /*!< protection violation */ +#define EXC_NO_PRI_VIO (7) /*!< privilege violation */ +#define EXC_NO_SWI (8) /*!< software interrupt */ +#define EXC_NO_TRAP (9) /*!< trap */ +#define EXC_NO_EXT (10) /*!< extension exception */ +#define EXC_NO_DIV_ZER0 (11) /*!< divide by zero */ +#define EXC_NO_DC_ERR (12) /*!< data cache consistency error */ +#define EXC_NO_MAL_ALIGN (13) /*!< misaligned data access */ +#define EXC_NO_RESERVE0 (14) /*!< reserved */ +#define EXC_NO_RESERVE1 (15) /*!< reserved */ + +/* extension interrupts */ +#define EXC_NO_16 (16) /*!< interrupt vector 16 */ +#define EXC_NO_17 (17) /*!< interrupt vector 17 */ +#define EXC_NO_18 (18) /*!< interrupt vector 18 */ +#define EXC_NO_19 (19) /*!< interrupt vector 19 */ +#define EXC_NO_20 (20) /*!< interrupt vector 20 */ +#define EXC_NO_21 (21) /*!< interrupt vector 21 */ +#define EXC_NO_22 (22) /*!< interrupt vector 22 */ +#define EXC_NO_23 (23) /*!< interrupt vector 23 */ +#define EXC_NO_24 (24) /*!< interrupt vector 24 */ +#define EXC_NO_25 (25) /*!< interrupt vector 25 */ +#define EXC_NO_26 (26) /*!< interrupt vector 26 */ +#define EXC_NO_27 (27) /*!< interrupt vector 27 */ +#define EXC_NO_28 (28) /*!< interrupt vector 28 */ +#define EXC_NO_29 (29) /*!< interrupt vector 29 */ +#define EXC_NO_30 (30) /*!< interrupt vector 30 */ +#define EXC_NO_31 (31) /*!< interrupt vector 31 */ +/* ... ARC supports 255 interrupt vectors at most */ +#define EXC_NO_255 (255) /*!< interrupt vector 255 */ + +/** @} */ + +/** + * \name exception vector offset + * @{ + */ +#define EXC_NO_TO_OFFSET(no) (no << 2) + +/* ARC exception vector offset */ +#define EXC_VECTOR_RESET (0x00) /*!< EXC_NO_RESET offset */ +#define EXC_VECTOR_MEM_ERR (0x04) /*!< EXC_NO_MEM_ERR offset */ +#define EXC_VECTOR_INS_ERR (0x08) /*!< EXC_NO_INS_ERR offset */ +#define EXC_VECTOR_MAC_CHK (0x0c) /*!< EXC_NO_MAC_CHK offset */ +#define EXC_VECTOR_TLB_MISS_I (0x10) /*!< EXC_NO_TLB_MISS_I offset */ +#define EXC_VECTOR_TLB_MISS_D (0x14) /*!< EXC_NO_TLB_MISS_D offset */ +#define EXC_VECTOR_PRO_VIO (0x18) /*!< EXC_NO_PRO_VIO offset */ +#define EXC_VECTOR_PRI_VIO (0x1c) /*!< EXC_NO_PRI_VIO offset */ +#define EXC_VECTOR_SWI (0x20) /*!< EXC_NO_SWI offset */ +#define EXC_VECTOR_TRAP (0x24) /*!< EXC_NO_TRAP offset */ +#define EXC_VECTOR_EXT (0x28) /*!< EXC_NO_EXT offset */ +#define EXC_VECTOR_DIV_ZER0 (0x2c) /*!< EXC_NO_DIV_ZER0 offset */ +#define EXC_VECTOR_DC_ERR (0x30) /*!< EXC_NO_DC_ERR offset */ +#define EXC_VECTOR_MAL_ALIGN (0x34) /*!< EXC_NO_MAL_ALIGN offset */ +#define EXC_VECTOR_RESERVE0 (0x38) /*!< EXC_NO_RESERVE0 offset */ +#define EXC_VECTOR_RESERVE1 (0x3c) /*!< EXC_NO_RESERVE1 offset */ +/** @} */ + +/** + * \name build configuration register + * @{ + */ +#define AUX_BCR_VER (0x60) /*!< build configuration register version */ +#define AUX_BCR_BTA (0x63) /*!< build configuration for BTA LINK */ +#define AUX_BCR_VECBASE (0x68) /*!< build configuration for interrupt vector base */ +#define AUX_BCR_MPU (0x6d) /*!< build configuration for memory protection unit */ +#define AUX_BCR_RF (0x6e) /*!< build configuration for core registers */ +#define AUX_BCR_D_CACHE (0x72) /*!< build configuration for data cache */ +#define AUX_BCR_DCCM (0x74) /*!< build configuration for DCCM */ +#define AUX_BCR_TIMERS (0x75) /*!< build configuration for processor timers */ +#define AUX_BCR_AP (0x76) /*!< build configuration for actionpoints */ +#define AUX_BCR_I_CACHE (0x77) /*!< build configuration for instruction cache */ +#define AUX_BCR_ICCM (0x78) /*!< build configuration for ICCM */ +#define AUX_BCR_DSP (0x7a) /*!< build configuration for DSP */ +#define AUX_BCR_MUL (0x7b) /*!< build configuration for multiply */ +#define AUX_BCR_SWAP (0x7c) /*!< build configuration for swap */ +#define AUX_BCR_NORM (0x7d) /*!< build configuration for normalize */ +#define AUX_BCR_MIXMAX (0x7e) /*!< build configuration for MIN/MAX */ +#define AUX_BCR_BARREL (0x7f) /*!< build configuration for barrel shift */ +#define AUX_BCR_ISA (0xc1) /*!< build configuration for ISA configuration */ +#define AUX_BCR_STACK (0xc5) /*!< build configuration for stack region */ +#define AUX_BCR_ERP (0xc7) /*!< build configuration for error protection */ +#define AUX_BCR_FPU (0xc8) /*!< build configuration for floating-point unit */ +#define AUX_BCR_CPORT (0xc9) /*!< build configuration for code protection */ +#define AUX_BCR_BS (0xcb) /*!< build configuration for bitstream */ +#define AUX_BCR_AGU (0xcc) /*!< build configuration for address generate unit */ +#define AUX_BCR_DMAC (0xcd) /*!< build configuration for DMA */ +#define AUX_BCR_CONNECT_SYSTEM (0xd0) /*!< build configuration for arc connect */ +#define AUX_BCR_CONNECT_SEMA (0xd1) /*!< build configuration for inter-core semaphore */ +#define AUX_BCR_CONNECT_MESSAGE (0xd2) /*!< build configuration for inter-code message */ +#define AUX_BCR_CONNECT_PMU (0xd3) /*!< build configuration for power management unit */ +#define AUX_BCR_CONNECT_GFRC (0xd6) /*!< build configuration for global free running counter */ +#define AUX_BCR_CAL_STORE (0xd9) /*!< build configuration for calibration parameter storage */ +#define AUX_BCR_CONNECT_ICI (0xe0) /*!< build configuration for inter-core interrupt unit */ +#define AUX_BCR_CONNECT_ICD (0xe1) /*!< build configuration for inter-core debug unit */ +#define AUX_BCR_CONNECT_PDM (0xe3) /*!< build configuration for power domain management unit*/ +#define AUX_BCR_RTT (0xf2) /*!< build configuration for real-time trace */ +#define AUX_BCR_IRQ (0xf3) /*!< build configuration for interrupt */ +#define AUX_BCR_PCT (0xf5) /*!< build configuration for performance counters */ +#define AUX_BCR_CC (0xf6) /*!< build configuration for performance counters */ +#define AUX_BCR_PDM_DVFS (0xf7) /*!< build configuration for PDM and DVFS */ + +#define AUX_BCR_SEC_BUILD (0xdb) + +/* from 0xF5 and 0xF6 */ + +#define AUX_BCR_IFQUEUE (0xfe) /*!< build configuration for instruction fetch queue */ +#define AUX_BCR_SMART (0xff) /*!< build configuration for SmaRT debug feature */ +/** @} */ + + +#define AUX_SEC_STAT (0x9) +#define AUX_SEC_STAT_BIT_SSC (0) +#define AUX_SEC_STAT_BIT_NSRT (1) +#define AUX_SEC_STAT_BIT_NSRU (2) +#define AUX_SEC_STAT_BIT_IRM (3) +#define AUX_SEC_STAT_BIT_SUE (4) +#define AUX_SEC_STAT_BIT_NIC (5) + +/** + * \name status register STATUS32 + * @{ + */ +#define AUX_STATUS32 (0xa) +#define AUX_STATUS32_P0 (0xb) + +/* STATUS32 bit-field definition */ +#define AUX_STATUS_BIT_AE (5) /*!< processor is in an exception */ +#define AUX_STATUS_BIT_DE (6) /*!< delayed branch is pending */ +#define AUX_STATUS_BIT_U (7) /*!< user mode */ +#define AUX_STATUS_BIT_L (12) /*!< zero-overhead loop enable */ +#define AUX_STATUS_BIT_IE (31) /*!< interrupt enable */ + +/* masks correspond to STATUS32 bit-field */ +#define AUX_STATUS_MASK_AE (1< Pre Incr + * Eff Addr for load = [reg2 + x] + * + * LD.ab reg1, [reg2, x] => Post Incr + * Eff Addr for load = [reg2] + */ +#if defined(__GNU__) +.macro PUSH reg + st.a \reg, [sp, -4] +.endm + +.macro PUSHAX aux + lr r10, [\aux] + PUSH r10 +.endm + +.macro POP reg + ld.ab \reg, [sp, 4] +.endm + +.macro POPAX aux + POP r10 + sr r10, [\aux] +.endm +#else +.macro PUSH, reg + st.a reg, [sp, -4] +.endm + +.macro PUSHAX, aux + lr r10, [aux] + PUSH r10 +.endm + +.macro POP, reg + ld.ab reg, [sp, 4] +.endm + +.macro POPAX, aux + POP r10 + sr r10, [aux] +.endm +#endif + +/*-------------------------------------------------------------- + * Helpers to save/restore callee-saved regs: + * used by several macros below + *-------------------------------------------------------------*/ +.macro SAVE_CALLEE_REGS + PUSH r13 + PUSH r14 + PUSH r15 +#ifndef ARC_FEATURE_RF16 + PUSH r16 + PUSH r17 + PUSH r18 + PUSH r19 + PUSH r20 + PUSH r21 + PUSH r22 + PUSH r23 + PUSH r24 + PUSH r25 +#endif +.endm + +.macro RESTORE_CALLEE_REGS +#ifndef ARC_FEATURE_RF16 + POP r25 + POP r24 + POP r23 + POP r22 + POP r21 + POP r20 + POP r19 + POP r18 + POP r17 + POP r16 +#endif + POP r15 + POP r14 + POP r13 +.endm + +.macro CLEAR_CALLEE_REGS +#ifndef ARC_FEATURE_RF16 + mov r25, 0 + mov r24, 0 + mov r23, 0 + mov r22, 0 + mov r21, 0 + mov r20, 0 + mov r19, 0 + mov r18, 0 + mov r17, 0 + mov r16, 0 +#endif + mov r15, 0 + mov r14, 0 + mov r13, 0 +.endm + +.macro CLEAR_SCRATCH_REGS + mov r1, 0 + mov r2, 0 + mov r3, 0 + mov r4, 0 + mov r5, 0 + mov r6, 0 + mov r7, 0 + mov r8, 0 + mov r9, 0 + mov r10, 0 + mov r11, 0 + mov r12, 0 + + mov fp, 0 + mov r29, 0 + mov r30, 0 +.endm + + +.macro SAVE_LP_REGS + PUSH r60 + PUSHAX AUX_LP_START + PUSHAX AUX_LP_END +.endm + +.macro RESTORE_LP_REGS + POPAX AUX_LP_END + POPAX AUX_LP_START + POP r10 +/* must not use the LP_COUNT register(r60) as the destination of multi-cycle instruction */ + mov r60, r10 + +.endm + +.macro SAVE_R0_TO_R12 + PUSH r0 + PUSH r1 + PUSH r2 + PUSH r3 +#ifndef ARC_FEATURE_RF16 + PUSH r4 + PUSH r5 + PUSH r6 + PUSH r7 + PUSH r8 + PUSH r9 +#endif + PUSH r10 + PUSH r11 + PUSH r12 +.endm + +.macro RESTORE_R0_TO_R12 + POP r12 + POP r11 + POP r10 +#ifndef ARC_FEATURE_RF16 + POP r9 + POP r8 + POP r7 + POP r6 + POP r5 + POP r4 +#endif + POP r3 + POP r2 + POP r1 + POP r0 +.endm + +.macro SAVE_CODE_DENSITY + PUSHAX AUX_JLI_BASE + PUSHAX AUX_LDI_BASE + PUSHAX AUX_EI_BASE +.endm + +.macro RESTORE_CODE_DENSITY + POPAX AUX_EI_BASE + POPAX AUX_LDI_BASE + POPAX AUX_JLI_BASE +.endm + +/* todo: check the contents of NON_SCRATCH_REGS in debug */ +.macro SAVE_NONSCRATCH_REGS +/* r0-r12 are saved by caller function */ + PUSH gp + PUSH fp + PUSH blink + SAVE_CALLEE_REGS +.endm + +.macro RESTORE_NONSCRATCH_REGS + RESTORE_CALLEE_REGS + POP blink + POP fp + POP gp +.endm + + +.macro SAVE_FIQ_EXC_REGS +#ifndef ARC_FEATURE_RGF_BANKED_REGS + SAVE_R0_TO_R12 + + PUSH gp + PUSH fp + PUSH r30 /* general purpose */ + PUSH blink + +#else +#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \ + ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32 +#error "unsupported ARC_FEATURE_RGF_BANKED_REGS" +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \ + ARC_FEATURE_RGF_BANKED_REGS == 16 + PUSH r4 + PUSH r5 + PUSH r6 + PUSH r7 + PUSH r8 + PUSH r9 +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 + PUSH r10 + PUSH r11 +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 + PUSH r12 +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 + PUSH gp + PUSH fp + PUSH r30 /* general purpose */ + PUSH blink +#endif + +#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */ + +#ifdef ARC_FEATURE_CODE_DENSITY + SAVE_CODE_DENSITY +#endif + SAVE_LP_REGS +.endm + +.macro RESTORE_FIQ_EXC_REGS + RESTORE_LP_REGS +#ifdef ARC_FEATURE_CODE_DENSITY + RESTORE_CODE_DENSITY +#endif + +#ifndef ARC_FEATURE_RGF_BANKED_REGS + POP blink + POP r30 + POP fp + POP gp + + RESTORE_R0_TO_R12 +#else + +#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \ + ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32 +#error "unsupported ARC_FEATURE_RGF_BANKED_REGS" +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 + POP blink + POP r30 + POP fp + POP gp +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 + POP r12 +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 + POP r11 + POP r10 +#endif + +#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \ + ARC_FEATURE_RGF_BANKED_REGS == 16 + POP r9 + POP r8 + POP r7 + POP r6 + POP r5 + POP r4 +#endif + +#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */ +.endm + +/* normal interrupt prologue, pc, status and r0-r11 are saved by hardware */ +.macro INTERRUPT_PROLOGUE + PUSH r12 + PUSH gp + PUSH fp + PUSH ilink + PUSH r30 + + sub sp, sp, 4 /* skip bta */ +.endm + + +/* normal interrupt epilogue, pc, status and r0-r11 are restored by hardware */ +.macro INTERRUPT_EPILOGUE + add sp, sp, 4 /* skip bta */ + + POP r30 + POP ilink + POP fp + POP gp + POP r12 +.endm + +#if SECURESHIELD_VERSION == 2 +/* exception prologue, create the same frame of interrupt manually */ +.macro EXCEPTION_PROLOGUE + st.as r10, [sp, -6] /* save r10 first, free up a register*/ + + PUSHAX AUX_ERSTATUS + sub sp, sp, 4 /* slot for SEC_STAT */ + PUSHAX AUX_ERRET + + PUSH blink + + PUSH r11 + sub sp, sp, 4 /* r10 is pushed before */ +#ifndef ARC_FEATURE_RF16 + PUSH r9 + PUSH r8 + PUSH r7 + PUSH r6 + PUSH r5 + PUSH r4 +#endif + PUSH r3 + PUSH r2 + PUSH r1 + PUSH r0 + +#ifdef ARC_FEATURE_CODE_DENSITY + SAVE_CODE_DENSITY +#endif + SAVE_LP_REGS + + PUSH r12 + PUSH gp + PUSH fp + PUSH ilink + PUSH r30 + + PUSHAX AUX_ERBTA +.endm + +/* exception epilogue, restore the same frame of interrupt manually */ +.macro EXCEPTION_EPILOGUE + POPAX AUX_ERBTA + + POP r30 + POP ilink + POP fp + POP gp + POP r12 + + RESTORE_LP_REGS + +#ifdef ARC_FEATURE_CODE_DENSITY + RESTORE_CODE_DENSITY +#endif + POP r0 + POP r1 + POP r2 + POP r3 +#ifndef ARC_FEATURE_RF16 + POP r4 + POP r5 + POP r6 + POP r7 + POP r8 + POP r9 +#endif + add sp, sp, 4 /* r10 will be popped finally */ + POP r11 + + POP blink + + + POPAX AUX_ERRET + add sp, sp, 4 /* slot for SEC_STAT */ + POPAX AUX_ERSTATUS + + ld.as r10, [sp, -6] /* restore r10 */ +.endm +#else /* normal version */ +/* exception prologue, create the same frame of interrupt manually */ +.macro EXCEPTION_PROLOGUE +#ifdef ARC_FEATURE_CODE_DENSITY + st.as r10, [sp, -11] /* save r10 first, free up a register*/ +#else + st.as r10, [sp, -8] +#endif + PUSHAX AUX_ERSTATUS + PUSHAX AUX_ERRET + +#ifdef ARC_FEATURE_CODE_DENSITY + SAVE_CODE_DENSITY +#endif + SAVE_LP_REGS + + PUSH blink + + PUSH r11 + sub sp, sp, 4 /* r10 is pushed before */ +#ifndef ARC_FEATURE_RF16 + PUSH r9 + PUSH r8 + PUSH r7 + PUSH r6 + PUSH r5 + PUSH r4 +#endif + PUSH r3 + PUSH r2 + PUSH r1 + PUSH r0 + + PUSH r12 + PUSH gp + PUSH fp + PUSH ilink + PUSH r30 + + PUSHAX AUX_ERBTA +.endm + +/* exception epilogue, restore the same frame of interrupt manually */ +.macro EXCEPTION_EPILOGUE + POPAX AUX_ERBTA + + POP r30 + POP ilink + POP fp + POP gp + POP r12 + + POP r0 + POP r1 + POP r2 + POP r3 +#ifndef ARC_FEATURE_RF16 + POP r4 + POP r5 + POP r6 + POP r7 + POP r8 + POP r9 +#endif + add sp, sp, 4 /* r10 will be popped finally */ + POP r11 + + POP blink + + RESTORE_LP_REGS + +#ifdef ARC_FEATURE_CODE_DENSITY + RESTORE_CODE_DENSITY +#endif + + POPAX AUX_ERRET + POPAX AUX_ERSTATUS + +#ifdef ARC_FEATURE_CODE_DENSITY + ld.as r10, [sp, -11] /* restore r10 */ +#else + ld.as r10, [sp, -8] +#endif +.endm + +#endif /* SECURESHIELD_VERSION == 2 */ + +#endif /* _ARC_HAL_ASM_COMMON_H */ +/** @endcond */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_builtin.h b/bsp/synopsys/embarc/inc/arc/arc_builtin.h new file mode 100644 index 0000000000..d9b76124ff --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_builtin.h @@ -0,0 +1,301 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-12 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_BUILTIN + * \brief header file of builtin and helper functions + * + * The Metaware toolchain and the GNU toolchain are supported. The details please go to see the file. + */ + +/** + * \addtogroup ARC_HAL_BUILTIN + * @{ + */ + +#ifndef _ARC_HAL_BUILTIN_H_ +#define _ARC_HAL_BUILTIN_H_ + +#include "inc/embARC_toolchain.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__MW__) /* Metaware toolchain */ + +#define _arc_nop _nop /*!< no operation, generate a nop instruction produces a single NOP instruction in the compiled code */ + +#define _arc_brk _brk /*!< generate a brk instruction */ + +#define _arc_clri _clri /*!< generate a clri instruction */ + +#define _arc_seti(c) _seti(c) /*!< generate a seti instruction */ + +#define _arc_core_write(regno, val) _core_write(val, regno) /*!< write core register */ + +#define _arc_core_read(regno) _core_read(regno) /*!< read core register */ + +#define _arc_lr_reg(aux) _lr(aux) /*!< read auxiliary register */ + +#define _arc_sr_reg(aux, val) _sr(val, aux) /*!< write auxiliary register */ + +#define _arc_sleep(a) _sleep(a) /*!< generate a sleep instruction */ + +#define _arc_flag(a) _flag(a) /*!< generate a flag instruction */ + +#define _arc_kflag(a) + +#define _arc_sync _sync /*!< generate a sync instruction */ + +/* + * !< _arc_usually (expr) evaluates expression expr and + * informs the compiler that the value is usually true. + */ +#define _arc_usually(a) _Usually((a)) + +/* + * !< _arc_rarely (expr) evaluates expression expr and + * informs the compiler that the value is rarely true. + */ +#define _arc_rarely(a) _Rarely((a)) + +#if 0 +/** + * \brief Reverses the byte order of the 16-bit operand, + * reversing the endianness of the value. + * Not for ARC HS family + */ +#define _arc_swap16(a) _swap16(a) +/** + * \brief Reverses the byte order of the 32-bit operand, + * reversing the endianness of the value. + * Not for ARC HS family + */ +#define _arc_swap32(a) _swap32(a) +#else +Inline uint32_t _arc_swap32(uint32_t val) { + register uint32_t v; + __asm__ volatile ("swape %0, %1" :"=r"(v): "r"(val)); + return v; +} + +Inline uint16_t _arc_swap16(uint32_t val) { + register uint32_t temp; + register uint32_t v; + __asm__ volatile ("swape %0, %1" :"=r"(temp): "r"(val)); + __asm__ volatile ("lsr16 %0, %1" :"=r"(v): "r"(temp)); + return (unsigned short)v; +} +#endif + +/** + * \brief Each call to _swi() generates one + * software interrupt instruction (SWI) for processors + * to support the SWI instruction. + */ +#define _arc_swi _swi + +/* \todo add more builtin functions of metaware tool */ + +#elif defined (__GNU__) /* GNU toolchain */ + +#define _arc_nop __builtin_arc_nop +#define _arc_brk __builtin_arc_brk +#define _arc_seti(c) __builtin_arc_seti(c) +#define _arc_core_write(regno, val) __builtin_arc_core_write(regno,val) +#define _arc_core_read(regno) __builtin_arc_core_read(regno) +#define _arc_flag(a) __builtin_arc_flag(a) +#define _arc_kflag(a) __builtin_arc_kflag(a) +#define _arc_lr_reg(aux) __builtin_arc_lr(aux) +/* don't uncomment this now */ +//#define _arc_sr_reg(aux, val) __builtin_arc_sr(aux, val) +#define _arc_sleep(a) __builtin_arc_sleep(a) +//#define _arc_sync __builtin_arc_sync + +/** + * \brief _arc_usually (expr) evaluates expression expr and + * informs the compiler that the value is usually true. + */ +#define _arc_usually(a) __builtin_expect((int)(a), 1) + +/** + * \brief _arc_rarely (expr) evaluates expression expr and + * informs the compiler that the value is rarely true. + */ +#define _arc_rarely(a) __builtin_expect((int)(a), 0) + +/** + * \brief Each call to _swi() generates one + * software interrupt instruction (SWI) for processors + * to support the SWI instruction. + */ +#define _arc_swi __builtin_arc_swi + +Inline uint32_t _arc_clri(void) { + register uint32_t v; + __asm__ volatile ("clri %0" :"=r"(v)); + return v; + +} +/* \todo add more builtin functions of gnu tool */ + +Inline uint32_t _arc_swap32(uint32_t val) { + register uint32_t v; + __asm__ volatile ("swape %0, %1" :"=r"(v): "r"(val)); + return v; +} + +Inline uint16_t _arc_swap16(uint32_t val) { + register uint32_t temp; + register uint32_t v; + __asm__ volatile ("swape %0, %1" :"=r"(temp): "r"(val)); + __asm__ volatile ("lsr16 %0, %1" :"=r"(v): "r"(temp)); + return (unsigned short)v; +} + +Inline void _arc_sync(void) { + __asm__ volatile ("sync"); +} + +/** + * \note Following is a workaround for arc gcc + * built-in function __builtin_arc_sr. + * But it is wrong in GCC arc-4.8-R3-rc3 and shouldn't be used. + */ + +/* + * The auxiliary register address is specified as a long immediate operand by caller. + * e.g. + * write_aux_reg(0x69, some_val); + * This generates the tightest code. + */ +#define write_aux_reg(reg_imm, val) \ +({ \ + Asm( \ + " sr %0, [%1] \n" \ + : \ + : "ir"(val), "r"(reg_imm)); \ +}) + +#define _arc_sr_reg(aux, val) write_aux_reg(aux, val) + +#endif + +/* \todo add more helper functions here, such as memory operation */ + +#define _arc_aux_read(aux) _arc_lr_reg(aux) +#define _arc_aux_write(aux, val) _arc_sr_reg(aux, val) + +/** + * \name cache related helper function + * @{ + */ + +/** + * \brief read memory and bypass the cache + * \param[in] ptr memory address + * \return value in the memory + */ +Inline uint32_t _arc_read_uncached_32(void *ptr) +{ + uint32_t __ret; + Asm("ld.di %0, [%1]":"=r"(__ret):"r"(ptr)); + return __ret; +} + +/** + * \brief write memory and bypass the cache + * \param[in] ptr memory address + * \param[in] data vaule to be written + */ +Inline void _arc_write_uncached_32(void *ptr, uint32_t data) +{ + Asm("st.di %0, [%1]":: "r"(data), "r"(ptr)); +} + +/** + * \brief read memory with cache + * \param[in] ptr memory address + * \returns value in the memory + */ +Inline uint32_t _arc_read_cached_32(void *ptr) +{ + uint32_t __ret; + Asm("ld %0, [%1]":"=r"(__ret):"r"(ptr)); + return __ret; +} + +/** + * \brief read memory with cache + * \param[in] ptr memory address + * \param[in] data vaule to be written + * \return description + */ +Inline void _arc_write_cached_32(void *ptr, uint32_t data) +{ + Asm("st %0, [%1]":: "r"(data), "r"(ptr)); +} + +/** + * \brief go to main function with proper arguments + * \param argc argument count + * \param argv argument content array + * \retval return value of main function + */ +Inline int32_t _arc_goto_main(int argc, char **argv) { + int __ret; + __asm__ volatile( + "mov %%r0, %1\n" + "mov %%r1, %2\n" + "push_s %%blink\n" + "jl main\n" + "pop_s %%blink\n" + "mov %0, %%r0" + :"=r"(__ret): "r"(argc), "r"(argv)); + return (int)__ret; +} + +#ifdef __cplusplus +} +#endif + +#if defined(LIB_SECURESHIELD) && defined(LIB_SECURESHIELD_OVERRIDES) && (SECURESHIELD_VERSION == 1) +#define OVERRIDE_ARC_HAL_BUILTIN_H +#include "secureshield_overrides.h" +#endif + +/** @} */ +#endif /* _ARC_HAL_BUILTIN_H_ */ +/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_cache.h b/bsp/synopsys/embarc/inc/arc/arc_cache.h new file mode 100644 index 0000000000..dfbc7df9a5 --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_cache.h @@ -0,0 +1,321 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_MISC_CACHE + * \brief header file of cache module + */ + +#ifndef _ARC_HAL_CACHE_H_ +#define _ARC_HAL_CACHE_H_ + +#include "inc/embARC_toolchain.h" +#include "inc/arc/arc.h" +#include "inc/arc/arc_builtin.h" +#include "inc/arc/arc_exception.h" + +/** + * \name instruction cache control register related definition + * \todo this definitions will be reviewed. + * @{ + */ +#define IC_CTRL_IC_ENABLE 0x0 /*!< enable instruction cache */ +#define IC_CTRL_IC_DISABLE 0x1 /*!< disable instruction cache */ +#define IC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */ +#define IC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */ +#define IC_CTRL_OP_SUCCEEDED 0x8 /*!< instruction cache operation succeeded */ +/** @} */ + +/** + * \name data cache control register related definition + * \todo this definition will be reviewed. + * @{ + */ +#define IC_CTRL_I +#define DC_CTRL_DC_ENABLE 0x0 /*!< enable data cache */ +#define DC_CTRL_DC_DISABLE 0x1 /*!< disable data cache */ +#define DC_CTRL_INVALID_ONLY 0x0 /*!< invalid data cache only */ +#define DC_CTRL_INVALID_FLUSH 0x40 /*!< invalid and flush data cache */ +#define DC_CTRL_ENABLE_FLUSH_LOCKED 0x80 /*!< the locked data cache can be flushed */ +#define DC_CTRL_DISABLE_FLUSH_LOCKED 0x0 /*!< the locked data cache cannot be flushed */ +#define DC_CTRL_FLUSH_STATUS 0x100 /*!< flush status */ +#define DC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */ +#define DC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */ +#define DC_CTRL_OP_SUCCEEDED 0x4 /*!< data cache operation succeeded */ +/** @} */ + +/** + * \name instruction cache related inline function + * @{ + */ + +/** + * \brief check whether instruction cache is available, + * 0 for not available, >0 for available + */ +Inline uint8_t icache_available(void) +{ + return (_arc_aux_read(AUX_BCR_I_CACHE) & 0xF); +} + +/** + * \brief enable instruction cache + * \param[in] icache_en_mask operation mask + */ +Inline void icache_enable(uint32_t icache_en_mask) +{ + if (!icache_available()) return; + _arc_aux_write(AUX_IC_CTRL, icache_en_mask); +} + +/** + * \brief disable instruction cache + */ +Inline void icache_disable(void) +{ + if (!icache_available()) return; + _arc_aux_write(AUX_IC_CTRL, IC_CTRL_IC_DISABLE); +} + +/** + * \brief invalidate the entire instruction cache + */ +Inline void icache_invalidate(void) +{ + if (!icache_available()) return; + /* invalidate the entire icache */ + _arc_aux_write(AUX_IC_IVIC, 0); + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); +} + +/** + * \brief invalidate specific cache line + * \param[in] address memory address + */ +Inline void icache_invalidate_line(uint32_t address) +{ + if (!icache_available()) return; + _arc_aux_write(AUX_IC_IVIL, address); + /* the 3 nops are required by ARCv2 ISA */ + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); +} + +/** + * \brief lock specific cache line + * \param[in] address memory address + * \return 0, succeeded, -1, failed + */ +Inline int32_t icache_lock_line(uint32_t address) +{ + if (!icache_available()) return -1; + _arc_aux_write(AUX_IC_LIL, address); + if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { + return 0; + } else { + return -1; + } +} + +/** + * \brief set icache access mode + * \param[in] mode, access mode, 1: indirect access 0:direct access + */ +Inline void icache_access_mode(uint32_t mode) +{ + if (!icache_available()) return; + if (mode) { + _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) | IC_CTRL_INDIRECT_ACCESS); + } else { + _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) & (~IC_CTRL_INDIRECT_ACCESS)); + } +} + + +/** @} */ + +/** + * \name data cache related inline functions + * @{ + */ + +/** + * \brief check whether data cache is available, + * 0 for not available, >0 for available + */ +Inline uint8_t dcache_available(void) +{ + return (_arc_aux_read(AUX_BCR_D_CACHE) & 0xF); +} + +/** + * \brief invalidate the entire data cache + */ +Inline void dcache_invalidate(void) +{ + if (!dcache_available()) return; + uint32_t status; + + status = cpu_lock_save(); + _arc_aux_write(AUX_DC_IVDC, 1); + /* wait for flush completion */ + while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); + cpu_unlock_restore(status); +} + +/** + * \brief invalidate the specific cache line + * \param[in] address memory address + */ +Inline void dcache_invalidate_line(uint32_t address) +{ + if (!dcache_available()) return; + _arc_aux_write(AUX_DC_IVDL, address); + Asm("nop_s"); + Asm("nop_s"); + Asm("nop_s"); +} + +/** + * \brief enable data cache + * \param[in] dcache_en_mask operation mask + */ +Inline void dcache_enable(uint32_t dcache_en_mask) +{ + if (!dcache_available()) return; + _arc_aux_write(AUX_DC_CTRL, dcache_en_mask); +} + +/** + * \brief disable data cache + */ +Inline void dcache_disable(void) +{ + if (!dcache_available()) return; + _arc_aux_write(AUX_DC_CTRL, DC_CTRL_DC_DISABLE); +} + +/** + * \brief flush data cache + */ +Inline void dcache_flush(void) +{ + if (!dcache_available()) return; + uint32_t status; + + status = cpu_lock_save(); + _arc_aux_write(AUX_DC_FLSH, 1); + /* wait for flush completion */ + while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); + cpu_unlock_restore(status); +} + +/** + * \brief flush the specific data cache line + * \param[in] address memory address + */ +Inline void dcache_flush_line(uint32_t address) +{ + if (!dcache_available()) return; + + uint32_t status; + + status = cpu_lock_save(); + _arc_aux_write(AUX_DC_FLDL, address); + while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); + cpu_unlock_restore(status); +} + +/** + * \brief lock the specific data cache line + * \param[in] address memory address + * \return 0, succeeded, -1, failed + */ +Inline int dcache_lock_line(uint32_t address) +{ + if (!dcache_available()) return -1; + _arc_aux_write(AUX_DC_LDL, address); + if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { + return 0; + } else { + return -1; + } +} + +/** + * \brief set dcache access mode + * \param[in] mode, access mode, 1: indirect access 0:direct access + */ +Inline void dcache_access_mode(uint32_t mode) +{ + if (!dcache_available()) return; + if (mode) { + _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) | DC_CTRL_INDIRECT_ACCESS); + } else { + _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) & (~DC_CTRL_INDIRECT_ACCESS)); + } +} + +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name declarations of cache related functions + * @{ + */ +extern int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size); +extern int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size); +extern int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data); +extern int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data); +extern int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data); +extern int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size); +extern int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size); +extern int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size); +extern int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data); +extern int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data); +extern int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data); +extern void arc_cache_init(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* _ARC_HAL_CACHE_H_ */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_em.h b/bsp/synopsys/embarc/inc/arc/arc_em.h new file mode 100644 index 0000000000..cfb9636449 --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_em.h @@ -0,0 +1,133 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-06-12 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_CORE_EM + * \brief header file of EM series + */ + +/** + * \addtogroup ARC_HAL_CORE_EM + * @{ + */ + +#ifndef _ARC_HAL_EM_H_ +#define _ARC_HAL_EM_H_ + +#include "inc/arc/arc.h" + +#define AUX_ACC0_LO (0x580) +#define AUX_ACC0_GLO (0x581) +#define AUX_ACC0_HI (0x582) +#define AUX_ACC0_GHI (0x583) +#define AUX_DSP_BFLY0 (0x598) +#define AUX_DSP_FFT_CTRL (0x59e) +#define AUX_DSP_CTRL (0x59f) + +#define AUX_AGU_AUX_AP0 (0x5c0) +#define AUX_AGU_AUX_AP1 (0x5c1) +#define AUX_AGU_AUX_AP2 (0x5c2) +#define AUX_AGU_AUX_AP3 (0x5c3) +#define AUX_AGU_AUX_AP4 (0x5c4) +#define AUX_AGU_AUX_AP5 (0x5c5) +#define AUX_AGU_AUX_AP6 (0x5c6) +#define AUX_AGU_AUX_AP7 (0x5c7) +#define AUX_AGU_AUX_AP8 (0x5c8) +#define AUX_AGU_AUX_AP9 (0x5c9) +#define AUX_AGU_AUX_AP10 (0x5ca) +#define AUX_AGU_AUX_AP11 (0x5cb) +#define AUX_AGU_AUX_AP12 (0x5cc) +#define AUX_AGU_AUX_AP13 (0x5cd) +#define AUX_AGU_AUX_AP14 (0x5ce) +#define AUX_AGU_AUX_AP15 (0x5cf) + +#define AUX_AGU_AXU_OS0 (0x5d0) +#define AUX_AGU_AXU_OS1 (0x5d1) +#define AUX_AGU_AXU_OS2 (0x5d2) +#define AUX_AGU_AXU_OS3 (0x5d3) +#define AUX_AGU_AXU_OS4 (0x5d4) +#define AUX_AGU_AXU_OS5 (0x5d5) +#define AUX_AGU_AXU_OS6 (0x5d6) +#define AUX_AGU_AXU_OS7 (0x5d7) +#define AUX_AGU_AXU_OS8 (0x5d8) +#define AUX_AGU_AXU_OS9 (0x5d9) +#define AUX_AGU_AXU_OS10 (0x5da) +#define AUX_AGU_AXU_OS11 (0x5db) +#define AUX_AGU_AXU_OS12 (0x5dc) +#define AUX_AGU_AXU_OS13 (0x5dd) +#define AUX_AGU_AXU_OS14 (0x5de) +#define AUX_AGU_AXU_OS15 (0x5df) + +#define AUX_AGU_AUX_MOD0 (0x5e0) +#define AUX_AGU_AUX_MOD1 (0x5e1) +#define AUX_AGU_AUX_MOD2 (0x5e2) +#define AUX_AGU_AUX_MOD3 (0x5e3) +#define AUX_AGU_AUX_MOD4 (0x5e4) +#define AUX_AGU_AUX_MOD5 (0x5e5) +#define AUX_AGU_AUX_MOD6 (0x5e6) +#define AUX_AGU_AUX_MOD7 (0x5e7) +#define AUX_AGU_AUX_MOD8 (0x5e8) +#define AUX_AGU_AUX_MOD9 (0x5e9) +#define AUX_AGU_AUX_MOD10 (0x5ea) +#define AUX_AGU_AUX_MOD11 (0x5eb) +#define AUX_AGU_AUX_MOD12 (0x5ec) +#define AUX_AGU_AUX_MOD13 (0x5ed) +#define AUX_AGU_AUX_MOD14 (0x5ee) +#define AUX_AGU_AUX_MOD15 (0x5ef) +#define AUX_AGU_AUX_MOD16 (0x5f0) +#define AUX_AGU_AUX_MOD17 (0x5f1) +#define AUX_AGU_AUX_MOD18 (0x5f2) +#define AUX_AGU_AUX_MOD19 (0x5f3) +#define AUX_AGU_AUX_MOD20 (0x5f4) +#define AUX_AGU_AUX_MOD21 (0x5f5) +#define AUX_AGU_AUX_MOD22 (0x5f6) +#define AUX_AGU_AUX_MOD23 (0x5f7) + +#define AUX_XCCM_BASE (0x5f8) +#define AUX_YCCM_BASE (0x5f9) + + +/** \todo add em series specific definitions here */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _ARC_HAL_EM_H_ */ + +/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_exception.h b/bsp/synopsys/embarc/inc/arc/arc_exception.h new file mode 100644 index 0000000000..e485b159c3 --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_exception.h @@ -0,0 +1,461 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT + * \brief header file of exception and interrupt management module + */ + +#ifndef _ARC_HAL_EXCEPTION_H_ +#define _ARC_HAL_EXCEPTION_H_ + +#include "inc/embARC_toolchain.h" +#include "inc/arc/arc.h" +#include "inc/arc/arc_builtin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup ARC_HAL_EXCEPTION_CPU + * @{ + * \todo need a conf.h from application or board to define the + * features of processor, such as number of exception, code + * density and FIQ. + */ +#ifndef NUM_EXC_CPU +#define NUM_EXC_CPU 16 /*!< number of CPU exceptions */ +#endif + +#ifndef NUM_EXC_INT +#define NUM_EXC_INT 9 /*!< number of interrupt exceptions, defined by users*/ +#endif + +#define NUM_EXC_ALL (NUM_EXC_CPU + NUM_EXC_INT) /*!< total number of exceptions */ + + + +#ifdef ARC_FEATURE_SEC_PRESENT +typedef struct int_exc_frame { + uint32_t erbta; + + uint32_t r30; /* r30 is useless, skipped? */ + uint32_t ilink; /* r29 is useless, skipped?*/ + /* r28 is sp, saved other place */ + uint32_t fp; /* r27 */ + uint32_t gp; /* r26 */ + + uint32_t r12; + + uint32_t lp_end, lp_start, lp_count; + +#ifdef ARC_FEATURE_CODE_DENSITY + uint32_t ei, ldi, jli; +#endif + + uint32_t r0, r1, r2, r3; +#ifndef ARC_FEATURE_RF16 + uint32_t r4, r5, r6, r7, r8, r9; +#endif + uint32_t r10, r11; + + uint32_t blink; /* r31 */ + uint32_t ret; + uint32_t sec_stat; + uint32_t status32; +} EMBARC_PACKED INT_EXC_FRAME; +#else +typedef struct int_exc_frame { + uint32_t erbta; + + uint32_t r30; /* r30 is useless, skipped? */ + uint32_t ilink; /* r29 is useless, skipped?*/ + /* r28 is sp, saved other place */ + uint32_t fp; /* r27 */ + uint32_t gp; /* r26 */ + + uint32_t r12; + + uint32_t r0, r1, r2, r3; +#ifndef ARC_FEATURE_RF16 + uint32_t r4, r5, r6, r7, r8, r9; +#endif + uint32_t r10, r11; + + uint32_t blink; /* r31 */ + + uint32_t lp_end, lp_start, lp_count; + +#ifdef ARC_FEATURE_CODE_DENSITY + uint32_t ei, ldi, jli; +#endif + + uint32_t ret; + uint32_t status32; +} EMBARC_PACKED INT_EXC_FRAME; +#endif + +typedef struct callee_frame { +#ifndef ARC_FEATURE_RF16 + uint32_t r25; + uint32_t r24; + uint32_t r23; + uint32_t r22; + uint32_t r21; + uint32_t r20; + uint32_t r19; + uint32_t r18; + uint32_t r17; + uint32_t r16; +#endif + uint32_t r15; + uint32_t r14; + uint32_t r13; +} EMBARC_PACKED CALLEE_FRAME; + +typedef struct processor_frame { + CALLEE_FRAME callee_regs; + INT_EXC_FRAME exc_frame; +} EMBARC_PACKED PROCESSOR_FRAME; + +#define ARC_PROCESSOR_FRAME_SIZE (sizeof(PROCESSOR_FRAME) / sizeof(uint32_t)) +#define ARC_EXC_FRAME_SIZE (sizeof(INT_EXC_FRAME) / sizeof(uint32_t)) +#define ARC_CALLEE_FRAME_SIZE (sizeof(CALLEE_FRAME) / sizeof(uint32_t)) + + +extern uint32_t exc_nest_count; + +/** + * \brief write the exception vector base + * + * \param[in] vec_base the target vector base + */ +Inline void arc_vector_base_write(const void * vec_base) +{ + _arc_aux_write(AUX_INT_VECT_BASE, (uint32_t)vec_base); +} + +/** + * \brief read current exception vector base + * + * \returns exception vector base (uint32_t) + */ +Inline uint32_t arc_vector_base_read(void) +{ + return _arc_aux_read(AUX_INT_VECT_BASE); +} + +/** + * \brief sense whether in exc/interrupt processing + * + * \retval 0 not in exc/interrupt processing + * \retval 1 in exc/interrupt processing + */ +Inline uint32_t exc_sense(void) +{ + return (exc_nest_count > 0U); +} + +/** @}*/ + +/** + * \addtogroup ARC_HAL_EXCEPTION_INTERRUPT + * @{ + */ +#ifndef INT_PRI_MIN +#define INT_PRI_MIN (-2) /*!< the minimum interrupt priority */ +#endif + +#define INT_PRI_MAX (-1) /*!< the maximum interrupt priority */ +/** + * \brief disable the specific interrupt + * + * \param[in] intno interrupt number + */ +Inline void arc_int_disable(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + _arc_aux_write(AUX_IRQ_ENABLE, 0); +} + +/** + * \brief enable the specific int + * + * \param[in] intno interrupt number + */ +Inline void arc_int_enable(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + _arc_aux_write(AUX_IRQ_ENABLE, 1); +} + +/** + * \brief check whether the specific int is enabled + * + * \param[in] intno interrupt number + * \return 0 disabled, 1 enabled + */ +Inline uint32_t arc_int_enabled(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + return _arc_aux_read(AUX_IRQ_ENABLE); +} + +/** + * \brief get the interrupt priority mask + * + * \returns interrupt priority mask, negative num + */ +Inline uint32_t arc_int_ipm_get(void) +{ + return ((_arc_aux_read(AUX_STATUS32) >> 1) & 0x0f); +} + +/** + * \brief set the interrupt priority mask + * + * \param[in] intpri interrupt priority + */ +Inline void arc_int_ipm_set(uint32_t intpri) +{ + volatile uint32_t status; + status = _arc_aux_read(AUX_STATUS32) & ~0x1e; + + status = status | ((intpri << 1) & 0x1e); + /* sr cannot write AUX_STATUS32 */ + Asm("kflag %0"::"ir"(status)); +} + +/** + * \brief get current interrupt priority mask + * + * \param[in] intno interrupt number + */ +Inline uint32_t arc_int_pri_get(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + return _arc_aux_read(AUX_IRQ_PRIORITY); +} + +/** + * \brief set interrupt priority + * + * \param[in] intno interrupt number + * \param[in] intpri interrupt priority + */ +Inline void arc_int_pri_set(const uint32_t intno, uint32_t intpri) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + _arc_aux_write(AUX_IRQ_PRIORITY, intpri | (_arc_aux_read(AUX_IRQ_PRIORITY) & 0xfffffff0)); +} + +/** + * \brief set interrupt secure or not secure + * + * \param[in] intno interrupt number + * \param[in] secure, 0 for normal, >0 for secure + */ +Inline void arc_int_secure_set(const uint32_t intno, uint32_t secure) +{ + + _arc_aux_write(AUX_IRQ_SELECT, intno); + + if (secure) { + _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) | + (1 << AUX_IRQ_PRIORITY_BIT_S)); + } else { + _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) & 0xf); + } + +} + +/** + * \brief probe the pending status of interrupt + * + * \param[in] intno interrupt number + * + * \returns 1 pending, 0 no pending + */ +Inline uint32_t arc_int_probe(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + return _arc_aux_read(AUX_IRQ_PENDING); +} + +/** + * \brief trigger the interrupt in software + * + * \param[in] intno interrupt number + */ +Inline void arc_int_sw_trigger(const uint32_t intno) +{ + _arc_aux_write(AUX_IRQ_HINT, intno); +} + +/** + * \brief config the interrupt level triggered or pulse triggered + * + * \param[in] intno interrupt number + * \param[in] level, 0-level trigger, 1-pluse triggered + */ +Inline void arc_int_level_config(const uint32_t intno, const uint32_t level) +{ + _arc_aux_write(AUX_IRQ_SELECT, intno); + _arc_aux_write(AUX_IRQ_TRIGGER, level); +} + +/** + * \brief lock cpu, disable interrupts + */ +Inline void arc_lock(void) +{ + Asm("clri"); + Asm("":::"memory"); +} + +/** + * \brief unlock cpu, enable interrupts to happen + */ +Inline void arc_unlock(void) +{ + Asm("":::"memory"); + Asm("seti"); +} + +/** + * \brief lock cpu and staus + * + * \returns cpu status + */ +Inline uint32_t arc_lock_save(void) +{ + return _arc_clri(); +} + +/** + * \brief unlock cpu with the specific status + * + * \param[in] status cpu status saved by cpu_lock_save + */ +Inline void arc_unlock_restore(const uint32_t status) +{ + _arc_seti(status); +} +/** @}*/ + +/** + * \addtogroup ARC_HAL_EXCEPTION_CPU + * @{ + */ +/** + * \typedef EXC_ENTRY + * \brief the data type for exception entry + */ +typedef void (*EXC_ENTRY) (void); +/** + * \typedef EXC_HANDLER + * \brief the data type for exception handler + */ +typedef void (*EXC_HANDLER) (void *exc_frame); +/** @}*/ + + +/** + * \ingroup ARC_HAL_EXCEPTION_INTERRUPT + * \typedef INT_HANDLER + * \brief the data type for interrupt handler + */ +typedef void (*INT_HANDLER) (void *ptr); + +extern EXC_ENTRY exc_entry_table[NUM_EXC_ALL]; +extern EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL]; + +/** \ingroup ARC_HAL_EXCEPTION_CPU + * @{ + */ +/** + * \fn _arc_reset + * \brief the reset entry + */ +extern void _arc_reset(void); +/** + * \fn exc_entry_cpu + * \brief the default CPU exception entry + */ +extern void exc_entry_cpu(void); + +/** + * \fn exc_entry_firq + * \brief the fast interrupt exception entry + */ +extern void exc_entry_firq(void); +/** + * \fn exc_entry_int + * \brief the interrupt exception entry + */ +extern void exc_entry_int(void); +/** @}*/ + +/* excetpion related apis */ +extern void exc_int_init(void); +extern int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry); +extern EXC_ENTRY exc_entry_get(const uint32_t excno); +extern int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler); +extern EXC_HANDLER exc_handler_get(const uint32_t excno); + +/* interrupt related apis */ +extern int32_t int_disable(const uint32_t intno); +extern int32_t int_enable(const uint32_t intno); +extern int32_t int_enabled(const uint32_t intno); +extern int32_t int_ipm_get(void); +extern int32_t int_ipm_set(int32_t intpri); +extern int32_t int_pri_get(const uint32_t intno); +extern int32_t int_pri_set(const uint32_t intno, int32_t intpri); +extern int32_t int_probe(const uint32_t intno); +extern int32_t int_sw_trigger(const uint32_t intno); +extern int32_t int_level_config(const uint32_t intno, const uint32_t level); +extern void cpu_lock(void); +extern void cpu_unlock(void); +extern uint32_t cpu_lock_save(void); +extern void cpu_unlock_restore(const uint32_t status); +extern int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler); +extern INT_HANDLER int_handler_get(const uint32_t intno); +extern int32_t int_secure_set(const uint32_t intno, uint32_t secure); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARC_HAL_EXCEPTION_H_*/ diff --git a/bsp/synopsys/embarc/inc/arc/arc_feature_config.h b/bsp/synopsys/embarc/inc/arc/arc_feature_config.h new file mode 100644 index 0000000000..87b1913df5 --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_feature_config.h @@ -0,0 +1,397 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2016-09-08 + * \author Huaqi Fang(Huaqi.Fang@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_MISC + * \brief header file for arc feature configuration + */ + +/** + * \addtogroup ARC_HAL_MISC + * @{ + */ + +#ifndef _ARC_FEATURE_CONFIG_H_ +#define _ARC_FEATURE_CONFIG_H_ + +// Enable core_config.h in EMSK OSP +//#ifdef EMBARC_TCF_GENERATED +#include "arc_core_config.h" +//#endif + +/** ARC baseline instruction set version number */ +#if !defined(_ARCVER) +#if defined(core_config_cir_identity_arcver) +#define _ARCVER core_config_cir_identity_arcver +#else +#define _ARCVER 0x42 +#endif +#endif + +/** ARC CPU Clock Frequency in Hz unit */ +#if !defined(ARC_FEATURE_CPU_CLOCK_FREQ) +#if defined(core_config_clock_speed) +#define ARC_FEATURE_CPU_CLOCK_FREQ (core_config_clock_speed*1000000) +#endif +#endif + +/** ARC PC size */ +#if !defined(ARC_FEATURE_PC_SIZE) +#if defined(core_config_pc_size) +#define ARC_FEATURE_PC_SIZE core_config_pc_size +#else +#define ARC_FEATURE_PC_SIZE 32 +#endif +#endif + +/** ARC LPC size */ +#if !defined(ARC_FEATURE_LPC_SIZE) +#if defined(core_config_lpc_size) +#define ARC_FEATURE_LPC_SIZE core_config_lpc_size +#else +#define ARC_FEATURE_LPC_SIZE 32 +#endif +#endif + +/** ARC Addr size */ +#if !defined(ARC_FEATURE_ADDR_SIZE) +#if defined(core_config_addr_size) +#define ARC_FEATURE_ADDR_SIZE core_config_addr_size +#else +#define ARC_FEATURE_ADDR_SIZE 32 +#endif +#endif + +/** ARC Endian/Byte Order */ +#define ARC_FEATURE_LITTLE_ENDIAN 1234 +#define ARC_FEATURE_BIG_ENDIAN 4321 + +#if !defined(ARC_FEATURE_BYTE_ORDER) +#if defined(core_config_bcr_isa_config_b) +#if core_config_bcr_isa_config_b == 0 +#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_LITTLE_ENDIAN +#else +#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_BIG_ENDIAN +#endif +#else +#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_LITTLE_ENDIAN +#endif +#endif + +/** Reduced register option, if enabled, ARC_FEATURE_RF16 will be defined */ +#if !defined(ARC_FEATURE_RF16) +#if defined(core_config_bcr_rf_build_e) && core_config_bcr_rf_build_e == 1 +#define ARC_FEATURE_RF16 +#endif +#endif + +/** Unaligned access option, if enabled, ARC_FEATURE_UNALIGNED will be defined */ +#if !defined(ARC_FEATURE_UNALIGNED) +#if defined(core_config_unaligned) && core_config_unaligned == 1 +#define ARC_FEATURE_UNALIGNED +#endif +#endif + + +/** Code density option, if enabled, ARC_FEATURE_CODE_DENSITY will be defined */ +#if !defined(ARC_FEATURE_CODE_DENSITY) +#if defined(core_config_code_density) && core_config_code_density == 1 +#define ARC_FEATURE_CODE_DENSITY +#endif +#endif + +/** The number of register file banks */ +#if !defined(ARC_FEATURE_RGF_NUM_BANKS) +#if defined(core_config_rgf_num_banks) +#define ARC_FEATURE_RGF_NUM_BANKS core_config_rgf_num_banks +#else +#define ARC_FEATURE_RGF_NUM_BANKS 1 +#endif +#endif + +/** The number of registers replicated per register bank */ +#if !defined(ARC_FEATURE_RGF_BANKED_REGS) +#if defined(core_config_rgf_banked_regs) +#define ARC_FEATURE_RGF_BANKED_REGS core_config_rgf_banked_regs +#endif +#endif + +/** Interrupt unit presence */ +#if !defined(ARC_FEATURE_INTERRUPTS_PRESENT) +#if defined(core_config_interrupts_present) +#define ARC_FEATURE_INTERRUPTS_PRESENT core_config_interrupts_present +#endif +#endif + +/** FIRQ_OPTION configuration option, 1 for enabled, 0 for disabled */ +#if !defined(ARC_FEATURE_FIRQ) +#if defined(core_config_bcr_irq_build_f) +#define ARC_FEATURE_FIRQ core_config_bcr_irq_build_f +#else +#define ARC_FEATURE_FIRQ 0 +#endif +#endif + +/** The number of interrupts */ +#if !defined(NUM_EXC_INT) +#if defined(core_config_interrupts_number) +#define NUM_EXC_INT core_config_interrupts_number +#endif +#endif + +/** The number of external interrupts */ +#if !defined(NUM_EXC_EXT_INT) +#if defined(core_config_interrupts_externals) +#define NUM_EXC_EXT_INT core_config_interrupts_externals +#endif +#endif + +/** The interrupt priority levels */ +#if !defined(INT_PRI_MIN) +#if defined(core_config_interrupts_priorities) +#define INT_PRI_MIN (-core_config_interrupts_priorities) +#endif +#endif + +// ARC TIMER_BUILD +/** Timer0 present or not */ +#if !defined(ARC_FEATURE_TIMER0_PRESENT) +#if defined(core_config_timer0) +#define ARC_FEATURE_TIMER0_PRESENT core_config_timer0 +#define ARC_FEATURE_TIMER0_LEVEL (core_config_timer0_level-core_config_interrupts_priorities) +#define ARC_FEATURE_TIMER0_VECTOR core_config_timer0_vector +#endif +#endif + +/** Timer1 present or not */ +#if !defined(ARC_FEATURE_TIMER1_PRESENT) +#if defined(core_config_timer1) +#define ARC_FEATURE_TIMER1_PRESENT core_config_timer1 +#define ARC_FEATURE_TIMER1_LEVEL (core_config_timer1_level-core_config_interrupts_priorities) +#define ARC_FEATURE_TIMER1_VECTOR core_config_timer1_vector +#endif +#endif + +/** Secure Timer0 present or not */ +#if !defined(ARC_FEATURE_SEC_TIMER0_PRESENT) +#if defined(core_config_sec_timer0) +#define ARC_FEATURE_SEC_TIMER0_PRESENT core_config_sec_timer0 +#define ARC_FEATURE_SEC_TIMER0_LEVEL (core_config_sec_timer0_level-core_config_interrupts_priorities) +#define ARC_FEATURE_SEC_TIMER0_VECTOR 20 +#endif +#endif + +/** Secure Timer1 present or not */ +#if !defined(ARC_FEATURE_SEC_TIMER1_PRESENT) +#if defined(core_config_sec_timer1) +#define ARC_FEATURE_SEC_TIMER1_PRESENT core_config_sec_timer1 +#define ARC_FEATURE_SEC_TIMER1_LEVEL (core_config_sec_timer1_level-core_config_interrupts_priorities) +#define ARC_FEATURE_SEC_TIMER1_VECTOR 21 +#endif +#endif + + +/** 64bit RTC present or not */ +#if !defined(ARC_FEATURE_RTC_PRESENT) +#if defined(core_config_rtc) +#define ARC_FEATURE_RTC_PRESENT core_config_rtc +#endif +#endif + +// Memory related definitions +/** ICCM Presence, base address and size */ +#if !defined(ARC_FEATURE_ICCM_PRESENT) +#if defined(core_config_iccm_present) && core_config_iccm_present == 1 +#define ARC_FEATURE_ICCM_PRESENT 1 +#define ARC_FEATURE_ICCM_BASE core_config_iccm_base +#define ARC_FEATURE_ICCM_SIZE core_config_iccm_size +#endif +#endif + +/** ICCM0 Presence, base address and size */ +#if !defined(ARC_FEATURE_ICCM0_PRESENT) +#if defined(core_config_iccm0_present) && core_config_iccm0_present == 1 +#define ARC_FEATURE_ICCM0_PRESENT 1 +#define ARC_FEATURE_ICCM0_BASE core_config_iccm0_base +#define ARC_FEATURE_ICCM0_SIZE core_config_iccm0_size +#endif +#endif + +/** ICCM1 Presence, base address and size */ +#if !defined(ARC_FEATURE_ICCM1_PRESENT) +#if defined(core_config_iccm1_present) && core_config_iccm1_present == 1 +#define ARC_FEATURE_ICCM1_PRESENT 1 +#define ARC_FEATURE_ICCM1_BASE core_config_iccm1_base +#define ARC_FEATURE_ICCM1_SIZE core_config_iccm1_size +#endif +#endif + +/** DCCM Presence, base address and size */ +#if !defined(ARC_FEATURE_DCCM_PRESENT) +#if defined(core_config_dccm_present) && core_config_dccm_present == 1 +#define ARC_FEATURE_DCCM_PRESENT 1 +#define ARC_FEATURE_DCCM_BASE core_config_dccm_base +#define ARC_FEATURE_DCCM_SIZE core_config_dccm_size +#ifdef core_config_dccm_interleave +#define ARC_FEATURE_DCCM_INTERLEAVE core_config_dccm_interleave +#endif +#endif +#endif + +/** Peripheral memory region(DMP) base address, if dmp configured, this macro will be defined as base address */ +#if !defined(ARC_FEATURE_DMP_PERIPHERAL) +#if defined(core_config_cir_dmp_peripheral) +#define ARC_FEATURE_DMP_PERIPHERAL core_config_cir_dmp_peripheral +#endif +#endif + +/** MPU options */ +#if !defined(ARC_FEATURE_MPU_PRESENT) +#if defined(core_config_mpu_present) && core_config_mpu_present == 1 +#define ARC_FEATURE_MPU_PRESENT 1 +#define ARC_FEATURE_MPU_VERSION core_config_bcr_mpu_build_version +#define ARC_FEATURE_MPU_REGIONS core_config_mpu_regions +#ifdef core_config_bcr_mpu_build_i +#define ARC_FEATURE_MPU_BUILD_I core_config_bcr_mpu_build_i +#endif +#ifdef core_config_bcr_mpu_build_s +#define ARC_FEATURE_MPU_BUILD_S core_config_bcr_mpu_build_s +#endif +#endif +#endif + +/** Secure BCR SEC_BUILD BCR */ +#if !defined(ARC_FEATURE_SEC_PRESENT) +#if defined(core_config_bcr_sec_build) +#define ARC_FEATURE_SEC_PRESENT 1 +#define ARC_FEATURE_SEC_VERSION core_config_bcr_sec_build_version +#define ARC_FEATURE_SEC_BUILD_DSM core_config_bcr_sec_build_dsm +#define ARC_FEATURE_SEC_BUILD_NSM core_config_bcr_sec_build_nsm +#define ARC_FEATURE_SEC_BUILD_I1SM core_config_bcr_sec_build_i1sm +#define ARC_FEATURE_SEC_BUILD_I0SM core_config_bcr_sec_build_i0sm +#define ARC_FEATURE_SEC_BUILD_S core_config_bcr_sec_build_s +#define ARC_FEATURE_SEC_BUILD_EI core_config_bcr_sec_build_ei +#define ARC_FEATURE_SEC_BUILD_ED core_config_bcr_sec_build_ed +#endif +#endif + +#if !defined(ARC_FEATURE_SEC_MODES) +#if defined(core_config_sec_modes) +#define ARC_FEATURE_SEC_MODES core_config_sec_modes +#endif +#endif + +/** Data Cache options */ +#if !defined(ARC_FEATURE_DCACHE_PRESENT) +#if defined(core_config_dcache_present) && core_config_dcache_present == 1 +#define ARC_FEATURE_DCACHE_PRESENT 1 +#define ARC_FEATURE_DCACHE_BUILD core_config_bcr_d_cache_build +#define ARC_FEATURE_DCACHE_BUILD_VERSION core_config_bcr_d_cache_build_version +#define ARC_FEATURE_DCACHE_BUILD_ASSOC core_config_bcr_d_cache_build_assoc +#define ARC_FEATURE_DCACHE_BUILD_CAPACITY core_config_bcr_d_cache_build_capacity +#define ARC_FEATURE_DCACHE_BUILD_BSIZE core_config_bcr_d_cache_build_bsize +#define ARC_FEATURE_DCACHE_BUILD_FL core_config_bcr_d_cache_build_fl +#define ARC_FEATURE_DCACHE_BUILD_U core_config_bcr_d_cache_build_u +#define ARC_FEATURE_DCACHE_SIZE core_config_dcache_size +#define ARC_FEATURE_DCACHE_LINE_SIZE core_config_dcache_line_size +#define ARC_FEATURE_DCACHE_WAYS core_config_dcache_ways +#define ARC_FEATURE_DCACHE_FEATURE core_config_dcache_feature +#endif +#endif + +/** Instruction Cache options */ +#if !defined(ARC_FEATURE_ICACHE_PRESENT) +#if defined(core_config_icache_present) && core_config_icache_present == 1 +#define ARC_FEATURE_ICACHE_PRESENT 1 +#define ARC_FEATURE_ICACHE_BUILD core_config_bcr_i_cache_build +#define ARC_FEATURE_ICACHE_BUILD_VERSION core_config_bcr_i_cache_build_version +#define ARC_FEATURE_ICACHE_BUILD_ASSOC core_config_bcr_i_cache_build_assoc +#define ARC_FEATURE_ICACHE_BUILD_CAPACITY core_config_bcr_i_cache_build_capacity +#define ARC_FEATURE_ICACHE_BUILD_BSIZE core_config_bcr_i_cache_build_bsize +#define ARC_FEATURE_ICACHE_BUILD_FL core_config_bcr_i_cache_build_fl +#define ARC_FEATURE_ICACHE_BUILD_D core_config_bcr_i_cache_build_d +#define ARC_FEATURE_ICACHE_SIZE core_config_icache_size +#define ARC_FEATURE_ICACHE_LINE_SIZE core_config_icache_line_size +#define ARC_FEATURE_ICACHE_WAYS core_config_icache_ways +#define ARC_FEATURE_ICACHE_FEATURE core_config_icache_feature +#endif +#endif + +/** ARC uDMA options */ +#if !defined(ARC_FEATURE_DMAC) +#if defined(core_config_dmac) +#define ARC_FEATURE_DMAC core_config_dmac +#define CORE_DMAC_CHANNELS core_config_dmac_channels +#define CORE_DMAC_REGISTERS core_config_dmac_registers +#if core_config_bcr_dmac_build_int_cfg == 2 && core_config_bcr_dmac_build_int_cfg == 4 +#define DMA_MULTI_IRQ 1 +#else +#define DMA_MULTI_IRQ 0 +#endif +#define ARC_FEATURE_DMAC_PRESENT core_config_dmac +#define ARC_FEATURE_DMAC_VERSION core_config_bcr_dmac_build_version +#define ARC_FEATURE_DMAC_CHANNELS core_config_dmac_channels +#define ARC_FEATURE_DMAC_REGISTERS core_config_dmac_registers +#define ARC_FEATURE_DMAC_INT_CFG core_config_bcr_dmac_build_int_cfg +#define ARC_FEATURE_DMAC_FIFO_DEPTH core_config_dmac_fifo_depth + +#ifdef ARC_FEATURE_SEC_TIMER0_PRESENT +#define DMA_IRQ_NUM_START 22 +#define ARC_FEATURE_DMAC_VECTOR_START 22 +#else +#define DMA_IRQ_NUM_START 20 +#define ARC_FEATURE_DMAC_VECTOR_START 20 +#endif + +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ARC_FEATURE_UNALIGNED +#define STATUS32_RESET_VALUE (1<<19) +#else +#define STATUS32_RESET_VALUE (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _ARC_FEATURE_CONFIG_H_ */ + +/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_timer.h b/bsp/synopsys/embarc/inc/arc/arc_timer.h new file mode 100644 index 0000000000..b5237f31a9 --- /dev/null +++ b/bsp/synopsys/embarc/inc/arc/arc_timer.h @@ -0,0 +1,99 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-07-15 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup ARC_HAL_MISC_TIMER + * \brief header file of ARC internal timer + */ + +/** + * \addtogroup ARC_HAL_MISC_TIMER + * @{ + */ + +#ifndef _ARC_HAL_TIMER_H_ +#define _ARC_HAL_TIMER_H_ +#include "inc/arc/arc.h" +#include "inc/embARC_toolchain.h" + +/** + * \name arc internal timers names + * @{ + */ +#define TIMER_0 0 /*!< macro name for arc internal timer 0 */ +#define TIMER_1 1 /*!< macro name for arc internal timer 1 */ +#define TIMER_RTC 2 /*!< macro name for arc internal RTC */ + +/** @} */ + +/** + * \name bit definition of RTC CTRL reg + * @{ + */ + +#define TIMER_RTC_ENABLE 0x01 /*!< enable RTC */ +#define TIMER_RTC_CLEAR 0x02 /* clears the AUX_RTC_LOW and AUX_RTC_HIGH */ +#define TIMER_RTC_STATUS_A0 0x40000000 /*!< track bit of atomicity of reads of RTC */ +#define TIMER_RTC_STATUS_A1 0x80000000 /*!< track bit of atomicity of reads of RTC */ + +/** @} */ + +/** + * \name bit definition of timer CTRL reg + * @{ + */ +#define TIMER_CTRL_IE (1 << 0) /*!< Interrupt when count reaches limit */ +#define TIMER_CTRL_NH (1 << 1) /*!< Count only when CPU NOT halted */ +#define TIMER_CTRL_W (1 << 2) /*!< watchdog enable */ +#define TIMER_CTRL_IP (1 << 3) /*!< interrupt pending */ + +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int32_t arc_timer_present(const uint32_t no); +extern int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val); +extern int32_t arc_timer_stop(const uint32_t no); +extern int32_t arc_timer_current(const uint32_t no, void* val); +extern int32_t arc_timer_int_clear(const uint32_t no); +extern void arc_timer_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARC_HAL_TIMER_H_ */ +/** }@*/ diff --git a/bsp/synopsys/embarc/inc/embARC_debug.h b/bsp/synopsys/embarc/inc/embARC_debug.h new file mode 100644 index 0000000000..092374622d --- /dev/null +++ b/bsp/synopsys/embarc/inc/embARC_debug.h @@ -0,0 +1,94 @@ +/* ------------------------------------------ + * Copyright (c) 2017, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2017.03 + * \date 2014-12-26 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup EMBARC_DEBUG + * \brief necessary definitions of debug + */ + +#ifndef _EMBARC_DEBUG_H_ +#define _EMBARC_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EMBARC_PRINTF + #include "common/xprintf.h" + #define EMBARC_PRINTF xprintf +#endif + +/* + * if you want to use DBG or dbg_printf, + * please define DEBUG or DBG_LESS or DBG_MORE before include embARC_debug.h + * DEBUG: enable debug print + * DBG_LESS: enable less debug msg + * DBG_MORE: enable more debug msg + **/ + +#if defined(DEBUG) +#if defined(DEBUG_HOSTLINK) +#include +#define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define DBG(fmt, ...) EMBARC_PRINTF(fmt, ##__VA_ARGS__) +#endif +#else +#define DBG(fmt, ...) +#endif + +#define DBG_LESS_INFO 0x01 /* less debug messages */ +#define DBG_MORE_INFO 0x02 /* more debug messages */ + + +#if defined (DBG_LESS) +#define DBG_TYPE (DBG_LESS_INFO) +#elif defined (DBG_MORE) +#define DBG_TYPE ((DBG_LESS_INFO) | (DBG_MORE_INFO)) +#else +#define DBG_TYPE 0 +#endif + +#if DBG_TYPE > 0 +#define dbg_printf(type, fmt, ...) \ + if (((type) & DBG_TYPE)) { EMBARC_PRINTF(fmt, ##__VA_ARGS__); } +#else +#define dbg_printf(type, fmt, ...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* DEBUG_H_ */ diff --git a/bsp/synopsys/embarc/inc/embARC_error.h b/bsp/synopsys/embarc/inc/embARC_error.h new file mode 100644 index 0000000000..9bd9c318aa --- /dev/null +++ b/bsp/synopsys/embarc/inc/embARC_error.h @@ -0,0 +1,156 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-12-25 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup EMBARC_ERROR + * \brief header file to define common definitions error management + */ + +/** + * \addtogroup EMBARC_ERROR + * @{ + */ + +#ifndef _EMBARC_ERROR_H_ +#define _EMBARC_ERROR_H_ + +#include +#include "inc/arc/arc_builtin.h" + +#ifdef __cplusplus +extern "C" { +#endif +/** + * \name Main Error Code Definitions + * @{ + */ +#define E_OK (0) /*!< ok */ +#define E_SYS (-5) /*!< system error */ +#define E_NOSPT (-9) /*!< unsupported features */ +#define E_RSFN (-10) /*!< reserved function code */ +#define E_RSATR (-11) /*!< reserved attribute */ +#define E_PAR (-17) /*!< parameter error */ +#define E_ID (-18) /*!< invalid ID number */ +#define E_CTX (-25) /*!< context error */ +#define E_MACV (-26) /*!< memory access violation */ +#define E_OACV (-27) /*!< object access violation */ +#define E_ILUSE (-28) /*!< illegal service call use */ +#define E_NOMEM (-33) /*!< insufficient memory */ +#define E_NOID (-34) /*!< no ID number available */ +#define E_NORES (-35) /*!< no resource available */ +#define E_OBJ (-41) /*!< object state error */ +#define E_NOEXS (-42) /*!< non-existent object */ +#define E_QOVR (-43) /*!< queue overflow */ +#define E_RLWAI (-49) /*!< forced release from waiting */ +#define E_TMOUT (-50) /*!< polling failure or timeout */ +#define E_DLT (-51) /*!< waiting object deleted */ +#define E_CLS (-52) /*!< waiting object state changed */ +#define E_WBLK (-57) /*!< non-blocking accepted */ +#define E_BOVR (-58) /*!< buffer overflow */ +#define E_OPNED (-6) /*!< device is opened */ +#define E_CLSED (-7) /*!< device is closed */ +/** @} end of name */ + +/** + * \name Generate And Decompose Error Code + * @{ + */ +#ifndef ERCD +/** generate error code using main error code and sub error code */ +#define ERCD(mercd, sercd) \ + ((uint32_t)((((uint32_t) sercd) << 8) | (((uint32_t) mercd) & 0xffU))) +#endif /* ERCD */ + +#ifndef MERCD +#ifdef INT8_MAX +/** get main error code from error code */ +#define MERCD(ercd) ((uint32_t)((int8_t)(ercd))) +#else /* INT8_MAX */ +/** get main error code from error code */ +#define MERCD(ercd) ((uint32_t)(((uint32_t) ercd) | ~0xffU)) +#endif /* INT8_MAX */ +#endif /* MERCD */ + +#ifndef SERCD +/** get sub error code from error code */ +#define SERCD(ercd) ((uint32_t)((ercd) >> 8)) +#endif /* SERCD */ +/** @} end of name */ + +/** + * \name Check Error + * @{ + */ +/** + * \brief check an expression to see if it is right, and when error + * set the ercd, and goto exit_label + * \param EXPR the expression that need to be checked (==0 failed) + * \param ERCD MUST pass a variable to here to get the error code + * \param ERROR_CODE error code that pass to ERCD + * \param EXIT_LABEL a label to go when error happens + */ +#define CHECK_EXP(EXPR, ERCD, ERROR_CODE, EXIT_LABEL) { \ + if (_arc_rarely(!(EXPR))) { \ + ERCD = (ERROR_CODE); \ + goto EXIT_LABEL; \ + } \ + } +/** + * \brief check an expression to see if it is right, and when error + * directly goto exit_label + * \param EXPR the expression that need to be checked (==0 failed) + * \param EXIT_LABEL a label to go when error happens + * \retval + */ +#define CHECK_EXP_NOERCD(EXPR, EXIT_LABEL) { \ + if (_arc_rarely(!(EXPR))) { \ + goto EXIT_LABEL; \ + } \ + } +/** check cnt bytes align, 1 for aligned, 0 for not-aligned */ +#define CHECK_ALIGN_BYTES(pointer, cnt) ((((uint32_t)(pointer)) & (cnt-1)) == 0) +/** check 2 bytes align, 1 for aligned, 0 for not-aligned */ +#define CHECK_ALIGN_2BYTES(pointer) ((((uint32_t)(pointer)) & 0x1) == 0) +/** check 4 bytes align, 1 for aligned, 0 for not-aligned */ +#define CHECK_ALIGN_4BYTES(pointer) ((((uint32_t)(pointer)) & 0x3) == 0) +/** check 8 bytes align, 1 for aligned, 0 for not-aligned */ +#define CHECK_ALIGN_8BYTES(pointer) ((((uint32_t)(pointer)) & 0x7) == 0) +/** @} end of name */ + +#ifdef __cplusplus +} +#endif + +#endif /* _EMBARC_ERROR_H_ */ +/** @} end of group EMBARC_ERROR */ diff --git a/bsp/synopsys/embarc/inc/embARC_toolchain.h b/bsp/synopsys/embarc/inc/embARC_toolchain.h new file mode 100644 index 0000000000..37aef66064 --- /dev/null +++ b/bsp/synopsys/embarc/inc/embARC_toolchain.h @@ -0,0 +1,121 @@ +/* ------------------------------------------ + * Copyright (c) 2016, Synopsys, Inc. All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + + * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * \version 2016.05 + * \date 2014-12-25 + * \author Wayne Ren(Wei.Ren@synopsys.com) +--------------------------------------------- */ + +/** + * \file + * \ingroup TOOLCHAIN + * \brief toolchain dependent definitions + */ + +#include /* C99 standard lib */ +#include /* C99 standard lib */ +#include /* C99 standard lib */ +#include /* C99 standard lib */ + +#include "embARC_BSP_config.h" + +/** + * \addtogroup TOOLCHAIN + * @{ + */ + +#ifndef _EMBARC_TOOLCHAIN_H_ +#define _EMBARC_TOOLCHAIN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * macro definitions of compiler extend function + */ +#ifndef __cplusplus /* C++ supports inline */ +#if __STDC_VERSION__ < 199901L /* C99 supports inline */ +#ifndef inline +#define inline __inline__ /* inline function */ +#endif +#endif /* __STDC_VERSION__ < 199901L */ +#endif /* __cplusplus */ + +#ifndef Inline +#define Inline static __inline__ /* inline function */ +#endif + +#ifndef __cplusplus /* C++ supports asm */ +#ifndef asm +#define asm __asm__ /* inline asm */ +#endif +#endif /* __cplusplus */ + +#ifndef Asm +#define Asm __asm__ volatile /* inline asm (no optimization) */ +#endif + +/* compiler attributes */ +#define EMBARC_FORCEINLINE __attribute__((always_inline)) +#define EMBARC_NOINLINE __attribute__((noinline)) +#define EMBARC_PACKED __attribute__((packed)) +#define EMBARC_WEAK __attribute__((weak)) +#define EMBARC_ALIAS(f) __attribute__((weak, alias (#f))) +#define EMBARC_LINKTO(f) __attribute__((alias (#f))) +#define EMBARC_NORETURN __attribute__((noreturn)) +#define EMBARC_NAKED __attribute__((naked)) /* function without return */ +#define EMBARC_ALIGNED(x) __attribute__((aligned(x))) + + +/* array count macro */ +#define EMBARC_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) + +/* convert macro argument to string */ +/* note: this needs one level of indirection, accomplished with the helper macro + * __EMBARC_TO_STRING */ +#define __EMBARC_TO_STRING(x) #x +#define EMBARC_TO_STRING(x) __EMBARC_TO_STRING(x) + +#if defined(__GNU__) +/* GNU tool specific definitions */ + +#elif defined(__MW__) +/* Metaware tool specific definitions */ +/* Metaware toolchain related definitions */ + +#else +#error "unsupported toolchain" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _EMBARC_TOOLCHAIN_H_ */ +/** }@ */ diff --git a/bsp/synopsys/emsk_em9d/.config b/bsp/synopsys/emsk_em9d/.config new file mode 100644 index 0000000000..55759f136a --- /dev/null +++ b/bsp/synopsys/emsk_em9d/.config @@ -0,0 +1,402 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# 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=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x40000 +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD 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_ECHO_DISABLE_DEFAULT is not set +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 +CONFIG_FINSH_ARG_MAX=10 + +# +# 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=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# 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_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_MTD is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set + +# +# Using WiFi +# +# 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 is not set +# CONFIG_RT_USING_POSIX is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +CONFIG_RT_USING_SAL=y + +# +# protocol stack implement +# +CONFIG_SAL_USING_LWIP=y +CONFIG_SAL_USING_AT=y +# CONFIG_SAL_USING_POSIX is not set +CONFIG_SAL_SOCKETS_NUM=16 +CONFIG_SAL_PROTO_FAMILIES_NUM=4 + +# +# light weight TCP/IP stack +# +CONFIG_RT_USING_LWIP=y +# CONFIG_RT_USING_LWIP141 is not set +CONFIG_RT_USING_LWIP202=y +# CONFIG_RT_USING_LWIP210 is not set +# CONFIG_RT_USING_LWIP_IPV6 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=y +CONFIG_IP_SOF_BROADCAST=1 +CONFIG_IP_SOF_BROADCAST_RECV=1 + +# +# Static IPv4 Address +# +CONFIG_RT_LWIP_IPADDR="192.168.1.30" +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=16 +CONFIG_RT_LWIP_RAW_PCB_NUM=4 +CONFIG_RT_LWIP_UDP_PCB_NUM=4 +CONFIG_RT_LWIP_TCP_PCB_NUM=4 +CONFIG_RT_LWIP_TCP_SEG_NUM=40 +CONFIG_RT_LWIP_TCP_SND_BUF=8196 +CONFIG_RT_LWIP_TCP_WND=8196 +CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10 +CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8 +CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=1024 +# CONFIG_LWIP_NO_RX_THREAD is not set +# CONFIG_LWIP_NO_TX_THREAD is not set +CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12 +CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024 +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 +# CONFIG_RT_LWIP_STATS is not set +# CONFIG_RT_LWIP_DEBUG is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +CONFIG_RT_USING_AT=y +# CONFIG_AT_DEBUG is not set +# CONFIG_AT_USING_SERVER is not set +CONFIG_AT_USING_CLIENT=y +CONFIG_AT_CLIENT_NUM_MAX=1 +CONFIG_AT_USING_SOCKET=y +CONFIG_AT_USING_CLI=y +# CONFIG_AT_PRINT_RAW_CMD is not set +CONFIG_AT_SW_VERSION_NUM=0x10200 +# 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 +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set + +# +# RT-Thread online packages +# + +# +# 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_JSMN is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +CONFIG_PKG_USING_AT_DEVICE=y +CONFIG_PKG_AT_DEVICE_PATH="/packages/iot/at_device" +CONFIG_PKG_AT_INIT_BY_THREAD=y +# CONFIG_AT_DEVICE_M26 is not set +# CONFIG_AT_DEVICE_EC20 is not set +CONFIG_AT_DEVICE_ESP8266=y +# CONFIG_AT_DEVICE_NOT_SELECTED is not set +CONFIG_AT_DEVICE_SOCKETS_NUM=5 +CONFIG_AT_DEVICE_NAME="uart0" +CONFIG_AT_DEVICE_RECV_BUFF_LEN=512 +CONFIG_AT_DEVICE_WIFI_SSID="embarc" +CONFIG_AT_DEVICE_WIFI_PASSWORD="qazwsxedc" +CONFIG_PKG_USING_AT_DEVICE_LATEST_VERSION=y +# CONFIG_PKG_USING_AT_DEVICE_V100 is not set +# CONFIG_PKG_USING_AT_DEVICE_V110 is not set +CONFIG_PKG_AT_DEVICE_VER="latest" + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_STM32F4_HAL is not set +# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set + +# +# sample package +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_SOC_EMSK=y +CONFIG_EMSK_USING_UART0=y +CONFIG_EMSK_USING_UART1=y diff --git a/bsp/synopsys/emsk_em9d/Kconfig b/bsp/synopsys/emsk_em9d/Kconfig new file mode 100644 index 0000000000..1748a1e8ae --- /dev/null +++ b/bsp/synopsys/emsk_em9d/Kconfig @@ -0,0 +1,26 @@ +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" + +config SOC_EMSK + bool + select ARCH_ARC_EM + default y + +source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/synopsys/emsk_em9d/SConscript b/bsp/synopsys/emsk_em9d/SConscript new file mode 100644 index 0000000000..86b6c891cd --- /dev/null +++ b/bsp/synopsys/emsk_em9d/SConscript @@ -0,0 +1,18 @@ +# for module compiling +import os +Import('RTT_ROOT') + +cwd = str(Dir('#')) +objs = [] +list = os.listdir(cwd) + +ASFLAGS = ' -I' + cwd + +objs = objs + SConscript(os.path.join(cwd, '../embarc/SConscript')) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/synopsys/emsk_em9d/SConstruct b/bsp/synopsys/emsk_em9d/SConstruct new file mode 100644 index 0000000000..a93d89ee74 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/SConstruct @@ -0,0 +1,52 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] + +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread_snps_emsk_em9d.' + rtconfig.TARGET_EXT + +# use scons --gdb to debug emsk +AddOption('--gdb', + dest = 'gdb', + action = 'store_true', + default = False, + help = 'use gdb to debug the elf') + +if GetOption('gdb'): + if os.path.isfile(rtconfig.TARGET): + os.system(rtconfig.DBG + rtconfig.DBG_HW_FLAGS + rtconfig.TARGET) + else: + print rtconfig.TARGET + 'not exist, please build first!!' + exit(0) + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# if the linker script changed, relink the target +Depends(TARGET, rtconfig.LINK_SCRIPT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/synopsys/emsk_em9d/applications/SConscript b/bsp/synopsys/emsk_em9d/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/synopsys/emsk_em9d/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/synopsys/emsk_em9d/applications/application.c b/bsp/synopsys/emsk_em9d/applications/application.c new file mode 100644 index 0000000000..3e12c0ba76 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/applications/application.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* thread phase init */ +static void rt_init_thread_entry(void *parameter) +{ + /* do component initialization */ + rt_components_init(); + + /* add your initialization here */ +} + +int rt_application_init() +{ + rt_thread_t tid; + + tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, + RT_THREAD_PRIORITY_MAX/3, 20); + if (tid != RT_NULL) + rt_thread_startup(tid); + + return 0; +} + diff --git a/bsp/synopsys/emsk_em9d/applications/startup.c b/bsp/synopsys/emsk_em9d/applications/startup.c new file mode 100644 index 0000000000..f561436272 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/applications/startup.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +extern int rt_application_init(void); + +void rt_hw_interrupt_init(void) +{ + /* rt-thread specific interrupt and exception init */ +} + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + + /* initialize board */ + rt_hw_board_init(); + + /* show RT-Thread version */ + rt_show_version(); + + /* initialize memory system */ +#ifdef RT_USING_HEAP + rt_system_heap_init(HEAP_BEGIN, HEAP_END); +#endif + + /* initialize scheduler system */ + rt_system_scheduler_init(); + + /* initialize system timer */ + rt_system_timer_init(); + + /* initialize soft timer thread */ + rt_system_timer_thread_init(); + + /* initialize application */ + rt_application_init(); + + /* initialize idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int board_main(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* invoke rtthread_startup */ + rtthread_startup(); + + return 0; +} + diff --git a/bsp/synopsys/emsk_em9d/drivers/Kconfig b/bsp/synopsys/emsk_em9d/drivers/Kconfig new file mode 100644 index 0000000000..3cc4d3470d --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/Kconfig @@ -0,0 +1,10 @@ + +config EMSK_USING_UART0 + bool "Using UART0" + select RT_USING_SERIAL + default y + +config EMSK_USING_UART1 + bool "Using UART1" + select RT_USING_SERIAL + default y \ No newline at end of file diff --git a/bsp/synopsys/emsk_em9d/drivers/SConscript b/bsp/synopsys/emsk_em9d/drivers/SConscript new file mode 100644 index 0000000000..29272aa88e --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/SConscript @@ -0,0 +1,15 @@ +import copy +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + +ASFLAGS = ' -I' + cwd + +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h b/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h new file mode 100644 index 0000000000..8340e94091 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h @@ -0,0 +1,229 @@ +/* This file is automatically generated from tcf file. DO NOT EDIT */ +#ifndef __core_config_h + #define __core_config_h 1 + #define core_config_cir_identity 0x00000042 + #define core_config_cir_identity_chipid 0 + #define core_config_cir_identity_arcnum 0 + #define core_config_cir_identity_arcver 66 + #define core_config_cir_identity_family 4 + #define core_config_cir_identity_corever 2 + #define core_config_cir_aux_dccm 0x80000000 + #define core_config_bcr_bcr_ver 0x00000002 + #define core_config_bcr_bcr_ver_version 2 + #define core_config_bcr_vecbase_ac_build 0x00000010 + #define core_config_bcr_rf_build 0x0000c902 + #define core_config_bcr_rf_build_version 2 + #define core_config_bcr_rf_build_p 1 + #define core_config_bcr_rf_build_e 0 + #define core_config_bcr_rf_build_r 0 + #define core_config_bcr_rf_build_b 1 + #define core_config_bcr_rf_build_d 3 + #define core_config_bcr_dccm_build 0x00010904 + #define core_config_bcr_dccm_build_cycles 0 + #define core_config_bcr_dccm_build_interleave 1 + #define core_config_bcr_dccm_build_size1 0 + #define core_config_bcr_dccm_build_size0 9 + #define core_config_bcr_dccm_build_version 4 + #define core_config_bcr_timer_build 0x00010304 + #define core_config_bcr_timer_build_sp1 0 + #define core_config_bcr_timer_build_sp0 0 + #define core_config_bcr_timer_build_p1 0 + #define core_config_bcr_timer_build_p0 1 + #define core_config_bcr_timer_build_st1 0 + #define core_config_bcr_timer_build_st0 0 + #define core_config_bcr_timer_build_rtc 0 + #define core_config_bcr_timer_build_rtsc_ver 1 + #define core_config_bcr_timer_build_rtsc 0 + #define core_config_bcr_timer_build_t0 1 + #define core_config_bcr_timer_build_t1 1 + #define core_config_bcr_timer_build_version 4 + #define core_config_bcr_ap_build 0x00000405 + #define core_config_bcr_ap_build_version 5 + #define core_config_bcr_ap_build_type 4 + #define core_config_bcr_iccm_build 0x00000a04 + #define core_config_bcr_iccm_build_iccm1_size1 0 + #define core_config_bcr_iccm_build_iccm0_size1 0 + #define core_config_bcr_iccm_build_iccm1_size0 0 + #define core_config_bcr_iccm_build_iccm0_size0 10 + #define core_config_bcr_iccm_build_version 4 + #define core_config_bcr_xy_build 0x00001620 + #define core_config_bcr_xy_build_memsize 1 + #define core_config_bcr_xy_build_interleaved 1 + #define core_config_bcr_xy_build_config 2 + #define core_config_bcr_xy_build_version 32 + #define core_config_bcr_dsp_build 0x00003521 + #define core_config_bcr_dsp_build_wide 0 + #define core_config_bcr_dsp_build_itu_pa 1 + #define core_config_bcr_dsp_build_acc_shift 2 + #define core_config_bcr_dsp_build_comp 1 + #define core_config_bcr_dsp_build_divsqrt 1 + #define core_config_bcr_dsp_build_version 33 + #define core_config_bcr_multiply_build 0x00022a06 + #define core_config_bcr_multiply_build_version16x16 2 + #define core_config_bcr_multiply_build_dsp 2 + #define core_config_bcr_multiply_build_cyc 2 + #define core_config_bcr_multiply_build_type 2 + #define core_config_bcr_multiply_build_version32x32 6 + #define core_config_bcr_swap_build 0x00000003 + #define core_config_bcr_swap_build_version 3 + #define core_config_bcr_norm_build 0x00000003 + #define core_config_bcr_norm_build_version 3 + #define core_config_bcr_minmax_build 0x00000002 + #define core_config_bcr_minmax_build_version 2 + #define core_config_bcr_barrel_build 0x00000303 + #define core_config_bcr_barrel_build_version 3 + #define core_config_bcr_barrel_build_shift_option 3 + #define core_config_bcr_isa_config 0x12447402 + #define core_config_bcr_isa_config_d 1 + #define core_config_bcr_isa_config_c 2 + #define core_config_bcr_isa_config_l 0 + #define core_config_bcr_isa_config_n 1 + #define core_config_bcr_isa_config_a 0 + #define core_config_bcr_isa_config_b 0 + #define core_config_bcr_isa_config_addr_size 4 + #define core_config_bcr_isa_config_lpc_size 7 + #define core_config_bcr_isa_config_pc_size 4 + #define core_config_bcr_isa_config_version 2 + #define core_config_bcr_stack_region_build 0x00000002 + #define core_config_bcr_fpu_build 0x00000f02 + #define core_config_bcr_fpu_build_da 0 + #define core_config_bcr_fpu_build_dd 0 + #define core_config_bcr_fpu_build_dc 0 + #define core_config_bcr_fpu_build_df 0 + #define core_config_bcr_fpu_build_dp 0 + #define core_config_bcr_fpu_build_fd 0 + #define core_config_bcr_fpu_build_fm 0 + #define core_config_bcr_fpu_build_sd 1 + #define core_config_bcr_fpu_build_sc 1 + #define core_config_bcr_fpu_build_sf 1 + #define core_config_bcr_fpu_build_sp 1 + #define core_config_bcr_fpu_build_version 2 + #define core_config_bcr_bs_build 0x00000001 + #define core_config_bcr_bs_build_version 1 + #define core_config_bcr_agu_build 0x01988c01 + #define core_config_bcr_agu_build_accordian 1 + #define core_config_bcr_agu_build_wb_size 4 + #define core_config_bcr_agu_build_num_modifier 24 + #define core_config_bcr_agu_build_num_offset 8 + #define core_config_bcr_agu_build_num_addr 12 + #define core_config_bcr_agu_build_version 1 + #define core_config_bcr_dmac_build 0x000a0101 + #define core_config_bcr_dmac_build_int_cfg 1 + #define core_config_bcr_dmac_build_fifo 1 + #define core_config_bcr_dmac_build_chan_mem 0 + #define core_config_bcr_dmac_build_channels 1 + #define core_config_bcr_dmac_build_version 1 + #define core_config_bcr_core_config 0x00000101 + #define core_config_bcr_core_config_turbo_boost 1 + #define core_config_bcr_core_config_version 1 + #define core_config_bcr_irq_build 0x13101401 + #define core_config_bcr_irq_build_raz 0 + #define core_config_bcr_irq_build_f 1 + #define core_config_bcr_irq_build_p 3 + #define core_config_bcr_irq_build_exts 16 + #define core_config_bcr_irq_build_irqs 20 + #define core_config_bcr_irq_build_version 1 + #define core_config_bcr_pct_build 0x08080102 + #define core_config_bcr_pct_build_version 2 + #define core_config_bcr_pct_build_s 1 + #define core_config_bcr_pct_build_i 0 + #define core_config_bcr_pct_build_c 8 + #define core_config_bcr_cc_build 0x006f0004 + #define core_config_bcr_cc_build_version 4 + #define core_config_bcr_cc_build_cc 111 + #define core_config_bcr_ifqueue_build 0x00000002 + #define core_config_bcr_ifqueue_build_bd 0 + #define core_config_bcr_ifqueue_build_version 2 + #define core_config_bcr_smart_build 0x00002003 + #define core_config_bcr_smart_build_version 3 + #define core_config_bcr_smart_build_stack_size 8 + #define core_config_cir_aux_iccm 0x00000000 + #define core_config_cir_dmp_peripheral 0xf0000000 + #define core_config_cir_xccm_base 0xc0000000 + #define core_config_cir_yccm_base 0xe0000000 + #define core_config_family 4 + #define core_config_core_version 2 + #define core_config_family_name "arcv2em" + #define core_config_rgf_num_banks 2 + #define core_config_rgf_banked_regs 32 + #define core_config_rgf_num_wr_ports 2 + #define core_config_endian "little" + #define core_config_endian_little 1 + #define core_config_endian_big 0 + #define core_config_lpc_size 32 + #define core_config_pc_size 32 + #define core_config_addr_size 32 + #define core_config_unaligned 1 + #define core_config_code_density 1 + #define core_config_div_rem "radix2" + #define core_config_div_rem_radix2 1 + #define core_config_turbo_boost 1 + #define core_config_swap 1 + #define core_config_bitscan 1 + #define core_config_mpy_option "mpyd" + #define core_config_mpy_option_num 8 + #define core_config_shift_assist 1 + #define core_config_barrel_shifter 1 + #define core_config_dsp 1 + #define core_config_dsp2 1 + #define core_config_dsp_complex 1 + #define core_config_dsp_divsqrt "radix2" + #define core_config_dsp_divsqrt_radix2 1 + #define core_config_dsp_itu 1 + #define core_config_dsp_accshift "full" + #define core_config_dsp_accshift_full 1 + #define core_config_agu_large 1 + #define core_config_agu_wb_depth 4 + #define core_config_agu_accord 1 + #define core_config_xy 1 + #define core_config_xy_config "dccm_x_y" + #define core_config_xy_config_dccm_x_y 1 + #define core_config_xy_size 8192 + #define core_config_xy_size_KM "8K" + #define core_config_xy_interleave 1 + #define core_config_xy_x_base 0xc0000000 + #define core_config_xy_y_base 0xe0000000 + #define core_config_bitstream 1 + #define core_config_fpus_div 1 + #define core_config_fpu_mac 1 + #define core_config_fpus_mpy_slow 1 + #define core_config_fpus_div_slow 1 + #define core_config_timer0 1 + #define core_config_timer0_level 1 + #define core_config_timer0_vector 16 + #define core_config_timer1 1 + #define core_config_timer1_level 0 + #define core_config_timer1_vector 17 + #define core_config_action_points 2 + #define core_config_stack_check 1 + #define core_config_smart_stack_entries 8 + #define core_config_ifq_present 1 + #define core_config_ifq_entries 1 + #define core_config_interrupts_present 1 + #define core_config_interrupts_number 20 + #define core_config_interrupts_priorities 4 + #define core_config_interrupts_externals 16 + #define core_config_interrupts 20 + #define core_config_interrupt_priorities 4 + #define core_config_ext_interrupts 16 + #define core_config_interrupts_firq 1 + #define core_config_interrupts_base 0x0 + #define core_config_dccm_present 1 + #define core_config_dccm_size 0x20000 + #define core_config_dccm_base 0x80000000 + #define core_config_dccm_interleave 1 + #define core_config_iccm_present 1 + #define core_config_iccm0_present 1 + #define core_config_iccm_size 0x40000 + #define core_config_iccm0_size 0x40000 + #define core_config_iccm_base 0x00000000 + #define core_config_iccm0_base 0x00000000 + #define core_config_pct_counters 8 + #define core_config_dmac 1 + #define core_config_dmac_channels 2 + #define core_config_dmac_registers 0 + #define core_config_dmac_fifo_depth 2 + #define core_config_dmac_int_config "single_internal" + #define core_config_clock_speed 20 +#endif /* __core_config_h */ + diff --git a/bsp/synopsys/emsk_em9d/drivers/board.c b/bsp/synopsys/emsk_em9d/drivers/board.c new file mode 100644 index 0000000000..449360f3a5 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/board.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include "board.h" +#include "inc/arc/arc_timer.h" +#include "inc/arc/arc_exception.h" + +#include "inc/embARC_error.h" +#include "mux.h" +#include "dw_uart_obj.h" + + +static void rt_hw_timer_isr(int vector, void *param) +{ + arc_timer_int_clear(BOARD_OS_TIMER_ID); + rt_tick_increase(); +} + +static void emsk_mux_init(void) +{ + MUX_REG *mux_regs; + + mux_regs = (MUX_REG *)(PERIPHERAL_BASE|REL_REGBASE_PINMUX); + mux_init(mux_regs); + + /** + * + Please refer to corresponding EMSK User Guide for detailed information + * -> Appendix: A Hardware Functional Description + * -> Pmods Configuration summary + * + Set up pin-multiplexer of all PMOD connections + * - PM1 J1: Upper row as UART 0, lower row as SPI Slave + * - PM2 J2: IIC 0 and run/halt signals + * - PM3 J3: GPIO Port A and Port C + * - PM4 J4: IIC 1 and Port D + * - PM5 J5: Upper row as SPI Master, lower row as Port A + * - PM6 J6: Upper row as SPI Master, lower row as Port A + */ + set_pmod_mux(mux_regs, PM1_UR_UART_0 | PM1_LR_SPI_S \ + | PM2_I2C_HRI \ + | PM3_GPIO_AC \ + | PM4_I2C_GPIO_D \ + | PM5_UR_SPI_M1 | PM5_LR_GPIO_A \ + | PM6_UR_SPI_M0 | PM6_LR_GPIO_A ); + + /** + * PM1 upper row as UART + * UM4:RXD, UM3:TXD + * UM2:RTS_N, UM1:CTS_N + */ + set_uart_map(mux_regs, 0xe4); +} + +static struct rt_serial_device _emsk_uart0; //abstracted serial for RTT +static struct rt_serial_device _emsk_uart1; + +static rt_err_t _configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + DEV_UART_PTR uart; + unsigned int id; + int ret; + + id = (unsigned int)(serial->parent.user_data); + + uart = uart_get_dev(id); + + ret = uart->uart_control(UART_CMD_SET_BAUD, (void *)(cfg->baud_rate)); + + if (ret != E_OK) { + return RT_ERROR; + } + + + return RT_EOK; +} + +static rt_err_t _control(struct rt_serial_device *serial, int cmd, void *arg) +{ + DEV_UART_PTR uart; + unsigned int id; + + id = (unsigned int)(serial->parent.user_data); + uart = uart_get_dev(id); + + switch (cmd) { + case RT_DEVICE_CTRL_CLR_INT: + uart->uart_control(UART_CMD_SET_RXINT, (void *)0); + break; + case RT_DEVICE_CTRL_SET_INT: + uart->uart_control(UART_CMD_SET_RXINT, (void *)1); + break; + case RT_DEVICE_CTRL_SUSPEND: + uart->uart_control(UART_CMD_DIS_DEV, (void *)0); + break; + case RT_DEVICE_CTRL_RESUME: + uart->uart_control(UART_CMD_ENA_DEV, (void *)0); + break; + + default: + return RT_ERROR; + break; + } + + return RT_EOK; +} + +static int _putc(struct rt_serial_device *serial, char c) +{ + DEV_UART_PTR uart; + unsigned int id; + int ret; + + id = (unsigned int)(serial->parent.user_data); + + uart = uart_get_dev(id); + + ret = uart->uart_write(&c, 1); + + if (ret < 0) { + return -1; + } else { + return 1; + } +} + +static int _getc(struct rt_serial_device *serial) +{ + DEV_UART_PTR uart; + unsigned int id; + unsigned int data; + int ret; + int rd_avail = 0; + + id = (unsigned int)(serial->parent.user_data); + uart = uart_get_dev(id); + + uart->uart_control(UART_CMD_GET_RXAVAIL, (void *)(&rd_avail)); + + if (rd_avail > 0) { + ret = uart->uart_read(&data, 1); + } else { + return -1; + } + + if (ret < 0) { + return -1; + } else { + return data; + } + +} + +static void _emsk_uart0_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&_emsk_uart0, RT_SERIAL_EVENT_RX_IND); +} + +static const struct rt_uart_ops _emsk_uart0_ops = +{ + _configure, + _control, + _putc, + _getc, +}; + +static void _emsk_uart1_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&_emsk_uart1, RT_SERIAL_EVENT_RX_IND); +} + +static const struct rt_uart_ops _emsk_uart1_ops = +{ + _configure, + _control, + _putc, + _getc, +}; + +int rt_hw_uart_init(void) +{ + DEV_UART_PTR uart; + struct serial_configure config; + int ret; + + config.baud_rate = BAUD_RATE_115200; + config.bit_order = BIT_ORDER_LSB; + config.data_bits = DATA_BITS_8; + config.parity = PARITY_NONE; + config.stop_bits = STOP_BITS_1; + config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; + + _emsk_uart0.ops = &_emsk_uart0_ops; + _emsk_uart0.config = config; + + _emsk_uart1.ops = &_emsk_uart1_ops; + _emsk_uart1.config = config; + + /* open UART1 for USB-UART interface */ + uart = uart_get_dev(DW_UART_1_ID); + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); + + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } + + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)1); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, _emsk_uart1_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&_emsk_uart1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)DW_UART_1_ID); + + /* open UART0 in PMOD A*/ + uart = uart_get_dev(DW_UART_0_ID); + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); + + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } + + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)1); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, _emsk_uart0_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&_emsk_uart0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)DW_UART_0_ID); + + return RT_EOK; +} + +void rt_hw_console_output(const char *str) +{ + while(*str != '\0') + { + if (*str == '\n') { + _putc(&_emsk_uart1,'\r'); + } + _putc(&_emsk_uart1,*str); + str++; + } +} + +int rt_hw_timer_init(void) +{ + + unsigned int cyc = BOARD_CPU_CLOCK / RT_TICK_PER_SECOND; + + int_disable(BOARD_OS_TIMER_INTNO); /* disable os timer interrupt */ + arc_timer_stop(BOARD_OS_TIMER_ID); + arc_timer_start(BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cyc); + + int_handler_install(BOARD_OS_TIMER_INTNO, (INT_HANDLER)rt_hw_timer_isr); + int_enable(BOARD_OS_TIMER_INTNO); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_timer_init); + +void rt_hw_board_init() +{ + emsk_mux_init(); + + rt_hw_uart_init(); + rt_components_board_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +} diff --git a/bsp/synopsys/emsk_em9d/drivers/board.h b/bsp/synopsys/emsk_em9d/drivers/board.h new file mode 100644 index 0000000000..aebf88bd42 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/board.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "emsk_hardware.h" + +#define BOARD_OS_TIMER_ID 0 +#define BOARD_OS_TIMER_INTNO 16 +#define BOARD_CPU_CLOCK 25000000 + +#if defined(__GNUC__) +extern int __start_heap; +#define HEAP_BEGIN ((void*)&__start_heap) +#endif + +extern int __end_heap; +#define HEAP_END (void*)(&__end_heap) + +void rt_hw_board_init(); + +int rt_hw_uart_init(void); + +#endif diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c new file mode 100644 index 0000000000..8701a0e9c7 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "inc/arc/arc.h" +#include "inc/arc/arc_builtin.h" + +#include "dw_gpio_obj.h" + +#include "emsk_hardware.h" +/* + * Uncomment this to enable default + * gpio bit handler output message + * by uart + */ + +#ifdef ARC_FEATURE_DMP_PERIPHERAL +#define PERIPHERAL_BASE ARC_FEATURE_DMP_PERIPHERAL +#else +#define PERIPHERAL_BASE _arc_aux_read(AUX_DMP_PERIPHERAL) +#endif + +#if (USE_DW_GPIO_PORT_A) +static DEV_GPIO port_a; +static DW_GPIO_PORT dw_gpio_port_a; +static DEV_GPIO_HANDLER dw_gpio_bit_handler_a[EMSK_GPIO_A_INT_MAX_COUNT]; +static DW_GPIO_BIT_ISR dw_gpio_bit_isr_a = { + EMSK_GPIO_A_INT_MAX_COUNT, dw_gpio_bit_handler_a +}; + +static int32_t porta_open(uint32_t dir) +{ + return dw_gpio_open(&port_a, dir); +} + +static int32_t porta_close(void) +{ + return dw_gpio_close(&port_a); +} + +static int32_t porta_control(uint32_t ctrl_cmd, void *param) +{ + return dw_gpio_control(&port_a, ctrl_cmd, param); +} + +static int32_t porta_write(uint32_t val, uint32_t mask) +{ + return dw_gpio_write(&port_a, val, mask); +} + +static int32_t porta_read(uint32_t *val, uint32_t mask) +{ + return dw_gpio_read(&port_a, val, mask); +} + +static void porta_isr(void *ptr) +{ + dw_gpio_isr_handler(&port_a, ptr); +} + +static void porta_install(void) +{ + uint32_t i; + DEV_GPIO_PTR port_ptr = &port_a; + DEV_GPIO_INFO_PTR info_ptr = &(port_a.gpio_info); + DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_a); + + info_ptr->gpio_ctrl = (void *)dw_port_ptr; + info_ptr->opn_cnt = 0; + info_ptr->method = 0; + info_ptr->direction = 0; + info_ptr->extra = 0; + + dw_port_ptr->no = DW_GPIO_PORT_A; + dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); + dw_port_ptr->valid_bit_mask = EMSK_GPIO_A_VALID_MASK; + dw_port_ptr->intno = INTNO_GPIO; + dw_port_ptr->int_handler = porta_isr; + + for (i=0; igpio_bit_isr = &dw_gpio_bit_isr_a; + + port_ptr->gpio_open = porta_open; + port_ptr->gpio_close = porta_close; + port_ptr->gpio_control = porta_control; + port_ptr->gpio_write = porta_write; + port_ptr->gpio_read = porta_read; +} +#endif + +#if (USE_DW_GPIO_PORT_B) +static DEV_GPIO port_b; +static DW_GPIO_PORT dw_gpio_port_b; + +static int32_t portb_open(uint32_t dir) +{ + return dw_gpio_open(&port_b, dir); +} + +static int32_t portb_close(void) +{ + return dw_gpio_close(&port_b); +} + +static int32_t portb_control(uint32_t ctrl_cmd, void *param) +{ + return dw_gpio_control(&port_b, ctrl_cmd, param); +} + +static int32_t portb_write(uint32_t val, uint32_t mask) +{ + return dw_gpio_write(&port_b, val, mask); +} + +static int32_t portb_read(uint32_t *val, uint32_t mask) +{ + return dw_gpio_read(&port_b, val, mask); +} + +static void portb_isr(void *ptr) +{ + dw_gpio_isr_handler(&port_b, ptr); +} + +static void portb_install(void) +{ + DEV_GPIO_PTR port_ptr = &port_b; + DEV_GPIO_INFO_PTR info_ptr = &(port_b.gpio_info); + DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_b); + + info_ptr->gpio_ctrl = (void *)dw_port_ptr; + info_ptr->opn_cnt = 0; + info_ptr->method = 0; + info_ptr->direction = 0; + info_ptr->extra = 0; + + dw_port_ptr->no = DW_GPIO_PORT_B; + dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); + dw_port_ptr->valid_bit_mask = EMSK_GPIO_B_VALID_MASK; + + dw_port_ptr->intno = INTNO_GPIO; + dw_port_ptr->int_handler = portb_isr; + dw_port_ptr->gpio_bit_isr = NULL; + + port_ptr->gpio_open = portb_open; + port_ptr->gpio_close = portb_close; + port_ptr->gpio_control = portb_control; + port_ptr->gpio_write = portb_write; + port_ptr->gpio_read = portb_read; +} +#endif + + +#if (USE_DW_GPIO_PORT_C) +static DEV_GPIO port_c; +static DW_GPIO_PORT dw_gpio_port_c; + +static int32_t portc_open(uint32_t dir) +{ + return dw_gpio_open(&port_c, dir); +} + +static int32_t portc_close(void) +{ + return dw_gpio_close(&port_c); +} + +static int32_t portc_control(uint32_t ctrl_cmd, void *param) +{ + return dw_gpio_control(&port_c, ctrl_cmd, param); +} + +static int32_t portc_write(uint32_t val, uint32_t mask) +{ + return dw_gpio_write(&port_c, val, mask); +} + +static int32_t portc_read(uint32_t *val, uint32_t mask) +{ + return dw_gpio_read(&port_c, val, mask); +} + +static void portc_isr(void *ptr) +{ + dw_gpio_isr_handler(&port_c, ptr); +} + +static void portc_install(void) +{ + DEV_GPIO_PTR port_ptr = &port_c; + DEV_GPIO_INFO_PTR info_ptr = &(port_c.gpio_info); + DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_c); + + info_ptr->gpio_ctrl = (void *)dw_port_ptr; + info_ptr->opn_cnt = 0; + info_ptr->method = 0; + info_ptr->direction = 0; + info_ptr->extra = 0; + + dw_port_ptr->no = DW_GPIO_PORT_C; + dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); + dw_port_ptr->valid_bit_mask = EMSK_GPIO_C_VALID_MASK; + + dw_port_ptr->intno = INTNO_GPIO; + dw_port_ptr->int_handler = portc_isr; + dw_port_ptr->gpio_bit_isr = NULL; + + port_ptr->gpio_open = portc_open; + port_ptr->gpio_close = portc_close; + port_ptr->gpio_control = portc_control; + port_ptr->gpio_write = portc_write; + port_ptr->gpio_read = portc_read; +} +#endif + +#if (USE_DW_GPIO_PORT_D) +static DEV_GPIO port_d; +static DW_GPIO_PORT dw_gpio_port_d; + +static int32_t portd_open(uint32_t dir) +{ + return dw_gpio_open(&port_d, dir); +} + +static int32_t portd_close(void) +{ + return dw_gpio_close(&port_d); +} + +static int32_t portd_control(uint32_t ctrl_cmd, void *param) +{ + return dw_gpio_control(&port_d, ctrl_cmd, param); +} + +static int32_t portd_write(uint32_t val, uint32_t mask) +{ + return dw_gpio_write(&port_d, val, mask); +} + +static int32_t portd_read(uint32_t *val, uint32_t mask) +{ + return dw_gpio_read(&port_d, val, mask); +} + +static void portd_isr(void *ptr) +{ + dw_gpio_isr_handler(&port_d, ptr); +} + +static void portd_install(void) +{ + DEV_GPIO_PTR port_ptr = &port_d; + DEV_GPIO_INFO_PTR info_ptr = &(port_d.gpio_info); + DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_d); + + info_ptr->gpio_ctrl = (void *)dw_port_ptr; + info_ptr->opn_cnt = 0; + info_ptr->method = 0; + info_ptr->direction = 0; + info_ptr->extra = 0; + + dw_port_ptr->no = DW_GPIO_PORT_D; + dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); + dw_port_ptr->valid_bit_mask = EMSK_GPIO_D_VALID_MASK; + + dw_port_ptr->intno = INTNO_GPIO; + dw_port_ptr->int_handler = portd_isr; + dw_port_ptr->gpio_bit_isr = NULL; + + port_ptr->gpio_open = portd_open; + port_ptr->gpio_close = portd_close; + port_ptr->gpio_control = portd_control; + port_ptr->gpio_write = portd_write; + port_ptr->gpio_read = portd_read; +} +#endif + +DEV_GPIO_PTR gpio_get_dev(int32_t gpio_id) +{ + static uint32_t install_flag = 0; + + /* intall device objects */ + if (install_flag == 0) { + install_flag = 1; + dw_gpio_all_install(); + } + + switch (gpio_id) { +#if (USE_DW_GPIO_PORT_A) + case DW_GPIO_PORT_A: return &port_a; +#endif +#if (USE_DW_GPIO_PORT_B) + case DW_GPIO_PORT_B: return &port_b; +#endif +#if (USE_DW_GPIO_PORT_C) + case DW_GPIO_PORT_C: return &port_c; +#endif +#if (USE_DW_GPIO_PORT_D) + case DW_GPIO_PORT_D: return &port_d; +#endif + default: + break; + } + return NULL; +} + +void dw_gpio_all_install(void) +{ +#if (USE_DW_GPIO_PORT_A) + porta_install(); +#endif +#if (USE_DW_GPIO_PORT_B) + portb_install(); +#endif +#if (USE_DW_GPIO_PORT_C) + portc_install(); +#endif +#if (USE_DW_GPIO_PORT_D) + portd_install(); +#endif +} diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h new file mode 100644 index 0000000000..d39a09159d --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _DW_GPIO_OBJ_H_ +#define _DW_GPIO_OBJ_H_ + +#include "device/designware/gpio/dw_gpio.h" + +/** + * \name Designware GPIO Port Bank Control Macros + * @{ + */ +#define USE_DW_GPIO_PORT_A 1 +#define USE_DW_GPIO_PORT_B 1 +#define USE_DW_GPIO_PORT_C 1 +#define USE_DW_GPIO_PORT_D 1 +/** @} end of name */ + +/** + * \name Designware GPIO Port Interrupt Available Number Macros + * @{ + */ +#define EMSK_GPIO_A_INT_MAX_COUNT 32 +#define EMSK_GPIO_B_INT_MAX_COUNT 0 +#define EMSK_GPIO_C_INT_MAX_COUNT 0 +#define EMSK_GPIO_D_INT_MAX_COUNT 0 +/** @} end of name */ + +/** + * \name Designware GPIO Port Available Bits Macros + * @{ + */ +#define EMSK_GPIO_A_VALID_MASK DW_GPIO_MASK_ALL +#define EMSK_GPIO_B_VALID_MASK DW_GPIO_MASK_ALL +#define EMSK_GPIO_C_VALID_MASK DW_GPIO_MASK_ALL +#define EMSK_GPIO_D_VALID_MASK DW_GPIO_MASK_ALL +/** @} end of name */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void dw_gpio_all_install(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DW_GPIO_OBJ_H_*/ diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c new file mode 100644 index 0000000000..9e3ebd3db9 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "inc/arc/arc.h" +#include "inc/arc/arc_builtin.h" +#include "inc/embARC_toolchain.h" +#include "inc/embARC_error.h" + +#include "inc/arc/arc_exception.h" +#include "device/designware/uart/dw_uart.h" +#include "dw_uart_obj.h" + +#include "emsk_hardware.h" + +#define DW_UART_FIFO_LEN 32 + +/** + * \name EMSK DesignWare UART 0 Object Instantiation + * @{ + */ +#if (USE_DW_UART_0) +static void dw_uart_0_isr(void *ptr); +#define DW_UART_0_RELBASE (REL_REGBASE_UART0) /*!< designware uart 0 relative baseaddr */ +#define DW_UART_0_INTNO (INTNO_UART0) /*!< designware uart 0 interrupt number */ + +DEV_UART dw_uart_0; /*!< designware uart object */ +DW_UART_CTRL dw_uart_0_ctrl = { /*!< designware uart 0 ctrl */ + 0, CLK_BUS_APB, DW_UART_0_INTNO, (INT_HANDLER)dw_uart_0_isr, + DW_UART_FIFO_LEN, DW_UART_FIFO_LEN, 0 +}; + +/** designware uart 0 open */ +static int32_t dw_uart_0_open (uint32_t baud) +{ + return dw_uart_open(&dw_uart_0, baud); +} +/** designware uart 0 close */ +static int32_t dw_uart_0_close (void) +{ + return dw_uart_close(&dw_uart_0); +} +/** designware uart 0 control */ +static int32_t dw_uart_0_control (uint32_t ctrl_cmd, void *param) +{ + return dw_uart_control(&dw_uart_0, ctrl_cmd, param); +} +/** designware uart 0 write */ +static int32_t dw_uart_0_write (const void *data, uint32_t len) +{ + return dw_uart_write(&dw_uart_0, data, len); +} +/** designware uart 0 close */ +static int32_t dw_uart_0_read (void *data, uint32_t len) +{ + return dw_uart_read(&dw_uart_0, data, len); +} +/** designware uart 0 interrupt rountine */ +static void dw_uart_0_isr(void *ptr) +{ + dw_uart_isr(&dw_uart_0, ptr); +} +/** install designware uart 0 to system */ +static void dw_uart_0_install(void) +{ + uint32_t uart_abs_base = 0; + DEV_UART *dw_uart_ptr = &dw_uart_0; + DEV_UART_INFO *dw_uart_info_ptr = &(dw_uart_0.uart_info); + DW_UART_CTRL *dw_uart_ctrl_ptr = &dw_uart_0_ctrl; + + /** + * get absolute designware base address + */ + uart_abs_base = (uint32_t)PERIPHERAL_BASE + DW_UART_0_RELBASE; + dw_uart_ctrl_ptr->dw_uart_regbase = uart_abs_base; + + /** uart info init */ + dw_uart_info_ptr->uart_ctrl = (void *)dw_uart_ctrl_ptr; + dw_uart_info_ptr->opn_cnt = 0; + dw_uart_info_ptr->status = 0; + dw_uart_info_ptr->baudrate = UART_BAUDRATE_115200; /* default 115200bps */ + + /** uart dev init */ + dw_uart_ptr->uart_open = dw_uart_0_open; + dw_uart_ptr->uart_close = dw_uart_0_close; + dw_uart_ptr->uart_control = dw_uart_0_control; + dw_uart_ptr->uart_write = dw_uart_0_write; + dw_uart_ptr->uart_read = dw_uart_0_read; + +} +#endif /* USE_DW_UART_0 */ +/** @} end of name */ + +/** + * \name EMSK DesignWare UART 1 Object Instantiation + * @{ + */ +#if (USE_DW_UART_1) +static void dw_uart_1_isr(void *ptr); +#define DW_UART_1_RELBASE (REL_REGBASE_UART1) /*!< designware uart 1 relative baseaddr */ +#define DW_UART_1_INTNO (INTNO_UART1) /*!< designware uart 1 interrupt number */ + +DEV_UART dw_uart_1; /*!< designware uart 1 object */ +DW_UART_CTRL dw_uart_1_ctrl = { /*!< designware uart 1 ctrl */ + 0, CLK_BUS_APB, DW_UART_1_INTNO, (INT_HANDLER)dw_uart_1_isr, + DW_UART_FIFO_LEN, DW_UART_FIFO_LEN, 0 +}; + +/** designware uart 1 open */ +static int32_t dw_uart_1_open (uint32_t baud) +{ + return dw_uart_open(&dw_uart_1, baud); +} +/** designware uart 1 close */ +static int32_t dw_uart_1_close (void) +{ + return dw_uart_close(&dw_uart_1); +} +/** designware uart 1 control */ +static int32_t dw_uart_1_control (uint32_t ctrl_cmd, void *param) +{ + return dw_uart_control(&dw_uart_1, ctrl_cmd, param); +} +/** designware uart 1 write */ +static int32_t dw_uart_1_write (const void *data, uint32_t len) +{ + return dw_uart_write(&dw_uart_1, data, len); +} +/** designware uart 1 close */ +static int32_t dw_uart_1_read (void *data, uint32_t len) +{ + return dw_uart_read(&dw_uart_1, data, len); +} +/** designware uart 1 interrupt routine */ +static void dw_uart_1_isr(void *ptr) +{ + dw_uart_isr(&dw_uart_1, ptr); +} +/** install designware uart 1 to system */ +static void dw_uart_1_install(void) +{ + uint32_t uart_abs_base = 0; + DEV_UART *dw_uart_ptr = &dw_uart_1; + DEV_UART_INFO *dw_uart_info_ptr = &(dw_uart_1.uart_info); + DW_UART_CTRL *dw_uart_ctrl_ptr = &dw_uart_1_ctrl; + + /** + * get absolute designware base address + */ + uart_abs_base = (uint32_t)PERIPHERAL_BASE + DW_UART_1_RELBASE; + dw_uart_ctrl_ptr->dw_uart_regbase = uart_abs_base; + + /** uart info init */ + dw_uart_info_ptr->uart_ctrl = (void *)dw_uart_ctrl_ptr; + dw_uart_info_ptr->opn_cnt = 0; + dw_uart_info_ptr->status = 0; + dw_uart_info_ptr->baudrate = UART_BAUDRATE_115200; /* default 115200bps */ + + /** uart dev init */ + dw_uart_ptr->uart_open = dw_uart_1_open; + dw_uart_ptr->uart_close = dw_uart_1_close; + dw_uart_ptr->uart_control = dw_uart_1_control; + dw_uart_ptr->uart_write = dw_uart_1_write; + dw_uart_ptr->uart_read = dw_uart_1_read; +} +#endif /* USE_DW_UART_1 */ +/** @} end of name */ + +/** get one designware device structure */ +DEV_UART_PTR uart_get_dev(int32_t uart_id) +{ + static uint32_t install_flag = 0; + + /* intall device objects */ + if (install_flag == 0) { + install_flag = 1; + dw_uart_all_install(); + } + + switch (uart_id) { +#if (USE_DW_UART_0) + case DW_UART_0_ID: + return &dw_uart_0; + break; +#endif +#if (USE_DW_UART_1) + case DW_UART_1_ID: + return &dw_uart_1; + break; +#endif + default: + break; + } + return NULL; +} + +/** + * \brief install all uart objects + * \note \b MUST be called during system init + */ +void dw_uart_all_install(void) +{ +#if (USE_DW_UART_0) + dw_uart_0_install(); +#endif +#if (USE_DW_UART_1) + dw_uart_1_install(); +#endif +} diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h new file mode 100644 index 0000000000..7a63880fab --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _DW_UART_OBJ_H_ +#define _DW_UART_OBJ_H_ + +#include "device/device_hal/inc/dev_uart.h" + +/** + * \name DesignWare UART Object Number + * @{ + */ +#define DW_UART_NUM (2) /*!< DesignWare UART valid number */ +/** @} end of name */ + +/** + * \name Designware UART Object ID Macros + * @{ + */ +#define DW_UART_0_ID 0 /*!< uart 0 id macro */ +#define DW_UART_1_ID 1 /*!< uart 1 id macro */ +/** @} end of name */ + +/** + * \name Designware UART Object Control Macros + * @{ + */ +#define USE_DW_UART_0 1 /*!< enable use designware uart 0 */ +#define USE_DW_UART_1 1 /*!< enable use designware uart 1 */ +/** @} end of name */ + +/** + * \name Designware UART Ringbuffer Size Control Macros + * @{ + */ +#define MAX_SNDBUF_SIZE 256 /*!< max size of uart send buffer */ +#define MAX_RCVBUF_SIZE 10 /*!< max size of uart recv buffer */ +/** @} end of name */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void dw_uart_all_install(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DW_UART_OBJ_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h b/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h new file mode 100644 index 0000000000..706aac94c4 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _EMBARC_BSP_CONFIG_H_ +#define _EMBARC_BSP_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOARD_EMSK +/**************************************************************************** + * BSP Definitions + ****************************************************************************/ +/** + * Toolchain Definition for MetaWare or GNU + */ +//#define __MW__ +#define __GNU__ + +/** + * Must be set. + * If changed, modify .lcf file for + * .stack ALIGN(4) SIZE(524288): {} + * .heap? ALIGN(4) SIZE(524288): {} + */ +#define _STACKSIZE (4 * 1024) +#define _HEAPSZ (32 * 1024) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _EMBARC_CONFIG_BSP_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h b/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h new file mode 100644 index 0000000000..d60e314389 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _EMSK_HARDWARE_H_ +#define _EMSK_HARDWARE_H_ + +#include "inc/arc/arc_feature_config.h" + +/** CPU Clock Frequency definition */ +#if defined(BOARD_CPU_FREQ) + /*!< Get cpu clock frequency definition from build system */ + #define CLK_CPU (BOARD_CPU_FREQ) +#elif defined(ARC_FEATURE_CPU_CLOCK_FREQ) + /*!< Get cpu clock frequency definition from tcf file */ + #define CLK_CPU (ARC_FEATURE_CPU_CLOCK_FREQ) +#else + /*!< Default cpu clock frequency */ + #define CLK_CPU (20000000) +#endif + +/** Peripheral Bus Reference Clock definition */ +#ifdef BOARD_DEV_FREQ + /*!< Get peripheral bus reference clock defintion from build system */ + #define CLK_BUS_APB (BOARD_DEV_FREQ) +#else + /*!< Default peripheral bus reference clock defintion */ + #define CLK_BUS_APB (50000000U) +#endif + +#ifdef ARC_FEATURE_DMP_PERIPHERAL +#define PERIPHERAL_BASE ARC_FEATURE_DMP_PERIPHERAL +#else +#define PERIPHERAL_BASE _arc_aux_read(AUX_DMP_PERIPHERAL) +#endif + +/* Device Register Base Address */ +#define REL_REGBASE_PINMUX (0x00000000U) /*!< PINMUX */ +#define REL_REGBASE_SPI_MST_CS_CTRL (0x00000014U) /*!< SPI Master Select Ctrl */ +#define REL_REGBASE_GPIO0 (0x00002000U) /*!< GPIO 0 Onboard */ +#define REL_REGBASE_TIMERS (0x00003000U) /*!< DW TIMER */ +#define REL_REGBASE_I2C0 (0x00004000U) /*!< I2C 0 */ +#define REL_REGBASE_I2C1 (0x00005000U) /*!< I2C 1 */ +#define REL_REGBASE_SPI0 (0x00006000U) /*!< SPI Master */ +#define REL_REGBASE_SPI1 (0x00007000U) /*!< SPI Slave */ +#define REL_REGBASE_UART0 (0x00008000U) /*!< UART0 is connected to PMOD */ +#define REL_REGBASE_UART1 (0x00009000U) /*!< UART1 is USB-UART£¬ use UART1 as default */ +#define REL_REGBASE_UART2 (0x0000A000U) /*!< UART2 */ +#define REL_REGBASE_WDT (0x0000B000U) /*!< WDT */ +// #define REL_REGBASE_I2S_MASTER_IN (0x0000C000U) /*!< I2S Master In */ +// #define REL_REGBASE_I2S_MASTER_OUT (0x0000D000U) /*!< I2S Master Out */ +// #define REL_REGBASE_GMAC (0x0000E000U) /*!< GMAC */ + +/* Interrupt Connection */ +#define INTNO_TIMER0 16 /*!< ARC Timer0 */ +#define INTNO_TIMER1 17 /*!< ARC Timer1 */ +#define INTNO_SECURE_TIMER0 20 /*!< Core Secure Timer 0 */ +#define INTNO_DMA_START 22 /*!< Core DMA Controller */ +#define INTNO_DMA_COMPLETE 22 /*!< Core DMA Controller Complete */ +#define INTNO_DMA_ERROR 23 /*!< Core DMA Controller Error */ +#define INTNO_GPIO 24 /*!< GPIO controller */ +#define INTNO_I2C0 25 /*!< I2C_0 controller */ +#define INTNO_I2C1 26 /*!< I2C_1 controller */ +#define INTNO_SPI_MASTER 27 /*!< SPI Master controller */ +#define INTNO_SPI_SLAVE 28 /*!< SPI Slave controller */ +#define INTNO_UART0 29 /*!< UART0 */ +#define INTNO_UART1 30 /*!< UART1 */ +#define INTNO_UART2 31 /*!< UART2 */ +#define INTNO_DW_WDT 32 /*!< WDT */ +#define INTNO_DW_TMR0 33 /*!< DW Timer 0 */ +#define INTNO_DW_TMR1 34 /*!< DW Timer 1 */ +// #define INTNO_I2S_Master_In 33 /*!< I2S Master In */ +// #define INTNO_I2S_Master_Out 34 /*!< I2S Master Out */ +// #define INTNO_GMAC 35 /*!< GMAC */ + +/* SPI Mater Signals Usage */ +#define EMSK_SPI_LINE_0 0 /*!< CS0 -- Pmod 6 pin1 */ +#define EMSK_SPI_LINE_1 1 /*!< CS1 -- Pmod 5 pin1 or Pmod 6 pin 7 */ +#define EMSK_SPI_LINE_2 2 /*!< CS2 -- Pmod 6 pin8 */ +#define EMSK_SPI_LINE_SDCARD 3 /*!< CS3 -- On-board SD card */ +#define EMSK_SPI_LINE_SPISLAVE 4 /*!< CS4 -- Internal SPI slave */ +#define EMSK_SPI_LINE_SFLASH 5 /*!< CS5 -- On-board SPI Flash memory */ + +#endif /* _EMSK_HARDWARE_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/mux.c b/bsp/synopsys/emsk_em9d/drivers/mux.c new file mode 100644 index 0000000000..a56cb15212 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/mux.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "mux_hal.h" +#include "mux.h" + +static MUX_REG *mux_ctrl_regs = (MUX_REG *)0; + +/** initialize i2c controller and set slave device address */ +void mux_init(MUX_REG *mux_regs) +{ + // Initialize Mux controller registers by default values + mux_regs[PMOD_MUX_CTRL] = PMOD_MUX_CTRL_DEFAULT; + mux_regs[SPI_MAP_CTRL] = SPI_MAP_CTRL_DEFAULT; + mux_regs[UART_MAP_CTRL] = UART_MAP_CTRL_DEFAULT; + mux_ctrl_regs = mux_regs; +} + +/** Get mux ctrl register pointer, only valid after mux_init */ +MUX_REG *get_mux_regs(void) +{ + return mux_ctrl_regs; +} + +/** set PMOD muxer scheme */ +void set_pmod_mux(MUX_REG *mux_regs, uint32_t val) +{ + mux_regs[PMOD_MUX_CTRL] = val; +} + +/** get PMOD muxer scheme */ +uint32_t get_pmod_mux(MUX_REG *mux_regs) +{ + return (uint32_t) mux_regs[PMOD_MUX_CTRL]; +} + +/** set PMOD muxer scheme */ +void change_pmod_mux(MUX_REG *mux_regs, uint32_t val, uint32_t change_bits) +{ + mux_regs[PMOD_MUX_CTRL] = ((mux_regs[PMOD_MUX_CTRL] & ~change_bits) | val); +} + +/** set SPI connection scheme */ +void set_spi_map(MUX_REG *mux_regs, uint32_t val) +{ + mux_regs[SPI_MAP_CTRL] = val; +} + +/** get SPI connection scheme */ +uint32_t get_spi_map(MUX_REG *mux_regs) +{ + return (uint32_t) mux_regs[SPI_MAP_CTRL]; +} + +/** set UART connection scheme */ +void set_uart_map(MUX_REG *mux_regs, uint32_t val) +{ + mux_regs[UART_MAP_CTRL] = val; +} + +/** get UART connection scheme */ +uint32_t get_uart_map(MUX_REG *mux_regs) +{ + return (uint32_t) mux_regs[UART_MAP_CTRL]; +} diff --git a/bsp/synopsys/emsk_em9d/drivers/mux.h b/bsp/synopsys/emsk_em9d/drivers/mux.h new file mode 100644 index 0000000000..47f796bebe --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/mux.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _MUX_H_ +#define _MUX_H_ + +#include "inc/embARC_toolchain.h" + +#define BIT0 (0) +#define BIT1 (1) +#define BIT2 (2) +#define BIT3 (3) +#define PM1_OFFSET (0) +#define PM2_OFFSET (4) +#define PM3_OFFSET (8) +#define PM4_OFFSET (12) +#define PM5_OFFSET (16) +#define PM6_OFFSET (20) +#define PM7_OFFSET (24) + +#define PM1_MASK (0xf << PM1_OFFSET) +#define PM2_MASK (0xf << PM2_OFFSET) +#define PM3_MASK (0xf << PM3_OFFSET) +#define PM4_MASK (0xf << PM4_OFFSET) +#define PM5_MASK (0xf << PM5_OFFSET) +#define PM6_MASK (0xf << PM6_OFFSET) +#define PM7_MASK (0xf << PM7_OFFSET) + + +#define SPI_MAP_NORMAL (0) +#define SPI_MAP_LOOPBACK (1) + +#define UART_MAP_TYPE4 (0xE4) +#define UART_MAP_TYPE3 (0x6C) + +/** + * \name Default pin muxer settings + * @{ + */ +#define PMOD_MUX_CTRL_DEFAULT (0) /*!< all pins are configured as GPIO inputs */ +#define SPI_MAP_CTRL_DEFAULT (SPI_MAP_NORMAL) /*!< normal SPI mode */ +#define UART_MAP_CTRL_DEFAULT (UART_MAP_TYPE4) /*!< TYPE4 PMOD compatible */ +/** @} end of name */ + +/** + * \name PMOD 1 Multiplexor + * @{ + */ +#define PM1_UR_GPIO_C ((0 << BIT0) << PM1_OFFSET) /*!< Pmod1[4:1] are connected to DW GPIO Port C[11:8] */ +#define PM1_UR_UART_0 ((1 << BIT0) << PM1_OFFSET) /*!< Pmod1[4:1] are connected to DW UART0 signals */ + +#define PM1_LR_GPIO_A ((0 << BIT2) << PM1_OFFSET) /*!< Pmod1[10:7] are connected to DW GPIO Port A[11:8] */ +#define PM1_LR_SPI_S ((1 << BIT2) << PM1_OFFSET) /*!< Pmod1[10:7] are connected to DW SPI Slave signals */ +/** @} end of name */ + + +/** + * \name PMOD 2 Multiplexor + * @{ + */ +#define PM2_GPIO_AC ((0 << BIT0) << PM2_OFFSET) /*!< Pmod2[4:1] are connected to DW GPIO Port C[15:12], + Pmod2[10:7] are connected to DW GPIO Port A[15:12] */ + +#define PM2_I2C_HRI ((1 << BIT0) << PM2_OFFSET) /*!< connect I2C to Pmod2[4:1] and halt/run interface to Pmod2[10:7] */ +/** @} end of name */ + + +/** + * \name PMOD 3 Multiplexor + * @{ + */ +#define PM3_GPIO_AC ((0 << BIT0) << PM3_OFFSET) /*!< Pmod3[4:1] are connected to DW GPIO Port C[19:16], + Pmod3[10:7] are connected to DW GPIO Port A[19:16] */ + +#define PM3_I2C_GPIO_D ((1 << BIT0) << PM3_OFFSET) /*!< Pmod3[4:3] are connected to DW I2C signals, + Pmod3[2:1] are connected to DW GPIO Port D[1:0], + Pmod3[10:7] are connected to DW GPIO Port D[3:2] */ +/** @} end of name */ + + +/** + * \name PMOD 4 Multiplexor + * @{ + */ +#define PM4_GPIO_AC ((0 << BIT0) << PM4_OFFSET) /*!< Pmod4[4:1] are connected to DW GPIO Port C[23:20], + Pmod4[10:7] are connected to DW GPIO Port A[23:20] */ + +#define PM4_I2C_GPIO_D ((1 << BIT0) << PM4_OFFSET) /*!< Pmod4[4:3] are connected to DW I2C signals, + Pmod4[2:1] are connected to DW GPIO Port D[5:4], + Pmod4[10:7] are connected to DW GPIO Port D[7:6] */ +/** @} end of name */ + +/** + * \name PMOD 5 Multiplexor + * @{ + */ +#define PM5_UR_GPIO_C ((0 << BIT0) << PM5_OFFSET) /*!< Pmod5[4:1] are connected to DW GPIO Port C[27:24] */ +#define PM5_UR_SPI_M1 ((1 << BIT0) << PM5_OFFSET) /*!< Pmod5[4:1] are connected to DW SPI Master signals using CS1_N */ + +#define PM5_LR_GPIO_A ((0 << BIT2) << PM5_OFFSET) /*!< Pmod5[10:7] are connected to DW GPIO Port A[27:24] */ +#define PM5_LR_SPI_M2 ((1 << BIT2) << PM5_OFFSET) /*!< Pmod5[10:7] are connected to DW SPI Master signals using CS2_N */ +/** @} end of name */ + + +/** + * \name PMOD 6 Multiplexor + * @{ + */ +#define PM6_UR_GPIO_C ((0 << BIT0) << PM6_OFFSET) /*!< Pmod6[4:1] are connected to DW GPIO Port C[31:28] */ +#define PM6_UR_SPI_M0 ((1 << BIT0) << PM6_OFFSET) /*!< Pmod6[4:1] are connected to DW SPI Master signals using CS0_N */ + +#define PM6_LR_GPIO_A ((0 << BIT2) << PM6_OFFSET) /*!< Pmod6[10:7] are connected to DW GPIO Port A[31:28] */ + +#define PM6_LR_CSS_STAT ((1 << BIT2) << PM6_OFFSET) /*!< Pmod6[8:7] are connected to the DW SPI Master chip select signals CS1_N and CS2_N, + Pmod6[6:5] are connected to the ARC EM halt and sleep status signals */ +/** @} end of name */ + +/** + * \name PMOD 7 Multiplexor + * @{ + */ +#define PM7_GPIO_D ((0 << BIT0) << PM7_OFFSET) /*!< Pmod7[4:1] are connected to DW GPIO Port D[11:8] */ +#define PM7_STAT ((1 << BIT0) << PM7_OFFSET) /*!< Pmod7[4:1] are connected to the ARC EM sleep status signals */ +/** @} end of name */ +typedef volatile uint32_t MUX_REG; + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mux_init(MUX_REG *mux_regs); +extern MUX_REG *get_mux_regs(void); +extern void set_pmod_mux(MUX_REG *mux_regs, uint32_t val); +extern uint32_t get_pmod_mux(MUX_REG *mux_regs); +extern void change_pmod_mux(MUX_REG *mux_regs, uint32_t val, uint32_t change_bits); +extern void set_spi_map(MUX_REG *mux_regs, uint32_t val); +extern uint32_t get_spi_map(MUX_REG *mux_regs); +extern void set_uart_map(MUX_REG *mux_regs, uint32_t val); +extern uint32_t get_uart_map(MUX_REG *mux_regs); + +#ifdef __cplusplus +} +#endif + +#endif /* _MUX_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/mux_hal.h b/bsp/synopsys/emsk_em9d/drivers/mux_hal.h new file mode 100644 index 0000000000..9a5c8c14b9 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/drivers/mux_hal.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _MUX_HAL_H_ +#define _MUX_HAL_H_ + +/** + * \name Mux Control Register Index + * @{ + */ +#define PMOD_MUX_CTRL 0 /*!< 32-bits, offset 0x0, + This register controls mapping of the peripheral device signals on Pmod connectors */ + +#define I2C_MAP_CTRL 1 /*!< 32-bits, offset 0x4 */ + +#define SPI_MAP_CTRL 2 /*!< 32-bits, offset 0x8, + SPI_MAP_CTRL[0] selects the mode of operation of the SPI Slave: + - Normal operation, SPI_MAP_CTRL[0]=0: SPI Slave is connected to Pmod1 at connector J1. + - Loop-back mode, SPI_MAP_CTRL[0]=1: SPI Slave is connected to the SPI Master inside the FPGA using CS4. + */ + +#define UART_MAP_CTRL 3 /*!< 32-bits, offset 0x8, + This register controls the mapping of the UART signals on the Pmod1 connector. */ +/** @} end of name */ + + +#endif /* _MUX_HAL_H_ */ diff --git a/bsp/synopsys/emsk_em9d/emsk_em9d.ld b/bsp/synopsys/emsk_em9d/emsk_em9d.ld new file mode 100644 index 0000000000..849ecf6329 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/emsk_em9d.ld @@ -0,0 +1,114 @@ +MEMORY +{ + ICCM : ORIGIN = 0x00000000, LENGTH = 0x40000 + DCCM : ORIGIN = 0x80000000, LENGTH = 0x20000 + EXT_RAM : ORIGIN = 0x10000000, LENGTH = 0x8000000 +} +ENTRY(_start) +SECTIONS +{ + .init : + { + _f_init = .; + KEEP (*(.init_vector)) + KEEP (*(.init_bootstrap)) + _e_init = .; + } > EXT_RAM + .vector : ALIGN(1024) + { + _f_vector = .; + *(.vector) + _e_vector = .; + } > EXT_RAM + .text : ALIGN(4) + { + _f_text = .; + *(.text .text.* .gnu.linkonce.t.*) + _e_text = .; + } > EXT_RAM + .rodata : ALIGN(4) + { + _f_rodata = .; + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + KEEP(*(SORT_BY_NAME(".ctors*"))) + LONG(0) + __CTOR_END__ = .; + . = ALIGN(4); + __init_array_start = .; + KEEP(*(SORT_BY_NAME(".init_array*"))) + __init_array_end = .; + . = ALIGN(4); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + KEEP(*(SORT_BY_NAME(".dtors*"))) + LONG(0) + __DTOR_END__ = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + _e_rodata = .; + } > EXT_RAM + .data : ALIGN(4) + { + _f_data = .; + *(.data .data.* .gnu.linkonce.d.*) + _f_sdata = .; + __SDATA_BEGIN__ = .; + *(.sdata .sdata.* .gnu.linkonce.s.*) + _e_sdata = .; + _e_data = .; + } > EXT_RAM + .bss (NOLOAD) : ALIGN(8) + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + _f_bss = .; + _f_sbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + _e_sbss = .; + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _e_bss = .; + } > EXT_RAM + .stack (NOLOAD) : + { + . = ALIGN(4); + _f_stack = .; + . = . + 4096; + _e_stack = .; + } > EXT_RAM + .heap (NOLOAD) : + { + . = ALIGN(4); + __start_heap = . ; + _f_heap = .; + . = . + 0x8000; + _e_heap = .; + __end_heap = . ; + } > EXT_RAM + _load_addr_text = LOADADDR(.text); + _load_addr_rodata = LOADADDR(.rodata); + _load_addr_data = LOADADDR(.data); +} diff --git a/bsp/synopsys/emsk_em9d/openocd.log b/bsp/synopsys/emsk_em9d/openocd.log new file mode 100644 index 0000000000..4ef893515e --- /dev/null +++ b/bsp/synopsys/emsk_em9d/openocd.log @@ -0,0 +1,9 @@ +Warn : deprecated option: -p/--pipe. Use '-c "gdb_port pipe; log_output openocd.log"' instead. +adapter speed: 5000 kHz +Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED +Info : clock speed 5000 kHz +Info : JTAG tap: arc-em.cpu tap/device found: 0x200044b1 (mfg: 0x258, part: 0x0004, ver: 0x2) +Info : JTAG tap: arc-em.cpu tap/device found: 0x200044b1 (mfg: 0x258, part: 0x0004, ver: 0x2) +target state: halted +Info : accepting 'gdb' connection from pipe +Info : dropped 'gdb' connection diff --git a/bsp/synopsys/emsk_em9d/rtconfig.h b/bsp/synopsys/emsk_em9d/rtconfig.h new file mode 100644 index 0000000000..865e753ae5 --- /dev/null +++ b/bsp/synopsys/emsk_em9d/rtconfig.h @@ -0,0 +1,142 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +// + +// +#define RT_NAME_MAX 6 +// +#define RT_ALIGN_SIZE 4 +// +// 8 +// 32 +// 256 +// +#define RT_THREAD_PRIORITY_MAX 32 +// +#define RT_TICK_PER_SECOND 1000 +// +#define IDLE_THREAD_STACK_SIZE 512 +//
+#define RT_DEBUG +// +// #define RT_THREAD_DEBUG +// +#define RT_USING_OVERFLOW_CHECK +//
+ +// +#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 RT_USING_SEMAPHORE +// +#define RT_USING_MUTEX +// +#define RT_USING_EVENT +// +#define RT_USING_MAILBOX +// +#define RT_USING_MESSAGEQUEUE +//
+ +//
+// +#define RT_USING_MEMPOOL +// +// #define RT_USING_MEMHEAP +// +#define RT_USING_HEAP +// +// #define RT_USING_MEMHEAP_AS_HEAP +// +#define RT_USING_SMALL_MEM +// +// #define RT_USING_SLAB +//
+ +//
+#define RT_USING_DEVICE +// +#define RT_USING_DEVICE_IPC +// +#define RT_USING_SERIAL +// +#define RT_UART_RX_BUFFER_SIZE 64 +// +#define RT_USING_INTERRUPT_INFO +//
+ +//
+#define RT_USING_CONSOLE +// +#define RT_CONSOLEBUF_SIZE 128 +// +#define RT_CONSOLE_DEVICE_NAME "uart1" +//
+ +// +#define RT_USING_COMPONENTS_INIT +//
+#define RT_USING_FINSH +// +#define FINSH_USING_MSH +// +#define FINSH_USING_MSH_DEFAULT +// +#define FINSH_USING_SYMTAB +// +#define FINSH_USING_DESCRIPTION +// +#define FINSH_THREAD_STACK_SIZE 4096 +//
+ +//
+// +// +#define RT_USING_PTHREADS +//
+ +//
+// #define RT_USING_DFS +// +// #define DFS_USING_WORKDIR +// +#define DFS_FILESYSTEMS_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.5:/" +//
+//
+ + +#endif diff --git a/bsp/synopsys/emsk_em9d/rtconfig.py b/bsp/synopsys/emsk_em9d/rtconfig.py new file mode 100644 index 0000000000..7ba12867fd --- /dev/null +++ b/bsp/synopsys/emsk_em9d/rtconfig.py @@ -0,0 +1,60 @@ +import os + +# toolchains options +ARCH='arc' +CPU='em' +CROSS_TOOL='gcc' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +# only support GNU GCC compiler +PLATFORM = 'gcc' +EXEC_PATH = 'C:/arc/gnu/bin' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arc-elf32-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + DBG = PREFIX + 'gdb' + DEVICE = ' -mno-sdata -Wall -mcpu=em4_fpus -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter -mfpu=fpus_all' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LINK_SCRIPT = 'emsk_em9d.ld' + LFLAGS = DEVICE + ' -mno-sdata -nostartfiles -Wl,--gc-sections,-Map=emsk_em9d.map,-cref,-u,system_vectors -T %s' % LINK_SCRIPT + + OPENOCD_SCRIPT_ROOT = 'C:/arc/gnu/share/openocd/scripts' + OPENOCD_CFG_FILE = OPENOCD_SCRIPT_ROOT + '/board/snps_em_sk_v2.2.cfg' + + OPENOCD_OPTIONS = '-s %s -f %s' % (OPENOCD_SCRIPT_ROOT, OPENOCD_CFG_FILE) + + DBG_HW_FLAGS = ''' -ex "target remote | openocd --pipe %s" -ex "load" ''' % OPENOCD_OPTIONS + + + TARGET = 'rtthread_snps_emsk_em9d.' + TARGET_EXT + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\ + SIZE + ' $TARGET \n' + #POST_ACTION = DBG + DBG_HW_FLAGS + TARGET diff --git a/libcpu/arc/SConscript b/libcpu/arc/SConscript new file mode 100644 index 0000000000..cbec0b5ec1 --- /dev/null +++ b/libcpu/arc/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/arc/common/SConscript b/libcpu/arc/common/SConscript new file mode 100644 index 0000000000..1c77347e61 --- /dev/null +++ b/libcpu/arc/common/SConscript @@ -0,0 +1,10 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + + +group = DefineGroup('cpu', src, depend = [], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arc/em/SConscript b/libcpu/arc/em/SConscript new file mode 100644 index 0000000000..49c32b689d --- /dev/null +++ b/libcpu/arc/em/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_gcc.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arc/em/contex_gcc.S b/libcpu/arc/em/contex_gcc.S new file mode 100644 index 0000000000..a8abe089bf --- /dev/null +++ b/libcpu/arc/em/contex_gcc.S @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define __ASSEMBLY__ +#include "inc/arc/arc.h" +#include "inc/arc/arc_asm_common.h" + +.global rt_interrupt_enter; .type rt_interrupt_enter, %function +.global rt_interrupt_leave; .type rt_interrupt_leave, %function +.global context_switch_reqflg; .type context_switch_reqflg, %object +.global rt_interrupt_from_thread; .type rt_interrupt_from_thread, %object +.global rt_interrupt_to_thread; .type rt_interrupt_to_thread, %object + + .text + .align 4 +dispatcher: + st sp, [r0] + ld sp, [r1] + pop r0 + j [r0] + +/* return routine when task dispatch happened in task context */ +dispatch_r: + RESTORE_NONSCRATCH_REGS + j [blink] + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.global rt_hw_interrupt_disable +.type rt_hw_interrupt_disable, %function +rt_hw_interrupt_disable: + clri r0 + j [blink] + + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.global rt_hw_interrupt_enable +.type rt_hw_interrupt_enable, %function +rt_hw_interrupt_enable: + seti r0 + j [blink] + + +.global rt_hw_context_switch_interrupt +.type rt_hw_context_switch_interrupt, %function +rt_hw_context_switch_interrupt: + st r0, [rt_interrupt_from_thread] + st r1, [rt_interrupt_to_thread] + mov r0, 1 + st r0, [context_switch_reqflg] + j [blink] + + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.global rt_hw_context_switch +.type rt_hw_context_switch, %function +rt_hw_context_switch: + SAVE_NONSCRATCH_REGS + mov r2, dispatch_r + push r2 + b dispatcher + + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.global rt_hw_context_switch_to +.type rt_hw_context_switch_to, %function +rt_hw_context_switch_to: + ld sp, [r0] + pop r0 + j [r0] + +.global start_r +.type start_r, %function +start_r: + pop blink; + pop r1 + pop r2 + pop r0 + + j_s.d [r1] + kflag r2 + +/****** exceptions and interrupts handing ******/ +/****** entry for exception handling ******/ + .global exc_entry_cpu + .align 4 +exc_entry_cpu: + + EXCEPTION_PROLOGUE + + mov blink, sp + mov r3, sp /* as exception handler's para(p_excinfo) */ + + ld r0, [exc_nest_count] + add r1, r0, 1 + st r1, [exc_nest_count] + cmp r0, 0 + bne exc_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +exc_handler_1: + PUSH blink + + lr r0, [AUX_ECR] + lsr r0, r0, 16 + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] + + mov r0, r3 + jl [r2] + +/* interrupts are not allowed */ +ret_exc: + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + cmp r0, 0 + bne.d ret_exc_1 + st r0, [r1] + + ld r0, [context_switch_reqflg] + cmp r0, 0 + bne ret_exc_2 +ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */ + EXCEPTION_EPILOGUE + rtie + +/* there is a dispatch request */ +ret_exc_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + SAVE_CALLEE_REGS /* save callee save registers */ + + /* clear exception bit to do exception exit by SW */ + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_AE + kflag r0 + + mov r1, ret_exc_r /* save return address */ + PUSH r1 + + ld r0, [rt_interrupt_from_thread] + ld r1, [rt_interrupt_to_thread] + b dispatcher + +ret_exc_r: + /* recover exception status */ + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_AE + kflag r0 + + RESTORE_CALLEE_REGS + EXCEPTION_EPILOGUE + rtie + +/****** entry for normal interrupt exception handling ******/ + .global exc_entry_int /* entry for interrupt handling */ + .align 4 +exc_entry_int: +#if ARC_FEATURE_FIRQ == 1 +/* check whether it is P0 interrupt */ +#if ARC_FEATURE_RGF_NUM_BANKS > 1 + lr r0, [AUX_IRQ_ACT] + btst r0, 0 + jnz exc_entry_firq +#else + PUSH r10 + lr r10, [AUX_IRQ_ACT] + btst r10, 0 + POP r10 + jnz exc_entry_firq +#endif +#endif + INTERRUPT_PROLOGUE + + mov blink, sp + + clri /* disable interrupt */ + ld r3, [exc_nest_count] + add r2, r3, 1 + st r2, [exc_nest_count] + seti /* enable higher priority interrupt */ + + cmp r3, 0 + bne irq_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +irq_handler_1: + PUSH blink + + jl rt_interrupt_enter + + lr r0, [AUX_IRQ_CAUSE] + sr r0, [AUX_IRQ_SELECT] + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */ +/* handle software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d irq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +irq_hint_handled: + lr r3, [AUX_IRQ_PRIORITY] + PUSH r3 /* save irq priority */ + + jl [r2] /* jump to interrupt handler */ + jl rt_interrupt_leave +ret_int: + clri /* disable interrupt */ + POP r3 /* irq priority */ + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + cmp r0, 0 + bne.d ret_int_1 + st r0, [r1] + + ld r0, [context_switch_reqflg] + cmp r0, 0 + bne ret_int_2 +ret_int_1: /* return from non-task context */ + INTERRUPT_EPILOGUE + rtie +/* there is a dispatch request */ +ret_int_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + /* interrupt return by SW */ + lr r10, [AUX_IRQ_ACT] + PUSH r10 + bclr r10, r10, r3 /* clear related bits in IRQ_ACT */ + sr r10, [AUX_IRQ_ACT] + + SAVE_CALLEE_REGS /* save callee save registers */ + mov r1, ret_int_r /* save return address */ + PUSH r1 + + ld r0, [rt_interrupt_from_thread] + ld r1, [rt_interrupt_to_thread] + b dispatcher + +ret_int_r: + RESTORE_CALLEE_REGS + /* recover AUX_IRQ_ACT to restore the interrup status */ + POPAX AUX_IRQ_ACT + INTERRUPT_EPILOGUE + rtie \ No newline at end of file diff --git a/libcpu/arc/em/cpuport.c b/libcpu/arc/em/cpuport.c new file mode 100644 index 0000000000..88c2e12f9b --- /dev/null +++ b/libcpu/arc/em/cpuport.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "inc/arc/arc_exception.h" + +/* enable interrupt and set interrupt priority mask */ +#define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1)) + + +extern void start_r(void); + + +rt_uint32_t context_switch_reqflg; +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; + +struct init_stack_frame { + rt_uint32_t pc; + rt_uint32_t blink; + rt_uint32_t task; + rt_uint32_t status32; + rt_uint32_t r0; +}; + +/** + * shutdown CPU + */ +void rt_hw_cpu_shutdown(void) +{ + +} + +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, + rt_uint8_t *stack_addr, + void *texit) +{ + struct init_stack_frame *stack_frame; + rt_uint8_t *stk; + + stk = stack_addr + sizeof(rt_uint32_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); + stk -= sizeof(struct init_stack_frame); + + stack_frame = (struct init_stack_frame *)stk; + + stack_frame->pc = (rt_uint32_t)start_r; + stack_frame->blink = (rt_uint32_t)texit; + stack_frame->task = (rt_uint32_t)tentry; + stack_frame->status32 = ARC_INIT_STATUS; + stack_frame->r0 = (rt_uint32_t)parameter; + + return stk; +} + + +/** + * This function set the hook, which is invoked on fault exception handling. + * + * @param exception_handle the exception handling hook function. + */ +void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) +{ + exception_handle = exception_handle; +} \ No newline at end of file -- cgit v1.3.1 From 159def753f719e18e65110de47c8a4385cb33e3f Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Thu, 14 Mar 2019 15:45:20 +0800 Subject: arm926内容整理 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/arm926/context_gcc.S | 1 + libcpu/arm/arm926/cpuport.c | 44 ++-- libcpu/arm/arm926/machine.c | 41 +++ libcpu/arm/arm926/mmu.c | 40 +-- libcpu/arm/arm926/mmu.h | 5 +- libcpu/arm/arm926/stack.c | 2 +- libcpu/arm/arm926/start_gcc.S | 557 +++++++++++++++++++++------------------- libcpu/arm/arm926/trap.c | 91 +++---- 8 files changed, 420 insertions(+), 361 deletions(-) create mode 100644 libcpu/arm/arm926/machine.c (limited to 'libcpu') diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S index b6b7863679..f69aa9f5ba 100644 --- a/libcpu/arm/arm926/context_gcc.S +++ b/libcpu/arm/arm926/context_gcc.S @@ -10,6 +10,7 @@ #define NOINT 0xC0 +.text ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c index 1efb23e896..035e97d543 100644 --- a/libcpu/arm/arm926/cpuport.c +++ b/libcpu/arm/arm926/cpuport.c @@ -23,30 +23,30 @@ rt_inline rt_uint32_t cp15_rd(void) { rt_uint32_t i; - __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i)); return i; } rt_inline void cache_enable(rt_uint32_t bit) { __asm volatile(\ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "orr r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + : "r"(bit) \ + : "memory"); } rt_inline void cache_disable(rt_uint32_t bit) { __asm volatile(\ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "bic r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + : "r"(bit) \ + : "memory"); } #endif @@ -152,7 +152,7 @@ void rt_hw_cpu_reset() rt_kprintf("Restarting system...\n"); machine_reset(); - while(1); /* loop forever and wait for reset to happen */ + while (1); /* loop forever and wait for reset to happen */ /* NEVER REACHED */ } @@ -206,21 +206,7 @@ int __rt_ffs(int value) #elif defined(__GNUC__) || defined(__ICCARM__) int __rt_ffs(int value) { - register rt_uint32_t x; - - if (value == 0) - return value; - - __asm - ( - "rsb %[temp], %[val], #0\n" - "and %[temp], %[temp], %[val]\n" - "clz %[temp], %[temp]\n" - "rsb %[temp], %[temp], #32\n" - :[temp] "=r"(x) - :[val] "r"(value) - ); - return x; + return __builtin_ffs(value); } #endif diff --git a/libcpu/arm/arm926/machine.c b/libcpu/arm/arm926/machine.c new file mode 100644 index 0000000000..23953dea42 --- /dev/null +++ b/libcpu/arm/arm926/machine.c @@ -0,0 +1,41 @@ +/* + * File : cpu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 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-02-08 RT-Thread the first version + */ + +#include +#include + +RT_WEAK void machine_reset(void) +{ + rt_kprintf("reboot system...\n"); + rt_hw_interrupt_disable(); + while (1); +} + +RT_WEAK void machine_shutdown(void) +{ + rt_kprintf("shutdown...\n"); + rt_hw_interrupt_disable(); + while (1); +} + diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c index f1e475189b..19d70b9b0b 100644 --- a/libcpu/arm/arm926/mmu.c +++ b/libcpu/arm/arm926/mmu.c @@ -140,7 +140,7 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while(ptr < buffer + size) + while (ptr < buffer + size) { __asm volatile { MCR p15, 0, ptr, c7, c14, 1 } ptr += CACHE_LINE_SIZE; @@ -211,18 +211,18 @@ void mmu_setttbase(register rt_uint32_t i) * set by page table entry */ value = 0; - asm volatile ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); value = 0x55555555; - asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); - asm volatile ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); + asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); } void mmu_set_domain(register rt_uint32_t i) { - asm volatile ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); + asm volatile("mcr p15,0, %0, c3, c0, 0": :"r"(i)); } void mmu_enable() @@ -321,7 +321,7 @@ void mmu_disable_alignfault() void mmu_clean_invalidated_cache_index(int index) { - asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); + asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index)); } void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) @@ -330,9 +330,9 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while(ptr < buffer + size) + while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -347,7 +347,7 @@ void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -361,7 +361,7 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -369,19 +369,19 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) void mmu_invalidate_tlb() { - asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0)); } void mmu_invalidate_icache() { - asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0)); } void mmu_invalidate_dcache_all() { - asm volatile ("mcr p15, 0, %0, c7, c6, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0)); } #endif @@ -389,10 +389,10 @@ void mmu_invalidate_dcache_all() /* level1 page table */ #if defined(__ICCARM__) #pragma data_alignment=(16*1024) -static volatile rt_uint32_t _page_table[4*1024]; +static volatile rt_uint32_t _page_table[4 * 1024]; #else -static volatile rt_uint32_t _page_table[4*1024] \ - __attribute__((aligned(16*1024))); +static volatile rt_uint32_t _page_table[4 * 1024] \ +__attribute__((aligned(16 * 1024))); #endif void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, @@ -401,11 +401,11 @@ void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, volatile rt_uint32_t *pTT; volatile int nSec; int i = 0; - pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20); - nSec=(vaddrEnd>>20)-(vaddrStart>>20); - for(i=0; i<=nSec; i++) + pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for (i = 0; i <= nSec; i++) { - *pTT = attr |(((paddrStart>>20)+i)<<20); + *pTT = attr | (((paddrStart >> 20) + i) << 20); pTT++; } } diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h index 7b930f5358..36fdbeacd8 100644 --- a/libcpu/arm/arm926/mmu.h +++ b/libcpu/arm/arm926/mmu.h @@ -5,6 +5,7 @@ * * Change Logs: * Date Author Notes + * 2018-02-08 RT-Thread the first version */ #ifndef __MMU_H__ @@ -45,5 +46,7 @@ struct mem_desc }; void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size); - +void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size); +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size); +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size); #endif diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c index fa98feb824..f90bfa8c22 100644 --- a/libcpu/arm/arm926/stack.c +++ b/libcpu/arm/arm926/stack.c @@ -38,7 +38,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, stack_addr += sizeof(rt_uint32_t); stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t *)stack_addr; + stk = (rt_uint32_t *)stack_addr; *(--stk) = (rt_uint32_t)tentry; /* entry point */ *(--stk) = (rt_uint32_t)texit; /* lr */ diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index fee8e018cb..35c1f1722e 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -11,295 +11,320 @@ * 2015-06-04 aozima Align stack address to 8 byte. */ -#include "rt_low_level_init.h" - -#define S_FRAME_SIZE (18*4) //72 - -@#define S_SPSR (17*4) //SPSR -@#define S_CPSR (16*4) //CPSR -#define S_PC (15*4) //R15 -@#define S_LR (14*4) //R14 -@#define S_SP (13*4) //R13 - -@#define S_IP (12*4) //R12 -@#define S_FP (11*4) //R11 -@#define S_R10 (10*4) -@#define S_R9 (9*4) -@#define S_R8 (8*4) -@#define S_R7 (7*4) -@#define S_R6 (6*4) -@#define S_R5 (5*4) -@#define S_R4 (4*4) -@#define S_R3 (3*4) -@#define S_R2 (2*4) -@#define S_R1 (1*4) -@#define S_R0 (0*4) - -#define MODE_SYS 0x1F -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_ABT 0x17 -#define MODE_UND 0x1B -#define MODEMASK 0x1F - -#define NOINT 0xC0 - -@;----------------------- Stack and Heap Definitions --------------------------- - .section .nobss, "w" - - .space UND_STK_SIZE +.equ MODE_USR, 0x10 +.equ MODE_FIQ, 0x11 +.equ MODE_IRQ, 0x12 +.equ MODE_SVC, 0x13 +.equ MODE_ABT, 0x17 +.equ MODE_UND, 0x1B +.equ MODE_SYS, 0x1F +.equ MODEMASK, 0x1F +.equ NOINT, 0xC0 + +.equ I_BIT, 0x80 +.equ F_BIT, 0x40 + +.equ UND_STACK_SIZE, 0x00000100 +.equ SVC_STACK_SIZE, 0x00000100 +.equ ABT_STACK_SIZE, 0x00000100 +.equ FIQ_STACK_SIZE, 0x00000100 +.equ IRQ_STACK_SIZE, 0x00000100 +.equ SYS_STACK_SIZE, 0x00000100 + + /* + *************************************** + * Interrupt vector table + *************************************** + */ +.section .vectors +.code 32 + +.global system_vectors +system_vectors: + ldr pc, _vector_reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +_vector_reset: + .word reset +_vector_undef: + .word vector_undef +_vector_swi: + .word vector_swi +_vector_pabt: + .word vector_pabt +_vector_dabt: + .word vector_dabt +_vector_resv: + .word vector_resv +_vector_irq: + .word vector_irq +_vector_fiq: + .word vector_fiq + +.balignl 16,0xdeadbeef + + /* + *************************************** + * Stack and Heap Definitions + *************************************** + */ + .section .data + .space UND_STACK_SIZE .align 3 - .global UND_STACK_START -UND_STACK_START: + .global und_stack_start +und_stack_start: - .space ABT_STK_SIZE + .space ABT_STACK_SIZE .align 3 - .global ABT_STACK_START -ABT_STACK_START: + .global abt_stack_start +abt_stack_start: - .space FIQ_STK_SIZE + .space FIQ_STACK_SIZE .align 3 - .global FIQ_STACK_START -FIQ_STACK_START: + .global fiq_stack_start +fiq_stack_start: - .space IRQ_STK_SIZE + .space IRQ_STACK_SIZE .align 3 - .global IRQ_STACK_START -IRQ_STACK_START: + .global irq_stack_start +irq_stack_start: - .skip SYS_STK_SIZE + .skip SYS_STACK_SIZE .align 3 - .global SYS_STACK_START -SYS_STACK_START: + .global sys_stack_start +sys_stack_start: - .space SVC_STK_SIZE + .space SVC_STACK_SIZE .align 3 - .global SVC_STACK_START -SVC_STACK_START: - -@;--------------Jump vector table----------------------------------------------- - .section .init, "ax" - .arm - - .global start -start: - LDR PC, vector_reset - LDR PC, vector_undef - LDR PC, vector_swi - LDR PC, vector_pabt - LDR PC, vector_dabt - LDR PC, vector_resv - LDR PC, vector_irq - LDR PC, vector_fiq - -vector_reset: - .word Reset_Handler -vector_undef: - .word Undef_Handler -vector_swi: - .word SWI_Handler -vector_pabt: - .word PAbt_Handler -vector_dabt: - .word DAbt_Handler -vector_resv: - .word Resv_Handler -vector_irq: - .word IRQ_Handler -vector_fiq: - .word FIQ_Handler - - .balignl 16,0xdeadbeef - -@;----------------- Reset Handler --------------------------------------------- - .global rt_low_level_init - .global main - .global Reset_Handler -Reset_Handler: - @; Set the cpu to SVC32 mode - MRS R0, CPSR - BIC R0, R0, #MODEMASK - ORR R0, R0, #MODE_SVC|NOINT - MSR CPSR_cxsf, R0 + .global svc_stack_start +svc_stack_start: + +/* + *************************************** + * Startup Code + *************************************** + */ + .section .text + .global reset +reset: + /* Enter svc mode and mask interrupts */ + mrs r0, cpsr + bic r0, r0, #MODEMASK + orr r0, r0, #MODE_SVC|NOINT + msr cpsr_cxsf, r0 + + /* init cpu */ + bl cpu_init_crit + + /* todo:copyself to link address */ + + /* Copy vector to the correct address */ + ldr r0, =system_vectors + mrc p15, 0, r2, c1, c0, 0 + ands r2, r2, #(1 << 13) + ldreq r1, =0x00000000 + ldrne r1, =0xffff0000 + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} + + /* turn off the watchdog */ + ldr r0, =0x01C20CB8 + mov r1, #0x0 + str r1, [r0] + + /* mask all IRQs source */ + ldr r1, =0xffffffff + ldr r0, =0x01C20430 + str r1, [r0], #0x04 + str r1, [r0] + + /* Call low level init function */ + ldr sp, =svc_stack_start + ldr r0, =rt_low_level_init + blx r0 + + /* init stack */ + bl stack_setup - @; Set CO-Processor - @; little-end锛宒isbale I/D Cache MMU, vector table is 0x00000000 - MRC P15, 0, R0, C1, C0, 0 @; Read CP15 - LDR R1, =0x00003085 @; set clear bits - BIC R0, R0, R1 - MCR P15, 0, R0, C1, C0, 0 @; Write CP15 - - @; Call low level init function, - @; disable and clear all IRQs, Init MMU, Init interrupt controller, etc. - LDR SP, =SVC_STACK_START - LDR R0, =rt_low_level_init - BLX R0 - -Setup_Stack: - @; Setup Stack for each mode - MRS R0, CPSR - BIC R0, R0, #MODEMASK - - ORR R1, R0, #MODE_UND|NOINT - MSR CPSR_cxsf, R1 @; Undef mode - LDR SP, =UND_STACK_START - - ORR R1, R0, #MODE_ABT|NOINT - MSR CPSR_cxsf, R1 @; Abort mode - LDR SP, =ABT_STACK_START - - ORR R1, R0, #MODE_IRQ|NOINT - MSR CPSR_cxsf, R1 @; IRQ mode - LDR SP, =IRQ_STACK_START - - ORR R1, R0, #MODE_FIQ|NOINT - MSR CPSR_cxsf, R1 @; FIQ mode - LDR SP, =FIQ_STACK_START - - ORR R1, R0, #MODE_SYS|NOINT - MSR CPSR_cxsf,R1 @; SYS/User mode - LDR SP, =SYS_STACK_START - - ORR R1, R0, #MODE_SVC|NOINT - MSR CPSR_cxsf, R1 @; SVC mode - LDR SP, =SVC_STACK_START - - @; clear .bss - MOV R0, #0 @; get a zero - LDR R1, =__bss_start__ @; bss start - LDR R2, =__bss_end__ @; bss end + /* clear bss */ + mov r0, #0 + ldr r1, =__bss_start + ldr r2, =__bss_end bss_clear_loop: - CMP R1, R2 @; check if data to clear - STRLO R0, [R1], #4 @; clear 4 bytes - BLO bss_clear_loop @; loop until done - - @; call C++ constructors of global objects - LDR R0, =__ctors_start__ - LDR R1, =__ctors_end__ + cmp r1, r2 + strlo r0, [r1], #4 + blo bss_clear_loop + + /* call c++ constructors of global objects */ + /* + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ ctor_loop: - CMP R0, R1 - BEQ ctor_end - LDR R2, [R0], #4 - STMFD SP!, {R0-R1} - MOV LR, PC - BX R2 - LDMFD SP!, {R0-R1} - B ctor_loop + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + bx r2 + ldmfd sp!, {r0-r1} + b ctor_loop ctor_end: + */ + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup +_rtthread_startup: + .word rtthread_startup + + + +cpu_init_crit: + /* invalidate I/D caches */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 + mcr p15, 0, r0, c8, c7, 0 + + /* disable MMU stuff and caches */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 + bic r0, r0, #0x00000087 + orr r0, r0, #0x00000002 + orr r0, r0, #0x00001000 + mcr p15, 0, r0, c1, c0, 0 + + bx lr + +stack_setup: + /* Setup Stack for each mode */ + mrs r0, cpsr + bic r0, r0, #MODEMASK + + orr r1, r0, #MODE_UND|NOINT + msr cpsr_cxsf, r1 + ldr sp, =und_stack_start + + orr r1, r0, #MODE_ABT|NOINT + msr cpsr_cxsf, r1 + ldr sp, =abt_stack_start + + orr r1, r0, #MODE_IRQ|NOINT + msr cpsr_cxsf, r1 + ldr sp, =irq_stack_start + + orr r1, r0, #MODE_FIQ|NOINT + msr cpsr_cxsf, r1 + ldr sp, =fiq_stack_start + + orr r1, r0, #MODE_SYS|NOINT + msr cpsr_cxsf,r1 + ldr sp, =sys_stack_start + + orr r1, r0, #MODE_SVC|NOINT + msr cpsr_cxsf, r1 + ldr sp, =svc_stack_start + + bx lr + +/* + *************************************** + * exception handlers + *************************************** + */ + /* Interrupt */ +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc, lr, #4 - @; Enter the C code - LDR R0, =rtthread_startup - BLX R0 - -@;----------------- Exception Handler ----------------------------------------- - .global rt_hw_trap_udef - .global rt_hw_trap_swi - .global rt_hw_trap_pabt - .global rt_hw_trap_dabt - .global rt_hw_trap_resv - .global rt_hw_trap_irq - .global rt_hw_trap_fiq - - .global rt_interrupt_enter - .global rt_interrupt_leave - .global rt_thread_switch_interrupt_flag - .global rt_interrupt_from_thread - .global rt_interrupt_to_thread - - .align 5 -Undef_Handler: - SUB SP, SP, #S_FRAME_SIZE - STMIA SP, {R0 - R12} @; Calling R0-R12 - ADD R8, SP, #S_PC - STMDB R8, {SP, LR} @; Calling SP, LR - STR LR, [R8, #0] @; Save calling PC - MRS R6, SPSR - STR R6, [R8, #4] @; Save CPSR - STR R0, [R8, #8] @; Save SPSR - MOV R0, SP - BL rt_hw_trap_udef - - .align 5 -SWI_Handler: - BL rt_hw_trap_swi - - .align 5 -PAbt_Handler: - BL rt_hw_trap_pabt - - .align 5 -DAbt_Handler: - SUB SP, SP, #S_FRAME_SIZE - STMIA SP, {R0 - R12} @; Calling R0-R12 - ADD R8, SP, #S_PC - STMDB R8, {SP, LR} @; Calling SP, LR - STR LR, [R8, #0] @; Save calling PC - MRS R6, SPSR - STR R6, [R8, #4] @; Save CPSR - STR R0, [R8, #8] @; Save SPSR - MOV R0, SP - BL rt_hw_trap_dabt - - .align 5 -Resv_Handler: - BL rt_hw_trap_resv - - .align 5 -FIQ_Handler: - STMFD SP!, {R0-R7,LR} - BL rt_hw_trap_fiq - LDMFD SP!, {R0-R7,LR} - SUBS PC, LR, #4 - - .align 5 -IRQ_Handler: - STMFD SP!, {R0-R12,LR} - BL rt_interrupt_enter - BL rt_hw_trap_irq - BL rt_interrupt_leave - - @; If rt_thread_switch_interrupt_flag set, - @; jump to rt_hw_context_switch_interrupt_do and don't return - LDR R0, =rt_thread_switch_interrupt_flag - LDR R1, [R0] - CMP R1, #1 - BEQ rt_hw_context_switch_interrupt_do - - LDMFD SP!, {R0-R12,LR} - SUBS PC, LR, #4 - -@;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- -rt_hw_context_switch_interrupt_do: - MOV R1, #0 @; Clear flag - STR R1, [R0] @; Save to flag variable +vector_irq: + stmfd sp!, {r0-r12,lr} + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave - LDMFD SP!, {R0-R12,LR} @; Reload saved registers - STMFD SP, {R0-R2} @; Save R0-R2 - SUB R1, SP, #4*3 @; Save old task's SP to R1 - SUB R2, LR, #4 @; Save old task's PC to R2 + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do - MRS R0, SPSR @; Get CPSR of interrupt thread + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 - MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt +rt_hw_context_switch_interrupt_do: + mov r1, #0 + str r1, [r0] + + mov r1, sp + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr} + mrs r0, spsr + sub r2, lr, #4 + + msr cpsr_c, #I_BIT|F_BIT|MODE_SVC + + stmfd sp!, {r2} + stmfd sp!, {r4-r12,lr} + ldmfd r1, {r1-r4} + stmfd sp!, {r1-r4} + stmfd sp!, {r0} + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] + + ldmfd sp!, {r4} + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ + + /* Exception */ +.macro push_svc_reg + sub sp, sp, #17 * 4 + stmia sp, {r0 - r12} + mov r0, sp + mrs r6, spsr + str lr, [r0, #15*4] + str r6, [r0, #16*4] + str sp, [r0, #13*4] + str lr, [r0, #14*4] +.endm - STMFD SP!, {R2} @; Push old task's PC - STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3 - LDMFD R1, {R1-R3} - STMFD SP!, {R1-R3} @; Push old task's R2-R0 - STMFD SP!, {R0} @; Push old task's CPSR +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . - LDR R4, =rt_interrupt_from_thread - LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB - STR SP, [R5] @; Store SP in preempted tasks's TCB +vector_undef: + push_svc_reg + bl rt_hw_trap_udef + b . - LDR R6, =rt_interrupt_to_thread - LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB - LDR SP, [R6] @; Get new task's stack pointer +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . - LDMFD SP!, {R4} @; Pop new task's SPSR - MSR SPSR_cxsf, R4 +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . - LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . diff --git a/libcpu/arm/arm926/trap.c b/libcpu/arm/arm926/trap.c index 054cc2741a..de04c3f8cb 100644 --- a/libcpu/arm/arm926/trap.c +++ b/libcpu/arm/arm926/trap.c @@ -41,14 +41,18 @@ struct rt_hw_register rt_uint32_t cpsr; rt_uint32_t ORIG_r0; }; - +static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; +void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) +{ + rt_exception_hook = exception_handle; +} /** * this function will show registers of CPU * * @param regs the registers point */ -void rt_hw_show_register (struct rt_hw_register *regs) +void rt_hw_show_register(struct rt_hw_register *regs) { rt_kprintf("Execption:\n"); rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", @@ -74,6 +78,13 @@ void rt_hw_show_register (struct rt_hw_register *regs) */ void rt_hw_trap_udef(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("undefined instruction\n"); @@ -96,6 +107,13 @@ void rt_hw_trap_udef(struct rt_hw_register *regs) */ void rt_hw_trap_swi(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("software interrupt\n"); @@ -112,6 +130,13 @@ void rt_hw_trap_swi(struct rt_hw_register *regs) */ void rt_hw_trap_pabt(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("prefetch abort\n"); @@ -133,6 +158,13 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs) */ void rt_hw_trap_dabt(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("data abort\n"); @@ -153,55 +185,26 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs) */ void rt_hw_trap_resv(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_kprintf("not used\n"); rt_hw_show_register(regs); rt_hw_cpu_shutdown(); } -extern struct rt_irq_desc irq_desc[]; -extern rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq); -extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id); - -void rt_hw_trap_irq() -{ - rt_isr_handler_t isr_func; - rt_uint32_t irq; - void *param; - - /* get irq number */ - irq = rt_hw_interrupt_get_active(INT_IRQ); +extern void rt_interrupt_dispatch(void); - /* get interrupt service routine */ - isr_func = irq_desc[irq].handler; - param = irq_desc[irq].param; - - /* turn to interrupt service routine */ - isr_func(irq, param); - - rt_hw_interrupt_ack(INT_IRQ, irq); -#ifdef RT_USING_INTERRUPT_INFO - irq_desc[irq].counter ++; -#endif +void rt_hw_trap_irq(void) +{ + rt_interrupt_dispatch(); } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { - rt_isr_handler_t isr_func; - rt_uint32_t irq; - void *param; - - /* get irq number */ - irq = rt_hw_interrupt_get_active(INT_FIQ); - - /* get interrupt service routine */ - isr_func = irq_desc[irq].handler; - param = irq_desc[irq].param; - - /* turn to interrupt service routine */ - isr_func(irq, param); - - rt_hw_interrupt_ack(INT_FIQ, irq); -#ifdef RT_USING_INTERRUPT_INFO - irq_desc[irq].counter ++; -#endif + rt_interrupt_dispatch(); } -- cgit v1.3.1 From 29264edde8a0fedec9edae6518e8520a9913fd88 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Thu, 14 Mar 2019 17:54:21 +0800 Subject: 修改arm926中machine.c的协议声明 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/arm926/machine.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'libcpu') diff --git a/libcpu/arm/arm926/machine.c b/libcpu/arm/arm926/machine.c index 23953dea42..aa26d10ec6 100644 --- a/libcpu/arm/arm926/machine.c +++ b/libcpu/arm/arm926/machine.c @@ -1,21 +1,7 @@ /* - * File : cpu.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team + * 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. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes -- cgit v1.3.1 From 3dd72f956bfa1f68a4ee69ccc823fb93c607f312 Mon Sep 17 00:00:00 2001 From: ZYH Date: Wed, 20 Mar 2019 12:01:44 +0800 Subject: [libcpu][k210]add description of exception --- libcpu/risc-v/k210/interrupt.c | 49 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'libcpu') diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c index 3d30e69ed2..f6424ab5ef 100644 --- a/libcpu/risc-v/k210/interrupt.c +++ b/libcpu/risc-v/k210/interrupt.c @@ -230,10 +230,6 @@ uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) /* Restore primitive IRQ threshold */ plic->targets.target[core_id].priority_threshold = int_threshold; } - else - { - rt_kprintf("unhandled trap!\n"); - } return epc; } @@ -270,8 +266,51 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) rt_hw_interrupt_disable(); tid = rt_thread_self(); + rt_kprintf("\nException:\n"); + switch (cause) + { + case CAUSE_MISALIGNED_FETCH: + rt_kprintf("Instruction address misaligned"); + break; + case CAUSE_FAULT_FETCH: + rt_kprintf("Instruction access fault"); + break; + case CAUSE_ILLEGAL_INSTRUCTION: + rt_kprintf("Illegal instruction"); + break; + case CAUSE_BREAKPOINT: + rt_kprintf("Breakpoint"); + break; + case CAUSE_MISALIGNED_LOAD: + rt_kprintf("Load address misaligned"); + break; + case CAUSE_FAULT_LOAD: + rt_kprintf("Load access fault"); + break; + case CAUSE_MISALIGNED_STORE: + rt_kprintf("Store address misaligned"); + break; + case CAUSE_FAULT_STORE: + rt_kprintf("Store access fault"); + break; + case CAUSE_USER_ECALL: + rt_kprintf("Environment call from U-mode"); + break; + case CAUSE_SUPERVISOR_ECALL: + rt_kprintf("Environment call from S-mode"); + break; + case CAUSE_HYPERVISOR_ECALL: + rt_kprintf("Environment call from H-mode"); + break; + case CAUSE_MACHINE_ECALL: + rt_kprintf("Environment call from M-mode"); + break; + default: + rt_kprintf("Uknown exception : %08lX", cause); + break; + } rt_kprintf("\n"); - rt_kprintf("unhandled trap, epc => 0x%08x, INT[%d]\n", epc, rt_interrupt_get_nest()); + rt_kprintf("exception pc => 0x%08x\n", epc); rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, tid->name); #ifdef RT_USING_FINSH list_thread(); -- cgit v1.3.1 From c41bf3120f5704f08a90f96ab068bfb4850ad692 Mon Sep 17 00:00:00 2001 From: ZYH Date: Thu, 21 Mar 2019 15:07:58 +0800 Subject: [libcpu][k210]add stack info printf --- libcpu/risc-v/k210/interrupt.c | 77 +++++++++++++++++++++++++++++++++++++- libcpu/risc-v/k210/interrupt_gcc.S | 2 +- 2 files changed, 77 insertions(+), 2 deletions(-) (limited to 'libcpu') diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c index f6424ab5ef..45b437c099 100644 --- a/libcpu/risc-v/k210/interrupt.c +++ b/libcpu/risc-v/k210/interrupt.c @@ -233,8 +233,82 @@ uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) return epc; } +struct exception_stack_frame +{ + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; +}; + +void print_stack_frame(uintptr_t * sp) +{ + struct exception_stack_frame * esf = (struct exception_stack_frame *)sp; + + rt_kprintf("\n=================================================================\n"); + rt_kprintf("x1 (ra : Return address ) ==> 0x%08x%08x\n", esf->x1 >> 32 , esf->x1 & UINT32_MAX); + rt_kprintf("x2 (sp : Stack pointer ) ==> 0x%08x%08x\n", esf->x2 >> 32 , esf->x2 & UINT32_MAX); + rt_kprintf("x3 (gp : Global pointer ) ==> 0x%08x%08x\n", esf->x3 >> 32 , esf->x3 & UINT32_MAX); + rt_kprintf("x4 (tp : Thread pointer ) ==> 0x%08x%08x\n", esf->x4 >> 32 , esf->x4 & UINT32_MAX); + rt_kprintf("x5 (t0 : Temporary ) ==> 0x%08x%08x\n", esf->x5 >> 32 , esf->x5 & UINT32_MAX); + rt_kprintf("x6 (t1 : Temporary ) ==> 0x%08x%08x\n", esf->x6 >> 32 , esf->x6 & UINT32_MAX); + rt_kprintf("x7 (t2 : Temporary ) ==> 0x%08x%08x\n", esf->x7 >> 32 , esf->x7 & UINT32_MAX); + rt_kprintf("x8 (s0/fp: Save register,frame pointer ) ==> 0x%08x%08x\n", esf->x8 >> 32 , esf->x8 & UINT32_MAX); + rt_kprintf("x9 (s1 : Save register ) ==> 0x%08x%08x\n", esf->x9 >> 32 , esf->x9 & UINT32_MAX); + rt_kprintf("x10(a0 : Function argument,return value) ==> 0x%08x%08x\n", esf->x10 >> 32 , esf->x10 & UINT32_MAX); + rt_kprintf("x11(a1 : Function argument,return value) ==> 0x%08x%08x\n", esf->x11 >> 32 , esf->x11 & UINT32_MAX); + rt_kprintf("x12(a2 : Function argument ) ==> 0x%08x%08x\n", esf->x12 >> 32 , esf->x12 & UINT32_MAX); + rt_kprintf("x13(a3 : Function argument ) ==> 0x%08x%08x\n", esf->x13 >> 32 , esf->x13 & UINT32_MAX); + rt_kprintf("x14(a4 : Function argument ) ==> 0x%08x%08x\n", esf->x14 >> 32 , esf->x14 & UINT32_MAX); + rt_kprintf("x15(a5 : Function argument ) ==> 0x%08x%08x\n", esf->x15 >> 32 , esf->x15 & UINT32_MAX); + rt_kprintf("x16(a6 : Function argument ) ==> 0x%08x%08x\n", esf->x16 >> 32 , esf->x16 & UINT32_MAX); + rt_kprintf("x17(a7 : Function argument ) ==> 0x%08x%08x\n", esf->x17 >> 32 , esf->x17 & UINT32_MAX); + rt_kprintf("x18(s2 : Save register ) ==> 0x%08x%08x\n", esf->x18 >> 32 , esf->x18 & UINT32_MAX); + rt_kprintf("x19(s3 : Save register ) ==> 0x%08x%08x\n", esf->x19 >> 32 , esf->x19 & UINT32_MAX); + rt_kprintf("x20(s4 : Save register ) ==> 0x%08x%08x\n", esf->x20 >> 32 , esf->x20 & UINT32_MAX); + rt_kprintf("x21(s5 : Save register ) ==> 0x%08x%08x\n", esf->x21 >> 32 , esf->x21 & UINT32_MAX); + rt_kprintf("x22(s6 : Save register ) ==> 0x%08x%08x\n", esf->x22 >> 32 , esf->x22 & UINT32_MAX); + rt_kprintf("x23(s7 : Save register ) ==> 0x%08x%08x\n", esf->x23 >> 32 , esf->x23 & UINT32_MAX); + rt_kprintf("x24(s8 : Save register ) ==> 0x%08x%08x\n", esf->x24 >> 32 , esf->x24 & UINT32_MAX); + rt_kprintf("x25(s9 : Save register ) ==> 0x%08x%08x\n", esf->x25 >> 32 , esf->x25 & UINT32_MAX); + rt_kprintf("x26(s10 : Save register ) ==> 0x%08x%08x\n", esf->x26 >> 32 , esf->x26 & UINT32_MAX); + rt_kprintf("x27(s11 : Save register ) ==> 0x%08x%08x\n", esf->x27 >> 32 , esf->x27 & UINT32_MAX); + rt_kprintf("x28(t3 : Temporary ) ==> 0x%08x%08x\n", esf->x28 >> 32 , esf->x28 & UINT32_MAX); + rt_kprintf("x29(t4 : Temporary ) ==> 0x%08x%08x\n", esf->x29 >> 32 , esf->x29 & UINT32_MAX); + rt_kprintf("x30(t5 : Temporary ) ==> 0x%08x%08x\n", esf->x30 >> 32 , esf->x30 & UINT32_MAX); + rt_kprintf("x31(t6 : Temporary ) ==> 0x%08x%08x\n", esf->x31 >> 32 , esf->x31 & UINT32_MAX); + rt_kprintf("=================================================================\n"); +} + -uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp) { int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK; @@ -310,6 +384,7 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) break; } rt_kprintf("\n"); + print_stack_frame(sp); rt_kprintf("exception pc => 0x%08x\n", epc); rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, tid->name); #ifdef RT_USING_FINSH diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S index 5d3e8368b1..aeda72ab31 100644 --- a/libcpu/risc-v/k210/interrupt_gcc.S +++ b/libcpu/risc-v/k210/interrupt_gcc.S @@ -69,7 +69,7 @@ trap_entry: call rt_interrupt_enter csrr a0, mcause csrr a1, mepc - mv a2, sp + mv a2, s0 call handle_trap call rt_interrupt_leave -- cgit v1.3.1 From e6d153732776c2e1950f3adfbce2dde2761bff60 Mon Sep 17 00:00:00 2001 From: tangyuxin <462747508@qq.com> Date: Mon, 25 Mar 2019 15:18:09 +0800 Subject: 移除 SConscript.1 临时文件 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/mips/xburst/SConscript.1 | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 libcpu/mips/xburst/SConscript.1 (limited to 'libcpu') diff --git a/libcpu/mips/xburst/SConscript.1 b/libcpu/mips/xburst/SConscript.1 deleted file mode 100644 index b0ae20ba02..0000000000 --- a/libcpu/mips/xburst/SConscript.1 +++ /dev/null @@ -1,14 +0,0 @@ -# RT-Thread building script for component - -from building import * - -Import('rtconfig') - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') -CPPPATH = [cwd] -ASFLAGS = '' - -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) - -Return('group') -- cgit v1.3.1 From 2eb1bef773e099ac93ec74dba7ec216bdf61597c Mon Sep 17 00:00:00 2001 From: qz721 <295354721@qq.com> Date: Mon, 25 Mar 2019 20:03:49 +0800 Subject: Make 'qemu-vexpress-a9' and 'imx6ul' use the same libcpu code. --- bsp/imx6ul/.config | 358 +++++++++++++++++++++ bsp/imx6ul/drivers/board.c | 19 +- bsp/imx6ul/platform/SConscript | 4 +- bsp/imx6ul/platform/cpu/gic.c | 243 --------------- bsp/imx6ul/platform/cpu/mmu.c | 285 ----------------- bsp/imx6ul/platform/cpu/mmu.h | 157 ---------- bsp/imx6ul/platform/cpu/platform.h | 96 ++++++ bsp/imx6ul/platform/include/gic.h | 183 ----------- bsp/imx6ul/platform/include/interrupt.h | 101 ------ bsp/imx6ul/rtconfig.py | 2 +- bsp/qemu-vexpress-a9/.config | 1 + bsp/qemu-vexpress-a9/SConstruct | 4 +- bsp/qemu-vexpress-a9/cpu/SConscript | 17 - bsp/qemu-vexpress-a9/cpu/armv7.h | 64 ---- bsp/qemu-vexpress-a9/cpu/context_gcc.S | 198 ------------ bsp/qemu-vexpress-a9/cpu/cp15.h | 12 - bsp/qemu-vexpress-a9/cpu/cp15_gcc.S | 140 --------- bsp/qemu-vexpress-a9/cpu/cpuport.c | 83 ----- bsp/qemu-vexpress-a9/cpu/gic.c | 299 ------------------ bsp/qemu-vexpress-a9/cpu/gic.h | 33 -- bsp/qemu-vexpress-a9/cpu/interrupt.c | 108 ------- bsp/qemu-vexpress-a9/cpu/interrupt.h | 25 -- bsp/qemu-vexpress-a9/cpu/mmu.c | 207 ------------- bsp/qemu-vexpress-a9/cpu/pmu.c | 12 - bsp/qemu-vexpress-a9/cpu/pmu.h | 151 --------- bsp/qemu-vexpress-a9/cpu/stack.c | 71 ----- bsp/qemu-vexpress-a9/cpu/start_gcc.S | 447 --------------------------- bsp/qemu-vexpress-a9/cpu/trap.c | 190 ------------ bsp/qemu-vexpress-a9/cpu/vector_gcc.S | 65 ---- bsp/qemu-vexpress-a9/drivers/board.c | 9 + bsp/qemu-vexpress-a9/platform/SConscript | 13 + bsp/qemu-vexpress-a9/platform/cpu/platform.h | 37 +++ bsp/qemu-vexpress-a9/rtconfig.h | 149 +++++++++ bsp/qemu-vexpress-a9/rtconfig.py | 5 +- components/lwp/SConscript | 2 +- components/lwp/arch/arm/cortex-a/lwp_gcc.S | 70 +++++ libcpu/arm/cortex-a/context_gcc.S | 92 ++++++ libcpu/arm/cortex-a/cp15.h | 4 + libcpu/arm/cortex-a/cp15_gcc.S | 15 +- libcpu/arm/cortex-a/cpu.c | 68 +++- libcpu/arm/cortex-a/gic.c | 301 ++++++++++++++++++ libcpu/arm/cortex-a/gic.h | 35 +++ libcpu/arm/cortex-a/interrupt.c | 119 +++---- libcpu/arm/cortex-a/interrupt.h | 32 ++ libcpu/arm/cortex-a/mmu.c | 49 +-- libcpu/arm/cortex-a/mmu.h | 48 +++ libcpu/arm/cortex-a/stack.c | 6 +- libcpu/arm/cortex-a/start_gcc.S | 112 ++++++- libcpu/arm/cortex-a/trap.c | 70 +++-- 49 files changed, 1541 insertions(+), 3270 deletions(-) create mode 100644 bsp/imx6ul/.config delete mode 100644 bsp/imx6ul/platform/cpu/gic.c delete mode 100644 bsp/imx6ul/platform/cpu/mmu.c delete mode 100644 bsp/imx6ul/platform/cpu/mmu.h create mode 100644 bsp/imx6ul/platform/cpu/platform.h delete mode 100644 bsp/imx6ul/platform/include/gic.h delete mode 100644 bsp/imx6ul/platform/include/interrupt.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/SConscript delete mode 100644 bsp/qemu-vexpress-a9/cpu/armv7.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/context_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/cp15.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/cp15_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/cpuport.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/gic.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/gic.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/interrupt.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/interrupt.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/mmu.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/pmu.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/pmu.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/stack.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/start_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/trap.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/vector_gcc.S create mode 100644 bsp/qemu-vexpress-a9/platform/SConscript create mode 100644 bsp/qemu-vexpress-a9/platform/cpu/platform.h create mode 100644 components/lwp/arch/arm/cortex-a/lwp_gcc.S create mode 100644 libcpu/arm/cortex-a/gic.c create mode 100644 libcpu/arm/cortex-a/gic.h create mode 100644 libcpu/arm/cortex-a/interrupt.h create mode 100644 libcpu/arm/cortex-a/mmu.h (limited to 'libcpu') diff --git a/bsp/imx6ul/.config b/bsp/imx6ul/.config new file mode 100644 index 0000000000..a9299a366b --- /dev/null +++ b/bsp/imx6ul/.config @@ -0,0 +1,358 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# +CONFIG_BOARD_IMX6UL=y + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# 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=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart" +CONFIG_RT_VER_NUM=0x40001 +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_CORTEX_A=y +CONFIG_ARCH_ARM_CORTEX_A7=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# 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_ECHO_DISABLE_DEFAULT is not set +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 +CONFIG_FINSH_ARG_MAX=10 + +# +# 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=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# 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 + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_MTD is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set + +# +# Using WiFi +# +# 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 is not set +CONFIG_RT_USING_POSIX=y +# CONFIG_RT_USING_POSIX_MMAP is not set +# CONFIG_RT_USING_POSIX_TERMIOS is not set +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT 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 +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_LWP is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET 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_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTKIT is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ADBD is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_RT_USING_UART0 is not set +CONFIG_RT_USING_UART1=y diff --git a/bsp/imx6ul/drivers/board.c b/bsp/imx6ul/drivers/board.c index e53e2405b6..015a3709c1 100644 --- a/bsp/imx6ul/drivers/board.c +++ b/bsp/imx6ul/drivers/board.c @@ -20,6 +20,15 @@ #include #include +#include + +struct mem_desc platform_mem_desc[] = { + {0x00000000, 0x80000000, 0x00000000, DEVICE_MEM}, + {0x80000000, 0xFFF00000, 0x80000000, NORMAL_MEM} +}; + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); + static void rt_hw_timer_isr(int vector, void *param) { rt_tick_increase(); @@ -32,17 +41,17 @@ int rt_hw_timer_init(void) // Make sure the timer is off. HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0; - + HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1; - + HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0; - + HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0; - + // Clear counter. HW_ARMGLOBALTIMER_COUNTER_HI_WR(0); HW_ARMGLOBALTIMER_COUNTER_LO_WR(0); - + // Now turn on the timer. HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1; diff --git a/bsp/imx6ul/platform/SConscript b/bsp/imx6ul/platform/SConscript index 34834e6391..9ba43b1483 100644 --- a/bsp/imx6ul/platform/SConscript +++ b/bsp/imx6ul/platform/SConscript @@ -8,14 +8,12 @@ drivers/imx_timer.c drivers/imx_i2c.c drivers/imx_uart.c cpu/armv7_cache.c -cpu/gic.c cpu/ccm_pll2.c -cpu/mmu.c cpu/cortex_a_gcc.S ''') CPPPATH = [ cwd + '/cpu', -cwd + '/include', +cwd + '/include', cwd + '/include/mx6ul', cwd + '/include/mx6ul/registers' ] diff --git a/bsp/imx6ul/platform/cpu/gic.c b/bsp/imx6ul/platform/cpu/gic.c deleted file mode 100644 index 2f140e02c6..0000000000 --- a/bsp/imx6ul/platform/cpu/gic.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include "gic.h" -#include "gic_registers.h" -#include "cortex_a.h" - -//////////////////////////////////////////////////////////////////////////////// -// Prototypes -//////////////////////////////////////////////////////////////////////////////// - -static inline gicd_t * gic_get_gicd(void); -static inline gicc_t * gic_get_gicc(void); -static inline uint32_t irq_get_register_offset(uint32_t irqID); -static inline uint32_t irq_get_bit_offset(uint32_t irqID); -static inline uint32_t irq_get_bit_mask(uint32_t irqID); - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -static inline gicd_t * gic_get_gicd(void) -{ - uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset; - return (gicd_t *)base; -} - -static inline gicc_t * gic_get_gicc(void) -{ - uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset; - return (gicc_t *)base; -} - -static inline uint32_t irq_get_register_offset(uint32_t irqID) -{ - return irqID / 32; -} - -static inline uint32_t irq_get_bit_offset(uint32_t irqID) -{ - return irqID & 0x1f; -} - -static inline uint32_t irq_get_bit_mask(uint32_t irqID) -{ - return 1 << irq_get_bit_offset(irqID); -} - -void gic_enable(bool enableIt) -{ - gicd_t * gicd = gic_get_gicd(); - - if (enableIt) - { - // Enable both secure and non-secure. - gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1; - } - else - { - // Clear the enable bits. - gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1); - } -} - -void gic_set_irq_security(uint32_t irqID, bool isSecure) -{ - gicd_t * gicd = gic_get_gicd(); - - uint32_t reg = irq_get_register_offset(irqID); - uint32_t mask = irq_get_bit_mask(irqID); - - uint32_t value = gicd->IGROUPRn[reg]; - if (!isSecure) - { - value &= ~mask; - } - else - { - value |= mask; - } - gicd->IGROUPRn[reg] = value; -} - -void gic_enable_irq(uint32_t irqID, bool isEnabled) -{ - gicd_t * gicd = gic_get_gicd(); - - uint32_t reg = irq_get_register_offset(irqID); - uint32_t mask = irq_get_bit_mask(irqID); - - // Select set-enable or clear-enable register based on enable flag. - if (isEnabled) - { - gicd->ISENABLERn[reg] = mask; - } - else - { - gicd->ICENABLERn[reg] = mask; - } -} - -void gic_set_irq_priority(uint32_t ID, uint32_t priority) -{ - gicd_t * gicd = gic_get_gicd(); - - // Update the priority register. The priority registers are byte accessible, and the register - // struct has the priority registers as a byte array, so we can just index directly by the - // interrupt ID. - gicd->IPRIORITYRn[ID] = priority & 0xff; -} - -void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt) -{ - // Make sure the CPU number is valid. - assert(cpuNumber <= 7); - - gicd_t * gicd = gic_get_gicd(); - uint8_t cpuMask = 1 << cpuNumber; - - // Like the priority registers, the target registers are byte accessible, and the register - // struct has the them as a byte array, so we can just index directly by the - // interrupt ID. - if (enableIt) - { - gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff); - } - else - { - gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff); - } -} - -void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list) -{ - gicd_t * gicd = gic_get_gicd(); - - gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter) - | (target_list << kBP_GICD_SGIR_CPUTargetList) - | (irqID & 0xf); -} - -void gic_cpu_enable(bool enableIt) -{ - gicc_t * gicc = gic_get_gicc(); - - if (enableIt) - { - gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS; - } - else - { - gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS); - } -} - -void gic_set_cpu_priority_mask(uint32_t priority) -{ - gicc_t * gicc = gic_get_gicc(); - gicc->PMR = priority & 0xff; -} - -uint32_t gic_read_irq_ack(void) -{ - gicc_t * gicc = gic_get_gicc(); - return gicc->IAR; -} - -void gic_write_end_of_irq(uint32_t irqID) -{ - gicc_t * gicc = gic_get_gicc(); - gicc->EOIR = irqID; -} - -void gic_init(void) -{ - gicd_t * gicd = gic_get_gicd(); - - // First disable the distributor. - gic_enable(false); - - // Clear all pending interrupts. - int i; - for (i = 0; i < 32; ++i) - { - gicd->ICPENDRn[i] = 0xffffffff; - } - - // Set all interrupts to secure. - for (i = 0; i < 8; ++i) - { - gicd->IGROUPRn[i] = 0; - } - - // Init the GIC CPU interface. - gic_init_cpu(); - - // Now enable the distributor. - gic_enable(true); -} - -void gic_init_cpu(void) -{ - // Init the GIC CPU interface. - gic_set_cpu_priority_mask(0xff); - - // Disable preemption. - gicc_t * gicc = gic_get_gicc(); - gicc->BPR = 7; - - // Enable signaling the CPU. - gic_cpu_enable(true); -} - -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.c b/bsp/imx6ul/platform/cpu/mmu.c deleted file mode 100644 index 0cf20c9942..0000000000 --- a/bsp/imx6ul/platform/cpu/mmu.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*! - * @file mmu.c - * @brief System memory arangement. - */ -#include "cortex_a.h" -#include "mmu.h" -#include "arm_cp_registers.h" - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Size in bytes of the first-level page table. -#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024) - -//! @brief First-level 1MB section descriptor entry. -typedef union mmu_l1_section { - uint32_t u; - struct { - uint32_t id:2; //!< ID - uint32_t b:1; //!< Bufferable - uint32_t c:1; //!< Cacheable - uint32_t xn:1; //!< Execute-not - uint32_t domain:4; //!< Domain - uint32_t _impl_defined:1; //!< Implementation defined, should be zero. - uint32_t ap1_0:2; //!< Access permissions AP[1:0] - uint32_t tex:3; //!< TEX remap - uint32_t ap2:1; //!< Access permissions AP[2] - uint32_t s:1; //!< Shareable - uint32_t ng:1; //!< Not-global - uint32_t _zero:1; //!< Should be zero. - uint32_t ns:1; //!< Non-secure - uint32_t address:12; //!< Physical base address - }; -} mmu_l1_section_t; - -enum { - kMMU_L1_Section_ID = 2, //!< ID value for a 1MB section first-level entry. - kMMU_L1_Section_Address_Shift = 20 //!< Bit offset of the physical base address field. -}; - -//////////////////////////////////////////////////////////////////////////////// -// Externs -//////////////////////////////////////////////////////////////////////////////// - -extern char __l1_page_table_start; - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -void mmu_enable() -{ - // invalidate all tlb - arm_unified_tlb_invalidate(); - - // read SCTLR - uint32_t sctlr; - _ARM_MRC(15, 0, sctlr, 1, 0, 0); - - // set MMU enable bit - sctlr |= BM_SCTLR_M; - - // write modified SCTLR - _ARM_MCR(15, 0, sctlr, 1, 0, 0); -} - -void mmu_disable() -{ - // read current SCTLR - uint32_t sctlr; - _ARM_MRC(15, 0, sctlr, 1, 0, 0); - - // clear MMU enable bit - sctlr &=~ BM_SCTLR_M; - - // write modified SCTLR - _ARM_MCR(15, 0, sctlr, 1, 0, 0); -} - -void mmu_init() -{ - // Get the L1 page table base address. - uint32_t * table = (uint32_t *)&__l1_page_table_start; - uint32_t share_attr = kShareable; - - // write table address to TTBR0 - _ARM_MCR(15, 0, table, 2, 0, 0); - - // set Client mode for all Domains - uint32_t dacr = 0x55555555; - _ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, , c3, c0, 0 ; Write DACR - - // Clear the L1 table. - bzero(table, MMU_L1_PAGE_TABLE_SIZE); - - // Create default mappings. - mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals - mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM - mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals - - // Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable. - uint32_t actlr = 0x0; - _ARM_MRC(15, 0, actlr, 1, 0, 1); - if (actlr & BM_ACTLR_SMP) - { - share_attr = kShareable; - } - else - { - share_attr = kNonshareable; - } - -#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL) - mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR -#elif defined(CHIP_MX6SL) || defined(CHIP_MX6UL) - mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR -#else -#error Unknown chip type! -#endif -} - -void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access) -{ - register mmu_l1_section_t entry; - entry.u = 0; - - // Set constant attributes. - entry.id = kMMU_L1_Section_ID; - entry.xn = 0; // Allow execution - entry.domain = 0; // Domain 0 - entry.ng = 0; // Global - entry.ns = 0; // Secure - - // Set attributes based on the selected memory type. - switch (memoryType) - { - case kStronglyOrdered: - entry.c = 0; - entry.b = 0; - entry.tex = 0; - entry.s = 1; // Ignored - break; - case kDevice: - if (isShareable) - { - entry.c = 0; - entry.b = 1; - entry.tex = 0; - entry.s = 1; // Ignored - } - else - { - entry.c = 0; - entry.b = 0; - entry.tex = 2; - entry.s = 0; // Ignored - } - break; - case kOuterInner_WB_WA: - entry.c = 1; - entry.b = 1; - entry.tex = 1; - entry.s = isShareable; - break; - case kOuterInner_WT: - entry.c = 1; - entry.b = 0; - entry.tex = 0; - entry.s = isShareable; - break; - case kNoncacheable: - entry.c = 0; - entry.b = 0; - entry.tex = 1; - entry.s = isShareable; - break; - } - - // Set attributes from specified access mode. - switch (access) - { - case kNoAccess: - entry.ap2 = 0; - entry.ap1_0 = 0; - break; - case kROAccess: - entry.ap2 = 1; - entry.ap1_0 = 3; - break; - case kRWAccess: - entry.ap2 = 0; - entry.ap1_0 = 3; - break; - } - - // Get the L1 page table base address. - uint32_t * table = (uint32_t *)&__l1_page_table_start; - - // Convert addresses to 12-bit bases. - uint32_t vbase = va >> kMMU_L1_Section_Address_Shift; - uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift; - uint32_t entries = length >> kMMU_L1_Section_Address_Shift; - - // Fill in L1 page table entries. - for (; entries > 0; ++pbase, ++vbase, --entries) - { - entry.address = pbase; - table[vbase] = entry.u; - } - - // Invalidate TLB - arm_unified_tlb_invalidate(); -} - -bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress) -{ - uint32_t pa = 0; - - // VA to PA translation with privileged read permission check - _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0); - - // Read PA register - _ARM_MRC(15, 0, pa, 7, 4, 0); - - // First bit of returned value is Result of conversion (0 is successful translation) - if (pa & 1) - { - // We can try write permission also - // VA to PA translation with privileged write permission check - _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1); - - // Read PA register - _ARM_MRC(15, 0, pa, 7, 4, 0); - - // First bit of returned value is Result of conversion (0 is successful translation) - if (pa & 1) - { - return false; - } - } - - if (physicalAddress) - { - // complete address returning base + offset - pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff); - *physicalAddress = pa; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.h b/bsp/imx6ul/platform/cpu/mmu.h deleted file mode 100644 index 961c17f541..0000000000 --- a/bsp/imx6ul/platform/cpu/mmu.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//! @addtogroup diag_mmu -//! @{ - -/*! - * @file mmu.h - * @brief System memory arrangement. - */ - -#ifndef _MMU_H_ -#define _MMU_H_ - -#include "sdk.h" - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Memory region attributes. -typedef enum _mmu_memory_type -{ - kStronglyOrdered, - kDevice, - kOuterInner_WB_WA, - kOuterInner_WT, - kNoncacheable, -} mmu_memory_type_t; - -//! @brief Memory region shareability options. -typedef enum _mmu_shareability -{ - kShareable = 1, - kNonshareable = 0 -} mmu_shareability_t; - -//! @brief Access permissions for a memory region. -typedef enum _mmu_access -{ - kNoAccess, - kROAccess, - kRWAccess -} mmu_access_t; - -//////////////////////////////////////////////////////////////////////////////// -// Prototypes -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @brief Enable the MMU. - * - * The L1 page tables and MMU settings must have already been configured by - * calling mmu_init() before the MMU is enabled. - */ -void mmu_enable(); - -/*! - * @brief Disable the MMU. - */ -void mmu_disable(); - -/*! - * @brief Set up the default first-level page table. - * - * Initializes the L1 page table with the following regions: - * - 0x00000000...0x00900000 : ROM and peripherals, strongly-ordered - * - 0x00900000...0x00a00000 : OCRAM, strongly-ordered - * - For MX6DQ or MX6SDL: 0x10000000...0x90000000 : DDR, normal, outer inner, write-back, write-allocate - * - For MX6SL: 0x80000000...0xc0000000 : DDR, normal, outer inner, write-back, write-allocate - * - * If the CPU is participating in SMP, then the DDR regions are made shareable. Otherwise they - * are marked as non-shareable. - * - * The TTBR0 register is set to the base of the L1 table. - * - * All memory domains are configured to allow client access. However, note that only domain 0 is - * used by mmu_map_l1_range(). - */ -void mmu_init(); - -/*! - * @brief Maps a range of memory in the first-level page table. - * - * Entries in the first-level page table are filled in for the range of virtual addresses - * starting at @a va and continuing for @a length bytes. These virtual addreses are mapped - * to the physical addresses starting at @a pa and continuing for @a length bytes. All table - * entries for the range of mapped memory have the same attributes, which are selected with - * the @a memoryType, @a isShareable, and @a access parameters. - * - * @param pa The base physical address of the range to which the virtual address will be mapped. - * @param va The base virtual address of the range. - * @param length The size of the range to be mapped, in bytes. This value must be divisible by 1MB. - * @param memoryType The type of the memory region. This controls caching, buffering, ordering of - * memory accesses, and other attributes of the region. - * @param isShareable The shareability of the physical memory. Ignored for strongly-ordered memory. - * @param access Access permissions. - */ -void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access); - -/*! - * @brief Convert virtual address to physical. - * - * First attempts a priviledged read translation for the current security mode. If that fails, - * a priviledged write translation, also for the current security mode, is attempted. If this - * second attempt at translation fails, then false will be returned. - * - * @param virtualAddress Virtual address to convert to a physical address. - * @param[out] physicalAddress This parameter is filled in with the physical address corresponding - * to the virtual address passed in @a virtualAddress. - * @retval true The address returned through @a physicalAddress is valid. - * @retval false The conversion failed for some reason. - */ -bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress); - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif // _MMU_H_ -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// - diff --git a/bsp/imx6ul/platform/cpu/platform.h b/bsp/imx6ul/platform/cpu/platform.h new file mode 100644 index 0000000000..f6a3995bc5 --- /dev/null +++ b/bsp/imx6ul/platform/cpu/platform.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-03-22 quanzhao first version + */ +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#include +#include + +/* SOC-relative definitions */ +//#include "realview.h" +#include "gic_registers.h" +#include "irq_numbers.h" + +/* the maximum number of gic */ +# define ARM_GIC_MAX_NR 1 + +/* the maximum number of interrupts */ +#define ARM_GIC_NR_IRQS IMX_INTERRUPT_COUNT + +/* the maximum entries of the interrupt table */ +#define MAX_HANDLERS IMX_INTERRUPT_COUNT + +/* the basic constants needed by gic */ +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ + rt_uint32_t gic_base; + asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base)); + return gic_base + kGICDBaseOffset; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ + rt_uint32_t gic_base; + asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base)); + return gic_base + kGICCBaseOffset; +} + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + +/* the definition needed by gic.c */ +#define __REG32(x) (*((volatile unsigned int *)(x))) + +/* keep compatible with platform SDK */ +typedef enum { + CPU_0, + CPU_1, + CPU_2, + CPU_3, +} cpuid_e; + +enum _gicd_sgi_filter +{ + //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. + kGicSgiFilter_UseTargetList = 0, + + //! Forward the interrupt to all CPU interfaces except that of the processor that requested + //! the interrupt. + kGicSgiFilter_AllOtherCPUs = 1, + + //! Forward the interrupt only to the CPU interface of the processor that requested the + //! interrupt. + kGicSgiFilter_OnlyThisCPU = 2 +}; + +typedef void (*irq_hdlr_t) (void); + +extern void rt_hw_interrupt_mask(int vector); +extern void rt_hw_interrupt_umask(int vector); +extern rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +rt_inline void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr) +{ + rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown"); +} + +rt_inline void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority) +{ + rt_hw_interrupt_umask(irq_id); +} + +rt_inline void disable_interrupt(uint32_t irq_id, uint32_t cpu_id) +{ + rt_hw_interrupt_mask(irq_id); +} + +#endif /* __PLATFORM_H__ */ diff --git a/bsp/imx6ul/platform/include/gic.h b/bsp/imx6ul/platform/include/gic.h deleted file mode 100644 index f3eee8499c..0000000000 --- a/bsp/imx6ul/platform/include/gic.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2011-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __GIC_H__ -#define __GIC_H__ - -#include "sdk_types.h" - -//! @addtogroup gic -//! @{ - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Options for sending a software generated interrupt. -//! -//! These options are used for the @a filter_list parameter of the gic_send_sgi() -//! function. They control how to select which CPUs that the interrupt is -//! sent to. -enum _gicd_sgi_filter -{ - //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. - kGicSgiFilter_UseTargetList = 0, - - //! Forward the interrupt to all CPU interfaces except that of the processor that requested - //! the interrupt. - kGicSgiFilter_AllOtherCPUs = 1, - - //! Forward the interrupt only to the CPU interface of the processor that requested the - //! interrupt. - kGicSgiFilter_OnlyThisCPU = 2 -}; - -//////////////////////////////////////////////////////////////////////////////// -// API -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -//! @name Initialization -//@{ -//! @brief Init interrupt handling. -//! -//! This function is intended to be called only by the primary CPU init code, so it will -//! only be called once during system bootup. -//! -//! Also inits the current CPU. You don't need to call gic_init_cpu() separately. -//! -//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts -//! that were pending are cleared, and all interrupts are made secure (group 0). -void gic_init(void); - -//! @brief Init the current CPU's GIC interface. -//! -//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption -//! is disabled by setting the Binary Point to a value of 7. -void gic_init_cpu(void); -//@} - -//! @name GIC Interrupt Distributor Functions -//@{ -//! @brief Enable or disable the GIC Distributor. -//! -//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure -//! (group 1) interrupts to the CPU interfaces. -//! -//! @param enableIt Pass true to enable or false to disable. -void gic_enable(bool enableIt); - -//! @brief Set the security mode for an interrupt. -//! -//! @param irqID The interrupt number. -//! @param isSecure Whether the interrupt is taken to secure mode. -void gic_set_irq_security(uint32_t irqID, bool isSecure); - -//! @brief Enable or disable an interrupt. -//! -//! @param irqID The number of the interrupt to control. -//! @param isEnabled Pass true to enable or false to disable. -void gic_enable_irq(uint32_t irqID, bool isEnabled); - -//! @brief Set whether a CPU will receive a particular interrupt. -//! -//! @param irqID The interrupt number. -//! @param cpuNumber The CPU number. The first CPU core is 0. -//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable -//! or false to disable. -void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt); - -//! @brief Set an interrupt's priority. -//! -//! @param irq_id The interrupt number. -//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with -//! 0 being the highest priority. -void gic_set_irq_priority(uint32_t irq_id, uint32_t priority); - -//! @brief Send a software generated interrupt to a specific CPU. -//! -//! @param irq_id The interrupt number to send. -//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded. -//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt -//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list -//! is set to #kGicSgiFilter_UseTargetList. -//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected -//! option determines which CPUs the interrupt will be sent to. If the value -//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used. -void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list); -//@} - -//! @name GIC CPU Interface Functions -//@{ -//! @brief Enable or disable the interface to the GIC for the current CPU. -//! -//! @param enableIt Pass true to enable or false to disable. -void gic_cpu_enable(bool enableIt); - -//! @brief Set the mask of which interrupt priorities the CPU will receive. -//! -//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to -//! allow all priority interrupts to signal the CPU. -void gic_set_cpu_priority_mask(uint32_t priority); - -//! @brief Acknowledge starting of interrupt handling and get the interrupt number. -//! -//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC -//! that you are starting to handle an interupt, and returns the number of the interrupt you -//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq() -//! to signal that the interrupt is completely handled. -//! -//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles -//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated -//! but nothing else. -//! -//! @return The number for the highest priority interrupt available for the calling CPU. If -//! the return value is 1022 or 1023, a spurious interrupt has occurred. -uint32_t gic_read_irq_ack(void); - -//! @brief Signal the end of handling an interrupt. -//! -//! @param irq_id The number of the interrupt for which handling has finished. -void gic_write_end_of_irq(uint32_t irq_id); -//@} - - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif // __GIC_H__ -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/include/interrupt.h b/bsp/imx6ul/platform/include/interrupt.h deleted file mode 100644 index 318e34f3bd..0000000000 --- a/bsp/imx6ul/platform/include/interrupt.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2009-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#include "sdk_types.h" -#include "irq_numbers.h" - -//! @addtogroup diag_interrupt -//! @{ - -/*! - * @file interrupt.h - * @brief Interface for the interrupt manager. - */ - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief -typedef enum { - CPU_0, - CPU_1, - CPU_2, - CPU_3, -} cpuid_e; - -//! @brief Interrupt service routine. -typedef void (*irq_hdlr_t) (void); - -//////////////////////////////////////////////////////////////////////////////// -// API -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -//! @brief Enable an interrupt. -//! -//! Sets the interrupt priority and makes it non-secure. Then the interrupt is -//! enabled on the CPU specified by @a cpu_id. -//! -//! @param irq_id The interrupt number to enable. -//! @param cpu_id The index of the CPU for which the interrupt will be enabled. -//! @param priority The interrupt priority, from 0-255. Lower numbers have higher priority. -void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority); - -//! @brief Disable an interrupt on the specified CPU. -//! -//! @param irq_id The interrupt number to disabled. -//! @param cpu_id The index of the CPU for which the interrupt will be disabled. -void disable_interrupt(uint32_t irq_id, uint32_t cpu_id); - -//! @brief Set the interrupt service routine for the specified interrupt. -//! -//! @param irq_id The interrupt number. -//! @param isr Function that will be called to handle the interrupt. -void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr); - -//! @brief Interrupt handler that simply prints a message. -void default_interrupt_routine(void); - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/rtconfig.py b/bsp/imx6ul/rtconfig.py index 2c08665920..0a9ea3dce3 100644 --- a/bsp/imx6ul/rtconfig.py +++ b/bsp/imx6ul/rtconfig.py @@ -10,7 +10,7 @@ if os.getenv('RTT_CC'): # only support GNU GCC compiler. PLATFORM = 'gcc' -EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin' +EXEC_PATH = '/usr/bin' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index c8814d366a..6fde000858 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -322,6 +322,7 @@ CONFIG_RT_USING_LWP=y # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_CJSON is not set # CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set diff --git a/bsp/qemu-vexpress-a9/SConstruct b/bsp/qemu-vexpress-a9/SConstruct index 638311d697..d618790dec 100644 --- a/bsp/qemu-vexpress-a9/SConstruct +++ b/bsp/qemu-vexpress-a9/SConstruct @@ -5,7 +5,7 @@ import rtconfig if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + RTT_ROOT = os.path.join(os.getcwd(), '..', '..') sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] from building import * @@ -25,7 +25,7 @@ Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) +objs = PrepareBuilding(env, RTT_ROOT) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/qemu-vexpress-a9/cpu/SConscript b/bsp/qemu-vexpress-a9/cpu/SConscript deleted file mode 100644 index b45f95cc1a..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -Import('rtconfig') -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') -CPPPATH = [cwd] - -if rtconfig.PLATFORM == 'iar': - src += Glob('*_iar.S') -elif rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') -elif rtconfig.PLATFORM == 'armcc': - src += Glob('*_rvds.S') - -group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/qemu-vexpress-a9/cpu/armv7.h b/bsp/qemu-vexpress-a9/cpu/armv7.h deleted file mode 100644 index 69c556eb3c..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/armv7.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __ARMV7_H__ -#define __ARMV7_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/context_gcc.S b/bsp/qemu-vexpress-a9/cpu/context_gcc.S deleted file mode 100644 index 0aad0200d5..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/context_gcc.S +++ /dev/null @@ -1,198 +0,0 @@ -/* - * File : context.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-05 Bernard the first version - * 2018-11-22 Jesven in the smp version, using macro to - * define rt_hw_interrupt_enable and rt_hw_interrupt_disable - * rt_hw_context_switch_interrupt switches to the new thread directly - */ - -#include "rtconfig.h" -.section .text, "ax" - -#ifdef RT_USING_SMP -#define rt_hw_interrupt_disable rt_hw_local_irq_disable -#define rt_hw_interrupt_enable rt_hw_local_irq_enable -#endif - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable -rt_hw_interrupt_disable: - mrs r0, cpsr - cpsid i - bx lr - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.globl rt_hw_interrupt_enable -rt_hw_interrupt_enable: - msr cpsr, r0 - bx lr - -/* - * void rt_hw_context_switch_to(rt_uint32 to); - * r0 --> to - */ -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - ldr sp, [r0] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r1 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc - -.section .bss.share.isr -_guest_switch_lvl: - .word 0 - -.section .text.isr, "ax" -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); - * r0 --> from - * r1 --> to - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - tst lr, #0x01 - orrne r4, r4, #0x20 @ it's thumb code - - stmfd sp!, {r4} @ push cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @ push usr_sp usr_lr - sub sp, #8 -#endif - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r2 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task cpsr to spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr - -/* - * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); - */ -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: -#ifdef RT_USING_SMP - /* r0 :irq_mod context - * r1 :addr of from_thread's sp - * r2 :addr of to_thread's sp - * r3 :to_thread's tcb - */ - - @ r0 point to {r0-r3} in stack - push {r1 - r3} - mov r1, r0 - add r0, r0, #4*4 - ldmfd r0!, {r4-r12,lr}@ reload saved registers - mrs r3, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r4-r7} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r4-r7} @ push old task's r0-r3 - stmfd sp!, {r3} @ push old task's cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13,r14}^ @push usr_sp usr_lr - sub sp, #8 -#endif - - msr cpsr_c, #I_Bit|F_Bit|Mode_IRQ - pop {r1 - r3} - mov sp, r0 - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - str sp, [r1] - - ldr sp, [r2] - mov r0, r3 - bl rt_cpus_lock_status_restore - -#ifdef RT_USING_LWP - ldmfd sp, {r13,r14}^ @pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -#else /*RT_USING_SMP*/ - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] - cmp r3, #1 - beq _reswitch - ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread - mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r0, [ip] - str r3, [r2] -_reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] - bx lr -#endif /*RT_USING_SMP*/ diff --git a/bsp/qemu-vexpress-a9/cpu/cp15.h b/bsp/qemu-vexpress-a9/cpu/cp15.h deleted file mode 100644 index ebea3f0fe3..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __CP15_H__ -#define __CP15_H__ - -unsigned long rt_cpu_get_smp_id(void); - -void rt_cpu_mmu_disable(void); -void rt_cpu_mmu_enable(void); -void rt_cpu_tlb_set(volatile unsigned long*); - -void rt_cpu_vector_set_base(unsigned int addr); - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S b/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S deleted file mode 100644 index f1ed6492aa..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S +++ /dev/null @@ -1,140 +0,0 @@ -/* - * File : cp15_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * http://www.rt-thread.org - * - * 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 - * 2013-07-05 Bernard the first version - */ - -.globl rt_cpu_get_smp_id -rt_cpu_get_smp_id: - mrc p15, #0, r0, c0, c0, #5 - bx lr - -.globl rt_cpu_vector_set_base -rt_cpu_vector_set_base: - mcr p15, #0, r0, c12, c0, #0 - dsb - bx lr - -.globl rt_hw_cpu_dcache_enable -rt_hw_cpu_dcache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_hw_cpu_icache_enable -rt_hw_cpu_icache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -_FLD_MAX_WAY: - .word 0x3ff -_FLD_MAX_IDX: - .word 0x7ff - -.globl rt_cpu_dcache_clean_flush -rt_cpu_dcache_clean_flush: - push {r4-r11} - dmb - mrc p15, #1, r0, c0, c0, #1 @ read clid register - ands r3, r0, #0x7000000 @ get level of coherency - mov r3, r3, lsr #23 - beq finished - mov r10, #0 -loop1: - add r2, r10, r10, lsr #1 - mov r1, r0, lsr r2 - and r1, r1, #7 - cmp r1, #2 - blt skip - mcr p15, #2, r10, c0, c0, #0 - isb - mrc p15, #1, r1, c0, c0, #0 - and r2, r1, #7 - add r2, r2, #4 - ldr r4, _FLD_MAX_WAY - ands r4, r4, r1, lsr #3 - clz r5, r4 - ldr r7, _FLD_MAX_IDX - ands r7, r7, r1, lsr #13 -loop2: - mov r9, r4 -loop3: - orr r11, r10, r9, lsl r5 - orr r11, r11, r7, lsl r2 - mcr p15, #0, r11, c7, c14, #2 - subs r9, r9, #1 - bge loop3 - subs r7, r7, #1 - bge loop2 -skip: - add r10, r10, #2 - cmp r3, r10 - bgt loop1 - -finished: - dsb - isb - pop {r4-r11} - bx lr - -.globl rt_hw_cpu_dcache_disable -rt_hw_cpu_dcache_disable: - push {r4-r11, lr} - bl rt_cpu_dcache_clean_flush - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - pop {r4-r11, lr} - bx lr - -.globl rt_hw_cpu_icache_disable -rt_hw_cpu_icache_disable: - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_cpu_mmu_disable -rt_cpu_mmu_disable: - mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #1 - mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit - dsb - bx lr - -.globl rt_cpu_mmu_enable -rt_cpu_mmu_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x001 - mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit - dsb - bx lr - -.globl rt_cpu_tlb_set -rt_cpu_tlb_set: - mcr p15, #0, r0, c2, c0, #0 - dmb - bx lr diff --git a/bsp/qemu-vexpress-a9/cpu/cpuport.c b/bsp/qemu-vexpress-a9/cpu/cpuport.c deleted file mode 100644 index 6b129f89ee..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cpuport.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - * 2018-11-22 Jesven add rt_hw_cpu_id() - */ - -#include -#include -#include - -#ifdef RT_USING_SMP -int rt_hw_cpu_id(void) -{ - int cpu_id; - __asm__ volatile ( - "mrc p15, 0, %0, c0, c0, 5" - :"=r"(cpu_id) - ); - cpu_id &= 0xf; - return cpu_id; -}; - -void rt_hw_spin_lock(rt_hw_spinlock_t *lock) -{ - unsigned long tmp; - unsigned long newval; - rt_hw_spinlock_t lockval; - - __asm__ __volatile__( - "pld [%0]" - ::"r"(&lock->slock) - ); - - __asm__ __volatile__( - "1: ldrex %0, [%3]\n" - " add %1, %0, %4\n" - " strex %2, %1, [%3]\n" - " teq %2, #0\n" - " bne 1b" - : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) - : "r" (&lock->slock), "I" (1 << 16) - : "cc"); - - while (lockval.tickets.next != lockval.tickets.owner) { - __asm__ __volatile__("wfe":::"memory"); - lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); - } - - __asm__ volatile ("dmb":::"memory"); -} - -void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) -{ - __asm__ volatile ("dmb":::"memory"); - lock->tickets.owner++; - __asm__ volatile ("dsb ishst\nsev":::"memory"); -} -#endif /*RT_USING_SMP*/ - -/** - * @addtogroup ARM CPU - */ -/*@{*/ - -/** shutdown CPU */ -void rt_hw_cpu_shutdown() -{ - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/gic.c b/bsp/qemu-vexpress-a9/cpu/gic.c deleted file mode 100644 index 66876518ce..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/gic.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * File : gic.c, ARM Generic Interrupt Controller - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, 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 - * 2013-07-20 Bernard first version - * 2014-04-03 Grissiom many enhancements - * 2018-11-22 Jesven add rt_hw_ipi_send() - * add rt_hw_ipi_handler_install() - */ - -#include -#include -#include - -#include "gic.h" -#include "cp15.h" - -struct arm_gic -{ - rt_uint32_t offset; - - rt_uint32_t dist_hw_base; - rt_uint32_t cpu_hw_base; -}; -static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; - -#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00) -#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04) -#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08) -#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c) -#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10) -#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14) -#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18) - -#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000) -#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004) -#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4) -#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4) -#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4) -#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380 + ((n)/32) * 4) -#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4) -#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4) -#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4) -#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00) -#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10 + ((n)/4) * 4) -#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8) - -static unsigned int _gic_max_irq; - -int arm_gic_get_active_irq(rt_uint32_t index) -{ - int irq; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base); - irq += _gic_table[index].offset; - return irq; -} - -void arm_gic_ack(rt_uint32_t index, int irq) -{ - rt_uint32_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; - GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_mask(rt_uint32_t index, int irq) -{ - rt_uint32_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_clear_pending(rt_uint32_t index, int irq) -{ - rt_uint32_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_clear_active(rt_uint32_t index, int irq) -{ - rt_uint32_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) -{ - rt_uint32_t old_tgt; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); - - old_tgt &= ~(0x0FFUL << ((irq % 4)*8)); - old_tgt |= cpumask << ((irq % 4)*8); - - GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; -} - -void arm_gic_umask(rt_uint32_t index, int irq) -{ - rt_uint32_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_dump_type(rt_uint32_t index) -{ - unsigned int gic_type; - - gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); - rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", - (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, - _gic_table[index].dist_hw_base, - _gic_max_irq, - gic_type & (1 << 10) ? "has" : "no", - gic_type); -} - -void arm_gic_dump(rt_uint32_t index) -{ - unsigned int i, k; - - k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); - rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); - rt_kprintf("--- hw mask ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n--- hw pending ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n--- hw active ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n"); -} -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT_ALIAS(arm_gic_dump, gic, show gic status); -#endif - -int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) -{ - unsigned int gic_type, i; - rt_uint32_t cpumask = 1 << 0; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - _gic_table[index].dist_hw_base = dist_base; - _gic_table[index].offset = irq_start; - - /* Find out how many interrupts are supported. */ - gic_type = GIC_DIST_TYPE(dist_base); - _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; - - /* - * The GIC only supports up to 1020 interrupt sources. - * Limit this to either the architected maximum, or the - * platform maximum. - */ - if (_gic_max_irq > 1020) - _gic_max_irq = 1020; - if (_gic_max_irq > ARM_GIC_NR_IRQS) - _gic_max_irq = ARM_GIC_NR_IRQS; - - cpumask |= cpumask << 8; - cpumask |= cpumask << 16; - - GIC_DIST_CTRL(dist_base) = 0x0; - - /* Set all global interrupts to be level triggered, active low. */ - for (i = 32; i < _gic_max_irq; i += 16) - GIC_DIST_CONFIG(dist_base, i) = 0x0; - - /* Set all global interrupts to this CPU only. */ - for (i = 32; i < _gic_max_irq; i += 4) - GIC_DIST_TARGET(dist_base, i) = cpumask; - - /* Set priority on all interrupts. */ - for (i = 0; i < _gic_max_irq; i += 4) - GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; - - /* Disable all interrupts. */ - for (i = 0; i < _gic_max_irq; i += 32) - GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; - -#if 0 - /* All interrupts defaults to IGROUP1(IRQ). */ - for (i = 0; i < _gic_max_irq; i += 32) - GIC_DIST_IGROUP(dist_base, i) = 0xffffffff; -#endif - - /* Enable group0 and group1 interrupt forwarding. */ - GIC_DIST_CTRL(dist_base) = 0x03; - - return 0; -} - -int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - _gic_table[index].cpu_hw_base = cpu_base; - - GIC_CPU_PRIMASK(cpu_base) = 0xf0; - /* Enable CPU interrupt */ - GIC_CPU_CTRL(cpu_base) = 0x01; - - return 0; -} - -void arm_gic_set_group(rt_uint32_t index, int vector, int group) -{ - /* As for GICv2, there are only group0 and group1. */ - RT_ASSERT(group <= 1); - RT_ASSERT(vector < _gic_max_irq); - - if (group == 0) - { - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, - vector) &= ~(1 << (vector % 32)); - } - else if (group == 1) - { - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, - vector) |= (1 << (vector % 32)); - } -} - -#ifdef RT_USING_SMP -void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) - { - /* note: ipi_vector maybe different with irq_vector */ - GIC_DIST_SOFTINT(_gic_table[0].dist_hw_base) = (cpu_mask << 16) | ipi_vector; -} -#endif - -#ifdef RT_USING_SMP -void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) -{ - /* note: ipi_vector maybe different with irq_vector */ - rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); -} -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/gic.h b/bsp/qemu-vexpress-a9/cpu/gic.h deleted file mode 100644 index 9d0368ec94..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/gic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * File : gic.h, ARM Generic Interrupt Controller - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-20 Bernard first version - */ - -#ifndef __GIC_H__ -#define __GIC_H__ - -int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); -int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base); - -void arm_gic_mask(rt_uint32_t index, int irq); -void arm_gic_umask(rt_uint32_t index, int irq); -void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); -void arm_gic_set_group(rt_uint32_t index, int vector, int group); - -int arm_gic_get_active_irq(rt_uint32_t index); -void arm_gic_ack(rt_uint32_t index, int irq); - -void arm_gic_dump_type(rt_uint32_t index); -void rt_hw_vector_init(void); - -#endif - diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.c b/bsp/qemu-vexpress-a9/cpu/interrupt.c deleted file mode 100644 index d7e9ec08fa..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * File : interrupt.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard first version - * 2018-11-22 Jesven add smp support - */ - -#include -#include -#include "realview.h" -#include "gic.h" - -#define MAX_HANDLERS NR_IRQS_PBA8 - -/* exception and interrupt handler table */ -struct rt_irq_desc isr_table[MAX_HANDLERS]; - -#ifndef RT_USING_SMP -/* Those varibles will be accessed in ISR, so we need to share them. */ -rt_uint32_t rt_interrupt_from_thread = 0; -rt_uint32_t rt_interrupt_to_thread = 0; -rt_uint32_t rt_thread_switch_interrupt_flag = 0; -#endif - -const unsigned int VECTOR_BASE = 0x00; -extern void rt_cpu_vector_set_base(unsigned int addr); -extern int system_vectors; - -void rt_hw_vector_init(void) -{ - rt_cpu_vector_set_base((unsigned int)&system_vectors); -} - -/** - * This function will initialize hardware interrupt - */ -void rt_hw_interrupt_init(void) -{ - rt_uint32_t gic_cpu_base; - rt_uint32_t gic_dist_base; - - /* initialize vector table */ - rt_hw_vector_init(); - - /* initialize exceptions table */ - rt_memset(isr_table, 0x00, sizeof(isr_table)); - - /* initialize ARM GIC */ - gic_dist_base = REALVIEW_GIC_DIST_BASE; - gic_cpu_base = REALVIEW_GIC_CPU_BASE; - - arm_gic_dist_init(0, gic_dist_base, 0); - arm_gic_cpu_init(0, gic_cpu_base); -} - -/** - * This function will mask a interrupt. - * @param vector the interrupt number - */ -void rt_hw_interrupt_mask(int vector) -{ - arm_gic_mask(0, vector); -} - -/** - * This function will un-mask a interrupt. - * @param vector the interrupt number - */ -void rt_hw_interrupt_umask(int vector) -{ - arm_gic_umask(0, vector); -} - -/** - * This function will install a interrupt service routine to a interrupt. - * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine - */ -rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name) -{ - rt_isr_handler_t old_handler = RT_NULL; - - if (vector < MAX_HANDLERS) - { - old_handler = isr_table[vector].handler; - - if (handler != RT_NULL) - { -#ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); -#endif /* RT_USING_INTERRUPT_INFO */ - isr_table[vector].handler = handler; - isr_table[vector].param = param; - } - } - - return old_handler; -} diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.h b/bsp/qemu-vexpress-a9/cpu/interrupt.h deleted file mode 100644 index 045246b21d..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * File : interrupt.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard first version - */ - -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -void rt_hw_interrupt_control(int vector, int priority, int route); - -void rt_hw_interrupt_init(void); - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/mmu.c b/bsp/qemu-vexpress-a9/cpu/mmu.c deleted file mode 100644 index b2503e4260..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/mmu.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * File : mmu.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2012-01-10 bernard porting to AM1808 - */ - -#include -#include -#include - -#include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO -#define XN (1<<4) // eXecute Never - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) - -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) - -/* dump 2nd level page table */ -void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - for (i = 0; i < 256; i++) - { - rt_uint32_t pte2 = ptb[i]; - if ((pte2 & 0x3) == 0) - { - if (fcnt == 0) - rt_kprintf(" "); - rt_kprintf("%04x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf(" %04x: %x: ", i, pte2); - if ((pte2 & 0x3) == 0x1) - { - rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, - (pte2 >> 15) & 0x1, - ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); - } - else - { - rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, - ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); - } - } -} - -void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - rt_kprintf("page table@%p\n", ptb); - for (i = 0; i < 1024*4; i++) - { - rt_uint32_t pte1 = ptb[i]; - if ((pte1 & 0x3) == 0) - { - rt_kprintf("%03x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf("%03x: %08x: ", i, pte1); - if ((pte1 & 0x3) == 0x3) - { - rt_kprintf("LPAE\n"); - } - else if ((pte1 & 0x3) == 0x1) - { - rt_kprintf("pte,ns:%d,domain:%d\n", - (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); - /* - *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) - * - 0x80000000 + 0xC0000000)); - */ - } - else if (pte1 & (1 << 18)) - { - rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); - } - else - { - rt_kprintf("section,ns:%d,ap:%x," - "xn:%d,texcb:%02x,domain:%d\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - (((pte1 & (0x7 << 12)) >> 10) | - ((pte1 & 0x0c) >> 2)) & 0x1f, - (pte1 >> 5) & 0xf); - } - } -} - -/* level1 page table, each entry for 1MB memory. */ -volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); -void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, - rt_uint32_t vaddrEnd, - rt_uint32_t paddrStart, - rt_uint32_t attr) -{ - volatile rt_uint32_t *pTT; - volatile int i, nSec; - pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); - nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); - for(i = 0; i <= nSec; i++) - { - *pTT = attr | (((paddrStart >> 20) + i) << 20); - pTT++; - } -} - -unsigned long rt_hw_set_domain_register(unsigned long domain_val) -{ - unsigned long old_domain; - - asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); - asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); - - return old_domain; -} - -void rt_hw_mmu_init(void) -{ - rt_hw_cpu_dcache_disable(); - rt_hw_cpu_icache_disable(); - rt_cpu_mmu_disable(); - - /* set page table */ - /* 4G 1:1 memory */ - rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); - /* IO memory region */ - rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); - - /*rt_hw_cpu_dump_page_table(MMUTable);*/ - rt_hw_set_domain_register(0x55555555); - - rt_cpu_tlb_set(MMUTable); - - rt_cpu_mmu_enable(); - - rt_hw_cpu_icache_enable(); - rt_hw_cpu_dcache_enable(); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.c b/bsp/qemu-vexpress-a9/cpu/pmu.c deleted file mode 100644 index 07911a2db7..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "pmu.h" - -void rt_hw_pmu_dump_feature(void) -{ - unsigned long reg; - - reg = rt_hw_pmu_get_control(); - rt_kprintf("ARM PMU Implementor: %c, ID code: %02x, %d counters\n", - reg >> 24, (reg >> 16) & 0xff, (reg >> 11) & 0x1f); - RT_ASSERT(ARM_PMU_CNTER_NR == ((reg >> 11) & 0x1f)); -} diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.h b/bsp/qemu-vexpress-a9/cpu/pmu.h deleted file mode 100644 index 05c1420dd8..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __PMU_H__ -#define __PMU_H__ - -#include "board.h" - -/* Number of counters */ -#define ARM_PMU_CNTER_NR 4 - -enum rt_hw_pmu_event_type { - ARM_PMU_EVENT_PMNC_SW_INCR = 0x00, - ARM_PMU_EVENT_L1_ICACHE_REFILL = 0x01, - ARM_PMU_EVENT_ITLB_REFILL = 0x02, - ARM_PMU_EVENT_L1_DCACHE_REFILL = 0x03, - ARM_PMU_EVENT_L1_DCACHE_ACCESS = 0x04, - ARM_PMU_EVENT_DTLB_REFILL = 0x05, - ARM_PMU_EVENT_MEM_READ = 0x06, - ARM_PMU_EVENT_MEM_WRITE = 0x07, - ARM_PMU_EVENT_INSTR_EXECUTED = 0x08, - ARM_PMU_EVENT_EXC_TAKEN = 0x09, - ARM_PMU_EVENT_EXC_EXECUTED = 0x0A, - ARM_PMU_EVENT_CID_WRITE = 0x0B, -}; - -/* Enable bit */ -#define ARM_PMU_PMCR_E (0x01 << 0) -/* Event counter reset */ -#define ARM_PMU_PMCR_P (0x01 << 1) -/* Cycle counter reset */ -#define ARM_PMU_PMCR_C (0x01 << 2) -/* Cycle counter divider */ -#define ARM_PMU_PMCR_D (0x01 << 3) - -#ifdef __GNUC__ -rt_inline void rt_hw_pmu_enable_cnt(int divide64) -{ - unsigned long pmcr; - unsigned long pmcntenset; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_E | ARM_PMU_PMCR_P | ARM_PMU_PMCR_C; - if (divide64) - pmcr |= ARM_PMU_PMCR_D; - else - pmcr &= ~ARM_PMU_PMCR_D; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - - /* enable all the counters */ - pmcntenset = ~0; - asm volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r"(pmcntenset)); - /* clear overflows(just in case) */ - asm volatile ("mcr p15, 0, %0, c9, c12, 3" :: "r"(pmcntenset)); -} - -rt_inline unsigned long rt_hw_pmu_get_control(void) -{ - unsigned long pmcr; - asm ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - return pmcr; -} - -rt_inline unsigned long rt_hw_pmu_get_ceid(void) -{ - unsigned long reg; - /* only PMCEID0 is supported, PMCEID1 is RAZ. */ - asm ("mrc p15, 0, %0, c9, c12, 6" : "=r"(reg)); - return reg; -} - -rt_inline unsigned long rt_hw_pmu_get_cnten(void) -{ - unsigned long pmcnt; - asm ("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcnt)); - return pmcnt; -} - -rt_inline void rt_hw_pmu_reset_cycle(void) -{ - unsigned long pmcr; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_C; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - asm volatile ("isb"); -} - -rt_inline void rt_hw_pmu_reset_event(void) -{ - unsigned long pmcr; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_P; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - asm volatile ("isb"); -} - -rt_inline unsigned long rt_hw_pmu_get_cycle(void) -{ - unsigned long cyc; - asm volatile ("isb"); - asm volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cyc)); - return cyc; -} - -rt_inline void rt_hw_pmu_select_counter(int idx) -{ - RT_ASSERT(idx < ARM_PMU_CNTER_NR); - - asm volatile ("mcr p15, 0, %0, c9, c12, 5" : : "r"(idx)); - /* Linux add an isb here, don't know why here. */ - asm volatile ("isb"); -} - -rt_inline void rt_hw_pmu_select_event(int idx, - enum rt_hw_pmu_event_type eve) -{ - RT_ASSERT(idx < ARM_PMU_CNTER_NR); - - rt_hw_pmu_select_counter(idx); - asm volatile ("mcr p15, 0, %0, c9, c13, 1" : : "r"(eve)); -} - -rt_inline unsigned long rt_hw_pmu_read_counter(int idx) -{ - unsigned long reg; - - rt_hw_pmu_select_counter(idx); - asm volatile ("isb"); - asm volatile ("mrc p15, 0, %0, c9, c13, 2" : "=r"(reg)); - return reg; -} - -rt_inline unsigned long rt_hw_pmu_get_ovsr(void) -{ - unsigned long reg; - asm volatile ("isb"); - asm ("mrc p15, 0, %0, c9, c12, 3" : "=r"(reg)); - return reg; -} - -rt_inline void rt_hw_pmu_clear_ovsr(unsigned long reg) -{ - asm ("mcr p15, 0, %0, c9, c12, 3" : : "r"(reg)); - asm volatile ("isb"); -} - -#endif - -void rt_hw_pmu_dump_feature(void); - -#endif /* end of include guard: __PMU_H__ */ - diff --git a/bsp/qemu-vexpress-a9/cpu/stack.c b/bsp/qemu-vexpress-a9/cpu/stack.c deleted file mode 100644 index dfb97557bc..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/stack.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * File : stack.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-09-23 Bernard the first version - * 2011-10-05 Bernard add thumb mode - */ -#include -#include - -/** - * @addtogroup AM33xx - */ -/*@{*/ - -/** - * This function will initialize thread stack - * - * @param tentry the entry of thread - * @param parameter the parameter of entry - * @param stack_addr the beginning stack address - * @param texit the function will be called when thread exit - * - * @return stack address - */ -rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, - rt_uint8_t *stack_addr, void *texit) -{ - rt_uint32_t *stk; - - stack_addr += sizeof(rt_uint32_t); - stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t*)stack_addr; - *(--stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0; /* r12 */ - *(--stk) = 0; /* r11 */ - *(--stk) = 0; /* r10 */ - *(--stk) = 0; /* r9 */ - *(--stk) = 0; /* r8 */ - *(--stk) = 0; /* r7 */ - *(--stk) = 0; /* r6 */ - *(--stk) = 0; /* r5 */ - *(--stk) = 0; /* r4 */ - *(--stk) = 0; /* r3 */ - *(--stk) = 0; /* r2 */ - *(--stk) = 0; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - /* cpsr */ - if ((rt_uint32_t)tentry & 0x01) - *(--stk) = SVCMODE | 0x20; /* thumb mode */ - else - *(--stk) = SVCMODE; /* arm mode */ - -#ifdef RT_USING_LWP - *(--stk) = 0; /* user lr */ - *(--stk) = 0; /* user sp*/ -#endif - - /* return task's current stack address */ - return (rt_uint8_t *)stk; -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/start_gcc.S b/bsp/qemu-vexpress-a9/cpu/start_gcc.S deleted file mode 100644 index b71d8a1568..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/start_gcc.S +++ /dev/null @@ -1,447 +0,0 @@ -/* - * File : start_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, 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 - * 2013-07-05 Bernard the first version - * 2018-11-22 Jesven in the interrupt context, use rt_scheduler_do_irq_switch checks - * and switches to a new thread - */ - -#include "rtconfig.h" - -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.equ UND_Stack_Size, 0x00000000 -.equ SVC_Stack_Size, 0x00000400 -.equ ABT_Stack_Size, 0x00000000 -.equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000800 -.equ USR_Stack_Size, 0x00000400 - -#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) - -.section .data.share.isr -/* stack */ -.globl stack_start -.globl stack_top - -stack_start: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top: - -.text -/* reset entry */ -.globl _reset -_reset: - /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 - - mrc p15, 0, r1, c1, c0, 1 - mov r0, #(1<<6) - orr r1, r0 - mcr p15, 0, r1, c1, c0, 1 //enable smp - - ldr lr, =after_enable_mmu - ldr r0, =mtbl - b enable_mmu - -after_enable_mmu: - - /* setup stack */ - bl stack_setup - - /* clear .bss */ - mov r0,#0 /* get a zero */ - ldr r1,=__bss_start /* bss start */ - ldr r2,=__bss_end /* bss end */ - -bss_loop: - cmp r1,r2 /* check if data to clear */ - strlo r0,[r1],#4 /* clear 4 bytes */ - blo bss_loop /* loop until done */ - - /* call C++ constructors of global objects */ - ldr r0, =__ctors_start__ - ldr r1, =__ctors_end__ - -ctor_loop: - cmp r0, r1 - beq ctor_end - ldr r2, [r0], #4 - stmfd sp!, {r0-r1} - mov lr, pc - bx r2 - ldmfd sp!, {r0-r1} - b ctor_loop -ctor_end: - - /* start RT-Thread Kernel */ - bl flush_cache_all - ldr pc, _rtthread_startup -_rtthread_startup: - .word rtthread_startup - -stack_setup: - ldr r0, =stack_top - - @ Set the startup stack for svc - mov sp, r0 - - @ Enter Undefined Instruction Mode and set its Stack Pointer - msr cpsr_c, #Mode_UND|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #UND_Stack_Size - - @ Enter Abort Mode and set its Stack Pointer - msr cpsr_c, #Mode_ABT|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #ABT_Stack_Size - - @ Enter FIQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_FIQ_STACK_PGSZ - - @ Enter IRQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_IRQ_STACK_PGSZ - - /* come back to SVC mode */ - msr cpsr_c, #Mode_SVC|I_Bit|F_Bit - bx lr - - .global enable_mmu -enable_mmu: - orr r0, #0x18 - mcr p15, 0, r0, c2, c0, 0 @ttbr0 - - mov r0, #(1 << 5) @PD1=1 - mcr p15, 0, r0, c2, c0, 2 @ttbcr - - mov r0, #1 - mcr p15, 0, r0, c3, c0, 0 @dacr - - mov r0, #0 - mcr p15, 0, r0, c8, c7, 0 - mcr p15, 0, r0, c7, c5, 0 @iciallu - mcr p15, 0, r0, c7, c5, 6 @bpiall - - mrc p15, 0, r0, c1, c0, 0 - orr r0, #(1 | 4) - orr r0, #(1 << 12) - mcr p15, 0, r0, c1, c0, 0 - dsb - isb - mov pc, lr - -.global flush_cache_all -flush_cache_all: - stmfd sp!, {r0-r12, lr} - bl v7_flush_dcache_all - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - dsb - isb - ldmfd sp!, {r0-r12, lr} - mov pc, lr - - v7_flush_dcache_all: - dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished @ if loc is 0, then no need to clean - mov r10, #0 @ start clean at cache level 0 -loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache level - mov r1, r0, lsr r2 @ extract cache type bits from clidr - and r1, r1, #7 @ mask of the bits for current cache only - cmp r1, #2 @ see what cache we have at this level - blt skip @ skip if no cache, or just i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - isb @ isb to sych the new cssr&csidr - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the way size - clz r5, r4 @ find bit position of way size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the index size -loop2: - mov r9, r4 @ create working copy of max way size -loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge loop3 - subs r7, r7, #1 @ decrement the index - bge loop2 -skip: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt loop1 -finished: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - dsb - isb - mov pc, lr - -/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ -.section .text.isr, "ax" - .align 5 -.globl vector_fiq -vector_fiq: - stmfd sp!,{r0-r7,lr} - bl rt_hw_trap_fiq - ldmfd sp!,{r0-r7,lr} - subs pc, lr, #4 - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread - - .align 5 -.globl vector_irq -vector_irq: -#ifdef RT_USING_SMP - clrex -#endif - stmfd sp!, {r0-r12,lr} - - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - -#ifdef RT_USING_SMP - mov r0, sp - bl rt_scheduler_do_irq_switch - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 -#else - @ if rt_thread_switch_interrupt_flag set, jump to - @ rt_hw_context_switch_interrupt_do and don't return - ldr r0, =rt_thread_switch_interrupt_flag - ldr r1, [r0] - cmp r1, #1 - beq rt_hw_context_switch_interrupt_do - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 - -rt_hw_context_switch_interrupt_do: - mov r1, #0 @ clear flag - str r1, [r0] - - mov r1, sp @ r1 point to {r0-r3} in stack - add sp, sp, #4*4 - ldmfd sp!, {r4-r12,lr}@ reload saved registers - mrs r0, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - - @ Switch to SVC mode with no interrupt. If the usr mode guest is - @ interrupted, this will just switch to the stack of kernel space. - @ save the registers in kernel space won't trigger data abort. - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r1-r4} @ push old task's r0-r3 - stmfd sp!, {r0} @ push old task's cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @push usr_sp, usr_lr - sub sp, #8 -#endif - - ldr r4, =rt_interrupt_from_thread - ldr r5, [r4] - str sp, [r5] @ store sp in preempted tasks's TCB - - ldr r6, =rt_interrupt_to_thread - ldr r6, [r6] - ldr sp, [r6] @ get new task's stack pointer - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -#endif - -.macro push_svc_reg - sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ - stmia sp, {r0 - r12} @/* Calling r0-r12 */ - mov r0, sp - mrs r6, spsr @/* Save CPSR */ - str lr, [r0, #15*4] @/* Push PC */ - str r6, [r0, #16*4] @/* Push CPSR */ - cps #Mode_SVC - str sp, [r0, #13*4] @/* Save calling SP */ - str lr, [r0, #14*4] @/* Save calling PC */ -.endm - - .align 5 - .globl vector_swi -.weak SVC_Handler -SVC_Handler: -vector_swi: - push_svc_reg - bl rt_hw_trap_swi - b . - - .align 5 - .globl vector_undef -vector_undef: - push_svc_reg - bl rt_hw_trap_undef - b . - - .align 5 - .globl vector_pabt -vector_pabt: - push_svc_reg - bl rt_hw_trap_pabt - b . - - .align 5 - .globl vector_dabt -vector_dabt: - push_svc_reg - bl rt_hw_trap_dabt - b . - - .align 5 - .globl vector_resv -vector_resv: - push_svc_reg - bl rt_hw_trap_resv - b . - -#ifdef RT_USING_SMP -.global set_secondary_cpu_boot_address -set_secondary_cpu_boot_address: - ldr r0, =secondary_cpu_start - - mvn r1, #0 //0xffffffff - ldr r2, =0x10000034 - str r1, [r2] - str r0, [r2, #-4] - mov pc, lr - -.global secondary_cpu_start -secondary_cpu_start: - mrc p15, 0, r1, c1, c0, 1 - mov r0, #(1<<6) - orr r1, r0 - mcr p15, 0, r1, c1, c0, 1 //enable smp - - ldr r0, =mtbl - ldr lr, =1f - - b enable_mmu -1: - mrc p15, 0, r0, c1, c0, 0 - bic r0, #(1<<13) - mcr p15, 0, r0, c1, c0, 0 - - cps #Mode_IRQ - ldr sp, =irq_stack_2_limit - - cps #Mode_FIQ - ldr sp, =irq_stack_2_limit - - cps #Mode_SVC - ldr sp, =svc_stack_2_limit - - b secondary_cpu_c_start -#endif - -.bss -.align 2 //align to 2~2=4 -svc_stack_2: - .space (1 << 10) -svc_stack_2_limit: - -irq_stack_2: - .space (1 << 10) -irq_stack_2_limit: - -.data -#define DEVICE_MEM 0x10c06 -#define NORMAL_MEM 0x11c0e -.align 14 -mtbl: - - //vaddr: 0x00000000 - .rept 0x100 - .word 0x0 - .endr - - //vaddr: 0x10000000 - .equ mmu_tbl_map_paddr, 0x10000000 - .rept 0x400 - .word mmu_tbl_map_paddr | DEVICE_MEM - .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000 - .endr - - //vaddr: 0x50000000 - .rept 0x100 - .word 0x0 - .endr - - //vaddr: 0x60000000 - .equ mmu_tbl_map_paddr, 0x60000000 - .rept 0x800 - .word mmu_tbl_map_paddr | NORMAL_MEM - .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000 - .endr - - //vaddr: 0xe0000000 - .rept 0x200 - .word 0x0 - .endr diff --git a/bsp/qemu-vexpress-a9/cpu/trap.c b/bsp/qemu-vexpress-a9/cpu/trap.c deleted file mode 100644 index a1f00d0075..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/trap.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * File : trap.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-20 Bernard first version - */ - -#include -#include -#include - -#include "armv7.h" - -#include "gic.h" - -#ifdef RT_USING_FINSH -extern long list_thread(void); -#endif - -/** - * this function will show registers of CPU - * - * @param regs the registers point - */ -void rt_hw_show_register(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); -} - -/** - * When comes across an instruction which it cannot handle, - * it takes the undefined instruction trap. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during an instruction prefetch. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during a data access. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("data abort:"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * Normally, system will never reach here - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -#define GIC_ACK_INTID_MASK 0x000003ff - -void rt_hw_trap_irq(void) -{ - void *param; - unsigned long ir; - unsigned long fullir; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - fullir = arm_gic_get_active_irq(0); - ir = fullir & GIC_ACK_INTID_MASK; - - if (ir == 1023) - { - /* Spurious interrupt */ - return; - } - - /* get interrupt service routine */ - isr_func = isr_table[ir].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[ir].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[ir].param; - /* turn to interrupt service routine */ - isr_func(ir, param); - } - - /* end of interrupt */ - arm_gic_ack(0, fullir); -} - -void rt_hw_trap_fiq(void) -{ - void *param; - unsigned long ir; - unsigned long fullir; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - fullir = arm_gic_get_active_irq(0); - ir = fullir & GIC_ACK_INTID_MASK; - - /* get interrupt service routine */ - isr_func = isr_table[ir].handler; - param = isr_table[ir].param; - - /* turn to interrupt service routine */ - isr_func(ir, param); - - /* end of interrupt */ - arm_gic_ack(0, fullir); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S b/bsp/qemu-vexpress-a9/cpu/vector_gcc.S deleted file mode 100644 index 2473e1f850..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S +++ /dev/null @@ -1,65 +0,0 @@ -/* - * File : vector_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-05 Bernard the first version - */ - -.section .vectors, "ax" -.code 32 - -.globl system_vectors -system_vectors: - ldr pc, _vector_reset - ldr pc, _vector_undef - ldr pc, _vector_swi - ldr pc, _vector_pabt - ldr pc, _vector_dabt - ldr pc, _vector_resv - ldr pc, _vector_irq - ldr pc, _vector_fiq - -.globl _reset -.globl vector_undef -.globl vector_swi -.globl vector_pabt -.globl vector_dabt -.globl vector_resv -.globl vector_irq -.globl vector_fiq - -_vector_reset: - .word _reset -_vector_undef: - .word vector_undef -_vector_swi: - .word SVC_Handler -_vector_pabt: - .word vector_pabt -_vector_dabt: - .word vector_dabt -_vector_resv: - .word vector_resv -_vector_irq: - .word vector_irq -_vector_fiq: - .word vector_fiq - -.balignl 16,0xdeadbeef diff --git a/bsp/qemu-vexpress-a9/drivers/board.c b/bsp/qemu-vexpress-a9/drivers/board.c index 6ffac7efd7..e236c68b80 100644 --- a/bsp/qemu-vexpress-a9/drivers/board.c +++ b/bsp/qemu-vexpress-a9/drivers/board.c @@ -17,6 +17,15 @@ #include "board.h" #include "drv_timer.h" +#include + +struct mem_desc platform_mem_desc[] = { + {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM}, + {0x60000000, 0xe0000000, 0x60000000, NORMAL_MEM} +}; + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); + #define SYS_CTRL __REG32(REALVIEW_SCTL_BASE) extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); diff --git a/bsp/qemu-vexpress-a9/platform/SConscript b/bsp/qemu-vexpress-a9/platform/SConscript new file mode 100644 index 0000000000..1b580929da --- /dev/null +++ b/bsp/qemu-vexpress-a9/platform/SConscript @@ -0,0 +1,13 @@ +from building import * + +cwd = GetCurrentDir() +src = Split(''' +''') + +CPPPATH = [ cwd + '/cpu', +cwd + '/include', +] + +group = DefineGroup('Platform', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/qemu-vexpress-a9/platform/cpu/platform.h b/bsp/qemu-vexpress-a9/platform/cpu/platform.h new file mode 100644 index 0000000000..2d5cc5f61b --- /dev/null +++ b/bsp/qemu-vexpress-a9/platform/cpu/platform.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-03-22 quanzhao first version + */ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +/* for 'rt_inline' */ +#include +/* SOC-relative definitions */ +#include "realview.h" + +/* the maximum entries of the exception table */ +#define MAX_HANDLERS NR_IRQS_PBA8 + +/* the basic constants and interfaces needed by gic */ +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ + return REALVIEW_GIC_DIST_BASE; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ + return REALVIEW_GIC_CPU_BASE; +} + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + +#endif /* __PLATFORM_H__ */ diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index b6c3399da3..831d54c52f 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -10,7 +10,9 @@ #define RT_USING_SMP #define RT_CPUS_NR 2 #define RT_ALIGN_SIZE 4 +/* 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 100 #define RT_USING_OVERFLOW_CHECK @@ -37,7 +39,10 @@ #define RT_USING_MEMPOOL #define RT_USING_MEMHEAP +/* RT_USING_NOHEAP is not set */ #define RT_USING_SMALL_MEM +/* RT_USING_SLAB is not set */ +/* RT_USING_MEMHEAP_AS_HEAP is not set */ #define RT_USING_MEMTRACE #define RT_USING_HEAP @@ -53,6 +58,7 @@ #define ARCH_ARM #define ARCH_ARM_CORTEX_A #define ARCH_ARM_CORTEX_A9 +/* ARCH_CPU_STACK_GROWS_UPWARD is not set */ /* RT-Thread Components */ @@ -73,11 +79,14 @@ #define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION +/* FINSH_ECHO_DISABLE_DEFAULT is not set */ #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 FINSH_ARG_MAX 10 /* Device virtual file system */ @@ -87,21 +96,29 @@ #define DFS_FILESYSTEMS_MAX 2 #define DFS_FILESYSTEM_TYPES_MAX 8 #define DFS_FD_MAX 16 +/* RT_USING_DFS_MNTTABLE is not set */ #define RT_USING_DFS_ELMFAT /* elm-chan's FatFs, Generic FAT Filesystem Module */ #define RT_DFS_ELM_CODE_PAGE 437 #define RT_DFS_ELM_WORD_ACCESS +/* RT_DFS_ELM_USE_LFN_0 is not set */ +/* RT_DFS_ELM_USE_LFN_1 is not set */ +/* RT_DFS_ELM_USE_LFN_2 is not set */ #define RT_DFS_ELM_USE_LFN_3 #define RT_DFS_ELM_USE_LFN 3 #define RT_DFS_ELM_MAX_LFN 255 #define RT_DFS_ELM_DRIVES 2 #define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +/* RT_DFS_ELM_USE_ERASE is not set */ #define RT_DFS_ELM_REENTRANT #define RT_USING_DFS_DEVFS #define RT_USING_DFS_ROMFS #define RT_USING_DFS_RAMFS +/* RT_USING_DFS_UFFS is not set */ +/* RT_USING_DFS_JFFS2 is not set */ +/* RT_USING_DFS_NFS is not set */ /* Device Drivers */ @@ -110,12 +127,19 @@ #define RT_USING_SERIAL #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 +/* RT_USING_CAN is not set */ +/* 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_ADC is not set */ +/* RT_USING_PWM is not set */ #define RT_USING_MTD_NOR #define RT_USING_MTD_NAND #define RT_MTD_NAND_DEBUG +/* RT_USING_MTD is not set */ +/* RT_USING_PM is not set */ #define RT_USING_RTC #define RT_USING_SOFT_RTC #define RT_USING_SDIO @@ -124,18 +148,31 @@ #define RT_MMCSD_STACK_SIZE 1024 #define RT_MMCSD_THREAD_PREORITY 22 #define RT_MMCSD_MAX_PARTITION 16 +/* RT_SDIO_DEBUG is not set */ #define RT_USING_SPI +/* RT_USING_QSPI is not set */ #define RT_USING_SPI_MSD #define RT_USING_SFUD #define RT_SFUD_USING_SFDP #define RT_SFUD_USING_FLASH_INFO_TABLE +/* RT_SFUD_USING_QSPI is not set */ +/* RT_DEBUG_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 */ #define RT_USING_WDT +/* RT_USING_AUDIO is not set */ +/* RT_USING_SENSOR is not set */ /* Using WiFi */ +/* 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 */ @@ -145,6 +182,7 @@ #define RT_USING_POSIX_MMAP #define RT_USING_POSIX_TERMIOS #define RT_USING_POSIX_AIO +/* RT_USING_MODULE is not set */ /* Network */ @@ -161,9 +199,13 @@ /* light weight TCP/IP stack */ #define RT_USING_LWIP +/* RT_USING_LWIP141 is not set */ #define RT_USING_LWIP202 +/* RT_USING_LWIP210 is not set */ #define RT_USING_LWIP_IPV6 +/* RT_LWIP_IGMP is not set */ #define RT_LWIP_ICMP +/* RT_LWIP_SNMP is not set */ #define RT_LWIP_DNS #define RT_LWIP_DHCP #define IP_SOF_BROADCAST 1 @@ -176,6 +218,8 @@ #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 16 #define RT_LWIP_RAW_PCB_NUM 4 @@ -187,6 +231,8 @@ #define RT_LWIP_TCPTHREAD_PRIORITY 10 #define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 #define RT_LWIP_TCPTHREAD_STACKSIZE 1024 +/* LWIP_NO_RX_THREAD is not set */ +/* LWIP_NO_TX_THREAD is not set */ #define RT_LWIP_ETHTHREAD_PRIORITY 12 #define RT_LWIP_ETHTHREAD_STACKSIZE 1024 #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 @@ -196,62 +242,164 @@ #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 +/* RT_LWIP_STATS is not set */ +/* RT_LWIP_DEBUG is not set */ /* Modbus master and slave stack */ +/* RT_USING_MODBUS is not set */ /* AT commands */ +/* RT_USING_AT is not set */ +/* LWIP_USING_DHCPD is not set */ /* VBUS(Virtual Software BUS) */ +/* RT_USING_VBUS is not set */ /* Utilities */ #define RT_USING_LOGTRACE #define LOG_TRACE_MAX_SESSION 16 +/* LOG_TRACE_USING_LEVEL_NOTRACE is not set */ +/* LOG_TRACE_USING_LEVEL_ERROR is not set */ +/* LOG_TRACE_USING_LEVEL_WARNING is not set */ #define LOG_TRACE_USING_LEVEL_INFO +/* LOG_TRACE_USING_LEVEL_VERBOSE is not set */ +/* LOG_TRACE_USING_LEVEL_DEBUG is not set */ +/* LOG_TRACE_USING_MEMLOG is not set */ +/* RT_USING_RYM is not set */ +/* RT_USING_ULOG is not set */ +/* RT_USING_UTEST is not set */ #define RT_USING_LWP /* RT-Thread online packages */ /* IoT - internet of things */ +/* PKG_USING_PAHOMQTT is not set */ +/* PKG_USING_WEBCLIENT is not set */ +/* PKG_USING_WEBNET is not set */ +/* PKG_USING_MONGOOSE is not set */ +/* PKG_USING_WEBTERMINAL is not set */ +/* PKG_USING_CJSON is not set */ +/* PKG_USING_JSMN is not set */ +/* PKG_USING_LIBMODBUS is not set */ +/* PKG_USING_LJSON is not set */ +/* PKG_USING_EZXML is not set */ +/* PKG_USING_NANOPB is not set */ /* Wi-Fi */ /* Marvell WiFi */ +/* PKG_USING_WLANMARVELL is not set */ /* Wiced WiFi */ +/* PKG_USING_WLAN_WICED is not set */ +/* PKG_USING_RW007 is not set */ +/* PKG_USING_COAP is not set */ +/* PKG_USING_NOPOLL is not set */ +/* PKG_USING_NETUTILS is not set */ +/* PKG_USING_AT_DEVICE is not set */ +/* PKG_USING_WIZNET is not set */ /* IoT Cloud */ +/* PKG_USING_ONENET is not set */ +/* PKG_USING_GAGENT_CLOUD is not set */ +/* PKG_USING_ALI_IOTKIT is not set */ +/* PKG_USING_AZURE is not set */ +/* PKG_USING_TENCENT_IOTKIT is not set */ +/* PKG_USING_NIMBLE is not set */ +/* PKG_USING_OTA_DOWNLOADER is not set */ /* security packages */ +/* PKG_USING_MBEDTLS is not set */ +/* PKG_USING_libsodium is not set */ +/* PKG_USING_TINYCRYPT is not set */ /* language packages */ +/* PKG_USING_LUA is not set */ +/* PKG_USING_JERRYSCRIPT is not set */ +/* PKG_USING_MICROPYTHON is not set */ /* multimedia packages */ +/* PKG_USING_OPENMV is not set */ +/* PKG_USING_MUPDF is not set */ /* tools packages */ +/* PKG_USING_CMBACKTRACE is not set */ +/* PKG_USING_EASYFLASH is not set */ +/* PKG_USING_EASYLOGGER is not set */ +/* PKG_USING_SYSTEMVIEW is not set */ +/* PKG_USING_RDB is not set */ +/* PKG_USING_QRCODE is not set */ +/* PKG_USING_ULOG_EASYFLASH is not set */ +/* PKG_USING_ADBD is not set */ /* system packages */ +/* PKG_USING_GUIENGINE is not set */ +/* PKG_USING_PERSIMMON is not set */ +/* PKG_USING_CAIRO is not set */ +/* PKG_USING_PIXMAN is not set */ +/* PKG_USING_LWEXT4 is not set */ +/* PKG_USING_PARTITION is not set */ +/* PKG_USING_FAL is not set */ +/* PKG_USING_SQLITE is not set */ +/* PKG_USING_RTI is not set */ +/* PKG_USING_LITTLEVGL2RTT is not set */ +/* PKG_USING_CMSIS is not set */ +/* PKG_USING_DFS_YAFFS is not set */ +/* PKG_USING_LITTLEFS is not set */ /* peripheral libraries and drivers */ /* sensors drivers */ +/* PKG_USING_LSM6DSL is not set */ +/* PKG_USING_LPS22HB is not set */ +/* PKG_USING_HTS221 is not set */ +/* PKG_USING_LSM303AGR is not set */ +/* PKG_USING_BME280 is not set */ +/* PKG_USING_BMA400 is not set */ +/* PKG_USING_BMI160_BMX160 is not set */ +/* PKG_USING_SPL0601 is not set */ +/* PKG_USING_REALTEK_AMEBA is not set */ +/* PKG_USING_SHT2X is not set */ +/* PKG_USING_AHT10 is not set */ +/* PKG_USING_AP3216C is not set */ +/* PKG_USING_STM32_SDIO is not set */ +/* PKG_USING_ICM20608 is not set */ +/* PKG_USING_U8G2 is not set */ +/* PKG_USING_BUTTON is not set */ +/* PKG_USING_MPU6XXX is not set */ +/* PKG_USING_PCF8574 is not set */ +/* PKG_USING_SX12XX is not set */ +/* PKG_USING_KENDRYTE_SDK is not set */ /* miscellaneous packages */ +/* PKG_USING_LIBCSV is not set */ +/* PKG_USING_OPTPARSE is not set */ +/* PKG_USING_FASTLZ is not set */ +/* PKG_USING_MINILZO is not set */ +/* PKG_USING_QUICKLZ is not set */ +/* PKG_USING_MULTIBUTTON is not set */ +/* PKG_USING_CANFESTIVAL is not set */ +/* PKG_USING_ZLIB is not set */ +/* PKG_USING_DSTR is not set */ +/* PKG_USING_TINYFRAME is not set */ +/* PKG_USING_KENDRYTE_DEMO is not set */ /* samples: kernel and components samples */ @@ -259,5 +407,6 @@ #define RT_USING_UART0 #define RT_USING_UART1 #define BSP_DRV_EMAC +/* BSP_DRV_AUDIO is not set */ #endif diff --git a/bsp/qemu-vexpress-a9/rtconfig.py b/bsp/qemu-vexpress-a9/rtconfig.py index 8ccd0227e4..d417673898 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.py +++ b/bsp/qemu-vexpress-a9/rtconfig.py @@ -2,14 +2,15 @@ import os # toolchains options ARCH='arm' -CPU='cortex-a9' +CPU='cortex-a' CROSS_TOOL='gcc' if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') +# only support GNU GCC compiler. PLATFORM = 'gcc' -EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin' +EXEC_PATH = '/usr/bin' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') diff --git a/components/lwp/SConscript b/components/lwp/SConscript index d3b799257b..f151f3b92e 100644 --- a/components/lwp/SConscript +++ b/components/lwp/SConscript @@ -5,7 +5,7 @@ cwd = GetCurrentDir() src = [] CPPPATH = [cwd] -support_arch = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a9"]} +support_arch = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a"]} platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'} if rtconfig.PLATFORM in platform_file.keys(): # support platforms diff --git a/components/lwp/arch/arm/cortex-a/lwp_gcc.S b/components/lwp/arch/arm/cortex-a/lwp_gcc.S new file mode 100644 index 0000000000..6c89152b0c --- /dev/null +++ b/components/lwp/arch/arm/cortex-a/lwp_gcc.S @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-12-10 Jesven first version + */ + +#define Mode_USR 0x10 +#define Mode_FIQ 0x11 +#define Mode_IRQ 0x12 +#define Mode_SVC 0x13 +#define Mode_MON 0x16 +#define Mode_ABT 0x17 +#define Mode_UDF 0x1B +#define Mode_SYS 0x1F + +#define A_Bit 0x100 +#define I_Bit 0x80 @; when I bit is set, IRQ is disabled +#define F_Bit 0x40 @; when F bit is set, FIQ is disabled +#define T_Bit 0x20 + +.cpu cortex-a9 +.syntax unified +.text + +/* + * void lwp_user_entry(args, text, data); + */ +.global lwp_user_entry +.type lwp_user_entry, % function +lwp_user_entry: + mrs r9, cpsr + bic r9, #0x1f + orr r9, #Mode_USR + cpsid i + msr spsr, r9 + + /* set data address. */ + mov r9, r2 + movs pc, r1 + +/* + * void SVC_Handler(void); + */ +.global SVC_Handler +.type SVC_Handler, % function +SVC_Handler: + push {lr} + mrs lr, spsr + push {r4, r5, lr} + cpsie i + + push {r0 - r3, r12} + and r0, r7, #0xff + bl lwp_get_sys_api + cmp r0, #0 /* r0 = api */ + mov lr, r0 + pop {r0 - r3, r12} + beq svc_exit + blx lr + +svc_exit: + cpsid i + pop {r4, r5, lr} + msr spsr_cxsf, lr + pop {lr} + movs pc, lr diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index 97b3dbc447..b009630fa8 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/libcpu/arm/cortex-a/context_gcc.S @@ -8,7 +8,14 @@ * 2013-07-05 Bernard the first version */ +#include "rtconfig.h" .section .text, "ax" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + /* * rt_base_t rt_hw_interrupt_disable(); */ @@ -34,6 +41,16 @@ rt_hw_interrupt_enable: rt_hw_context_switch_to: ldr sp, [r0] @ get new task stack pointer +#ifdef RT_USING_SMP + mov r0, r1 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task spsr msr spsr_cxsf, r4 @@ -62,9 +79,24 @@ rt_hw_context_switch: stmfd sp!, {r4} @ push cpsr +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @ push usr_sp usr_lr + sub sp, #8 +#endif + str sp, [r0] @ store sp in preempted tasks TCB ldr sp, [r1] @ get new task stack pointer +#ifdef RT_USING_SMP + mov r0, r2 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task cpsr to spsr msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr @@ -72,11 +104,70 @@ rt_hw_context_switch: /* * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); */ +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: +#ifdef RT_USING_SMP + /* r0 :irq_mod context + * r1 :addr of from_thread's sp + * r2 :addr of to_thread's sp + * r3 :to_thread's tcb + */ + + @ r0 point to {r0-r3} in stack + push {r1 - r3} + mov r1, r0 + add r0, r0, #4*4 + ldmfd r0!, {r4-r12,lr}@ reload saved registers + mrs r3, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r4-r7} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r4-r7} @ push old task's r0-r3 + stmfd sp!, {r3} @ push old task's cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13,r14}^ @push usr_sp usr_lr + sub sp, #8 +#endif + + msr cpsr_c, #I_Bit|F_Bit|Mode_IRQ + pop {r1 - r3} + mov sp, r0 + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + str sp, [r1] + + ldr sp, [r2] + mov r0, r3 + bl rt_cpus_lock_status_restore + +#ifdef RT_USING_LWP + ldmfd sp, {r13,r14}^ @pop usr_sp usr_lr + add sp, #8 +#endif + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +#else /*RT_USING_SMP*/ ldr r2, =rt_thread_switch_interrupt_flag ldr r3, [r2] cmp r3, #1 @@ -89,3 +180,4 @@ _reswitch: ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread str r1, [r2] bx lr +#endif /*RT_USING_SMP*/ diff --git a/libcpu/arm/cortex-a/cp15.h b/libcpu/arm/cortex-a/cp15.h index 486f38200d..97c5b93ad2 100644 --- a/libcpu/arm/cortex-a/cp15.h +++ b/libcpu/arm/cortex-a/cp15.h @@ -5,6 +5,7 @@ * * Change Logs: * Date Author Notes + * 2018-03-25 quanzhao the first version */ #ifndef __CP15_H__ #define __CP15_H__ @@ -15,6 +16,9 @@ void rt_cpu_mmu_disable(void); void rt_cpu_mmu_enable(void); void rt_cpu_tlb_set(volatile unsigned long*); +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + void rt_cpu_vector_set_base(unsigned int addr); #endif diff --git a/libcpu/arm/cortex-a/cp15_gcc.S b/libcpu/arm/cortex-a/cp15_gcc.S index 0e3e60655c..dd2436ffee 100644 --- a/libcpu/arm/cortex-a/cp15_gcc.S +++ b/libcpu/arm/cortex-a/cp15_gcc.S @@ -15,6 +15,11 @@ rt_cpu_get_smp_id: .globl rt_cpu_vector_set_base rt_cpu_vector_set_base: + /* clear SCTRL.V to customize the vector address */ + mrc p15, #0, r1, c1, c0, #0 + bic r1, #(1 << 13) + mcr p15, #0, r1, c1, c0, #0 + /* set up the vector address */ mcr p15, #0, r0, c12, c0, #0 dsb bx lr @@ -36,7 +41,7 @@ rt_hw_cpu_icache_enable: _FLD_MAX_WAY: .word 0x3ff _FLD_MAX_IDX: - .word 0x7ff + .word 0x7fff .globl rt_cpu_dcache_clean_flush rt_cpu_dcache_clean_flush: @@ -84,6 +89,14 @@ finished: pop {r4-r11} bx lr +.globl rt_cpu_icache_flush +rt_cpu_icache_flush: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + bx lr + .globl rt_hw_cpu_dcache_disable rt_hw_cpu_dcache_disable: push {r4-r11, lr} diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c index 2d78715011..6b129f89ee 100644 --- a/libcpu/arm/cortex-a/cpu.c +++ b/libcpu/arm/cortex-a/cpu.c @@ -6,28 +6,78 @@ * Change Logs: * Date Author Notes * 2011-09-15 Bernard first version + * 2018-11-22 Jesven add rt_hw_cpu_id() */ #include #include #include +#ifdef RT_USING_SMP +int rt_hw_cpu_id(void) +{ + int cpu_id; + __asm__ volatile ( + "mrc p15, 0, %0, c0, c0, 5" + :"=r"(cpu_id) + ); + cpu_id &= 0xf; + return cpu_id; +}; + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + unsigned long tmp; + unsigned long newval; + rt_hw_spinlock_t lockval; + + __asm__ __volatile__( + "pld [%0]" + ::"r"(&lock->slock) + ); + + __asm__ __volatile__( + "1: ldrex %0, [%3]\n" + " add %1, %0, %4\n" + " strex %2, %1, [%3]\n" + " teq %2, #0\n" + " bne 1b" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) + : "r" (&lock->slock), "I" (1 << 16) + : "cc"); + + while (lockval.tickets.next != lockval.tickets.owner) { + __asm__ __volatile__("wfe":::"memory"); + lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); + } + + __asm__ volatile ("dmb":::"memory"); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + __asm__ volatile ("dmb":::"memory"); + lock->tickets.owner++; + __asm__ volatile ("dsb ishst\nsev":::"memory"); +} +#endif /*RT_USING_SMP*/ + /** - * @addtogroup AM33xx + * @addtogroup ARM CPU */ /*@{*/ /** shutdown CPU */ void rt_hw_cpu_shutdown() { - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } } /*@}*/ diff --git a/libcpu/arm/cortex-a/gic.c b/libcpu/arm/cortex-a/gic.c new file mode 100644 index 0000000000..2a46142b54 --- /dev/null +++ b/libcpu/arm/cortex-a/gic.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + */ + +#include +#include + +#include "gic.h" +#include "cp15.h" + +struct arm_gic +{ + rt_uint32_t offset; /* the first interrupt index in the vector table */ + + rt_uint32_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint32_t cpu_hw_base; /* the base addrees of the gic cpu interface */ +}; + +/* 'ARM_GIC_MAX_NR' is the number of cores */ +static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; + +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18) + +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380 + ((n)/32) * 4) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00) +#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10 + ((n)/4) * 4) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8) + +static unsigned int _gic_max_irq; + +int arm_gic_get_active_irq(rt_uint32_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base); + irq += _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_mask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_clear_pending(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_clear_active(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +/* Set up the cpu mask for the specific interrupt */ +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) +{ + rt_uint32_t old_tgt; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); + + old_tgt &= ~(0x0FFUL << ((irq % 4)*8)); + old_tgt |= cpumask << ((irq % 4)*8); + + GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; +} + +void arm_gic_umask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_dump_type(rt_uint32_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1 << 10) ? "has" : "no", + gic_type); +} + +void arm_gic_dump(rt_uint32_t index) +{ + unsigned int i, k; + + k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); + rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); + rt_kprintf("--- hw mask ---\n"); + for (i = 0; i < _gic_max_irq / 32; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, + i * 32)); + } + rt_kprintf("\n--- hw pending ---\n"); + for (i = 0; i < _gic_max_irq / 32; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, + i * 32)); + } + rt_kprintf("\n--- hw active ---\n"); + for (i = 0; i < _gic_max_irq / 32; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, + i * 32)); + } + rt_kprintf("\n"); +} +#ifdef RT_USING_FINSH +#include +FINSH_FUNCTION_EXPORT_ALIAS(arm_gic_dump, gic, show gic status); +#endif + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) +{ + unsigned int gic_type, i; + rt_uint32_t cpumask = 1 << 0; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020) + _gic_max_irq = 1020; + if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + _gic_max_irq = ARM_GIC_NR_IRQS; + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + cpumask |= cpumask << 24; + + GIC_DIST_CTRL(dist_base) = 0x0; + + /* Set all global interrupts to be level triggered, active low. */ + for (i = 32; i < _gic_max_irq; i += 16) + GIC_DIST_CONFIG(dist_base, i) = 0x0; + + /* Set all global interrupts to this CPU only. */ + for (i = 32; i < _gic_max_irq; i += 4) + GIC_DIST_TARGET(dist_base, i) = cpumask; + + /* Set priority on all interrupts. */ + for (i = 0; i < _gic_max_irq; i += 4) + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; + + /* Disable all interrupts. */ + for (i = 0; i < _gic_max_irq; i += 32) + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; + +#if 0 + /* All interrupts defaults to IGROUP1(IRQ). */ + for (i = 0; i < _gic_max_irq; i += 32) + GIC_DIST_IGROUP(dist_base, i) = 0xffffffff; +#endif + for (i = 0; i < _gic_max_irq; i += 32) + GIC_DIST_IGROUP(dist_base, i) = 0; + + /* Enable group0 and group1 interrupt forwarding. */ + GIC_DIST_CTRL(dist_base) = 0x01; + + return 0; +} + +int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].cpu_hw_base = cpu_base; + + GIC_CPU_PRIMASK(cpu_base) = 0xf0; + GIC_CPU_BINPOINT(cpu_base) = 0x7; + /* Enable CPU interrupt */ + GIC_CPU_CTRL(cpu_base) = 0x01; + + return 0; +} + +void arm_gic_set_group(rt_uint32_t index, int vector, int group) +{ + /* As for GICv2, there are only group0 and group1. */ + RT_ASSERT(group <= 1); + RT_ASSERT(vector < _gic_max_irq); + + if (group == 0) + { + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, + vector) &= ~(1 << (vector % 32)); + } + else if (group == 1) + { + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, + vector) |= (1 << (vector % 32)); + } +} + +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) + { + /* note: ipi_vector maybe different with irq_vector */ + GIC_DIST_SOFTINT(_gic_table[0].dist_hw_base) = (cpu_mask << 16) | ipi_vector; +} +#endif + +#ifdef RT_USING_SMP +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +{ + /* note: ipi_vector maybe different with irq_vector */ + rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); +} +#endif diff --git a/libcpu/arm/cortex-a/gic.h b/libcpu/arm/cortex-a/gic.h new file mode 100644 index 0000000000..6d86dd31e0 --- /dev/null +++ b/libcpu/arm/cortex-a/gic.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#ifndef __GIC_H__ +#define __GIC_H__ + +#include +#include + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base); + +void arm_gic_mask(rt_uint32_t index, int irq); +void arm_gic_umask(rt_uint32_t index, int irq); +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); +void arm_gic_set_group(rt_uint32_t index, int vector, int group); + +int arm_gic_get_active_irq(rt_uint32_t index); +void arm_gic_ack(rt_uint32_t index, int irq); + +void arm_gic_clear_active(rt_uint32_t index, int irq); +void arm_gic_clear_pending(rt_uint32_t index, int irq); + +void arm_gic_dump_type(rt_uint32_t index); +void arm_gic_dump(rt_uint32_t index); + +#endif + diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index fb6e3ff3e0..b7a70719a9 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/libcpu/arm/cortex-a/interrupt.c @@ -6,68 +6,32 @@ * Change Logs: * Date Author Notes * 2013-07-06 Bernard first version - * 2014-04-03 Grissiom port to VMM + * 2018-11-22 Jesven add smp support */ #include #include +#include "interrupt.h" +#include "gic.h" -#include -#include - -#include -#include "cp15.h" - -#define MAX_HANDLERS IMX_INTERRUPT_COUNT - -extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; -rt_uint32_t rt_interrupt_from_thread; -rt_uint32_t rt_interrupt_to_thread; -rt_uint32_t rt_thread_switch_interrupt_flag; +#ifndef RT_USING_SMP +/* Those varibles will be accessed in ISR, so we need to share them. */ +rt_uint32_t rt_interrupt_from_thread = 0; +rt_uint32_t rt_interrupt_to_thread = 0; +rt_uint32_t rt_thread_switch_interrupt_flag = 0; +#endif +const unsigned int VECTOR_BASE = 0x00; extern void rt_cpu_vector_set_base(unsigned int addr); extern int system_vectors; -/* keep compatible with platform SDK */ -void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr) -{ - rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown"); -} - -void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority) -{ - gic_set_irq_priority(irq_id, priority); - gic_set_irq_security(irq_id, false); // set IRQ as non-secure - gic_set_cpu_target(irq_id, cpu_id, true); - gic_enable_irq(irq_id, true); -} - -void disable_interrupt(uint32_t irq_id, uint32_t cpu_id) +void rt_hw_vector_init(void) { - gic_enable_irq(irq_id, false); - gic_set_cpu_target(irq_id, cpu_id, false); -} - -static void rt_hw_vector_init(void) -{ - int sctrl; - unsigned int *src = (unsigned int *)&system_vectors; - - /* C12-C0 is only active when SCTLR.V = 0 */ - asm volatile ("mrc p15, #0, %0, c1, c0, #0" - :"=r" (sctrl)); - sctrl &= ~(1 << 13); - asm volatile ("mcr p15, #0, %0, c1, c0, #0" - : - :"r" (sctrl)); - - asm volatile ("mcr p15, #0, %0, c12, c0, #0" - : - :"r" (src)); + rt_cpu_vector_set_base((unsigned int)&system_vectors); } /** @@ -75,14 +39,24 @@ static void rt_hw_vector_init(void) */ void rt_hw_interrupt_init(void) { + rt_uint32_t gic_cpu_base; + rt_uint32_t gic_dist_base; + rt_uint32_t gic_irq_start; + + /* initialize vector table */ rt_hw_vector_init(); - gic_init(); - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + /* initialize exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* initialize ARM GIC */ + gic_dist_base = platform_get_gic_dist_base(); + gic_cpu_base = platform_get_gic_cpu_base(); + + gic_irq_start = GIC_IRQ_START; + + arm_gic_dist_init(0, gic_dist_base, gic_irq_start); + arm_gic_cpu_init(0, gic_cpu_base); } /** @@ -91,7 +65,7 @@ void rt_hw_interrupt_init(void) */ void rt_hw_interrupt_mask(int vector) { - disable_interrupt(vector, 0); + arm_gic_mask(0, vector); } /** @@ -100,9 +74,26 @@ void rt_hw_interrupt_mask(int vector) */ void rt_hw_interrupt_umask(int vector) { - enable_interrupt(vector, 0, 0); + arm_gic_umask(0, vector); } +/** + * This function returns the active interrupt number. + * @param none + */ +int rt_hw_interrupt_get_irq(void) +{ + return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK; +} + +/** + * This function acknowledges the interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_ack(int vector) +{ + arm_gic_ack(0, vector); +} /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number @@ -126,23 +117,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, isr_table[vector].handler = handler; isr_table[vector].param = param; } - // arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id()); } return old_handler; } - -/** - * Trigger a software IRQ - * - * Since we are running in single core, the target CPU are always CPU0. - */ -void rt_hw_interrupt_trigger(int vector) -{ - // arm_gic_trigger(0, 1, vector); -} - -void rt_hw_interrupt_clear(int vector) -{ - gic_write_end_of_irq(vector); -} diff --git a/libcpu/arm/cortex-a/interrupt.h b/libcpu/arm/cortex-a/interrupt.h new file mode 100644 index 0000000000..bff29d402d --- /dev/null +++ b/libcpu/arm/cortex-a/interrupt.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +void rt_hw_interrupt_control(int vector, int priority, int route); + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +int rt_hw_interrupt_get_irq(void); +void rt_hw_interrupt_ack(int vector); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif diff --git a/libcpu/arm/cortex-a/mmu.c b/libcpu/arm/cortex-a/mmu.c index 58acdd8145..1260f41fe5 100644 --- a/libcpu/arm/cortex-a/mmu.c +++ b/libcpu/arm/cortex-a/mmu.c @@ -13,35 +13,7 @@ #include #include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO -#define XN (1<<4) // eXecute Never - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) - -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) +#include "mmu.h" /* dump 2nd level page table */ void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) @@ -178,18 +150,25 @@ unsigned long rt_hw_set_domain_register(unsigned long domain_val) return old_domain; } +void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size) +{ + /* set page table */ + for(; size > 0; size--) + { + rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); + mdesc++; + } +} + void rt_hw_mmu_init(void) { + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); rt_hw_cpu_dcache_disable(); rt_hw_cpu_icache_disable(); rt_cpu_mmu_disable(); - /* set page table */ - /* 4G 1:1 memory */ - rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); - /* IO memory region */ - rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); - /*rt_hw_cpu_dump_page_table(MMUTable);*/ rt_hw_set_domain_register(0x55555555); diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h new file mode 100644 index 0000000000..deec690c69 --- /dev/null +++ b/libcpu/arm/cortex-a/mmu.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-25 quanzhao the first version + */ +#ifndef __MMU_H_ +#define __MMU_H_ + +#include + +#define DESC_SEC (0x2) +#define MEMWB (3<<2) /* write back, no write allocate */ +#define MEMWT (2<<2) /* write through, no write allocate */ +#define SHAREDEVICE (1<<2) /* shared device */ +#define STRONGORDER (0<<2) /* strong ordered */ +#define XN (1<<4) /* eXecute Never */ +#define AP_RW (3<<10) /* supervisor=RW, user=RW */ +#define AP_RO (2<<10) /* supervisor=RW, user=RO */ +#define SHARED (1<<16) /* shareable */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +/* device mapping type */ +#define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC) + +struct mem_desc +{ + rt_uint32_t vaddr_start; + rt_uint32_t vaddr_end; + rt_uint32_t paddr_start; + rt_uint32_t attr; +}; + + +#endif diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c index 1d3ebcb9e6..d76b8a428a 100644 --- a/libcpu/arm/cortex-a/stack.c +++ b/libcpu/arm/cortex-a/stack.c @@ -50,13 +50,17 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, *(--stk) = 0xdeadbeef; /* r2 */ *(--stk) = 0xdeadbeef; /* r1 */ *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - /* cpsr */ if ((rt_uint32_t)tentry & 0x01) *(--stk) = SVCMODE | 0x20; /* thumb mode */ else *(--stk) = SVCMODE; /* arm mode */ +#ifdef RT_USING_LWP + *(--stk) = 0; /* user lr */ + *(--stk) = 0; /* user sp*/ +#endif + /* return task's current stack address */ return (rt_uint8_t *)stk; } diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 2f16d16807..0f4ff58364 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -6,8 +6,12 @@ * Change Logs: * Date Author Notes * 2013-07-05 Bernard the first version + * 2018-11-22 Jesven in the interrupt context, use rt_scheduler_do_irq_switch checks + * and switches to a new thread */ +#include "rtconfig.h" + .equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 @@ -20,11 +24,11 @@ .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled .equ UND_Stack_Size, 0x00000000 -.equ SVC_Stack_Size, 0x00000100 +.equ SVC_Stack_Size, 0x00000400 .equ ABT_Stack_Size, 0x00000000 .equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000100 -.equ USR_Stack_Size, 0x00000100 +.equ RT_IRQ_STACK_PGSZ, 0x00000800 +.equ USR_Stack_Size, 0x00000400 #define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) @@ -44,12 +48,8 @@ stack_top: /* reset entry */ .globl _reset _reset: - bl rt_cpu_mmu_disable /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 + cps #Mode_SVC /* setup stack */ bl stack_setup @@ -64,6 +64,20 @@ bss_loop: strlo r0,[r1],#4 /* clear 4 bytes */ blo bss_loop /* loop until done */ +#ifdef RT_USING_SMP + mrc p15, 0, r1, c1, c0, 1 + mov r0, #(1<<6) + orr r1, r0 + mcr p15, 0, r1, c1, c0, 1 //enable smp +#endif + + /* initialize the mmu table and enable mmu */ + ldr r0, =platform_mem_desc + ldr r1, =platform_mem_desc_size + ldr r1, [r1] + bl rt_hw_init_mmu_table + bl rt_hw_mmu_init + /* call C++ constructors of global objects */ ldr r0, =__ctors_start__ ldr r1, =__ctors_end__ @@ -137,12 +151,22 @@ vector_fiq: .align 5 .globl vector_irq vector_irq: +#ifdef RT_USING_SMP + clrex +#endif stmfd sp!, {r0-r12,lr} bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave +#ifdef RT_USING_SMP + mov r0, sp + bl rt_scheduler_do_irq_switch + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 +#else @ if rt_thread_switch_interrupt_flag set, jump to @ rt_hw_context_switch_interrupt_do and don't return ldr r0, =rt_thread_switch_interrupt_flag @@ -174,6 +198,11 @@ rt_hw_context_switch_interrupt_do: stmfd sp!, {r1-r4} @ push old task's r0-r3 stmfd sp!, {r0} @ push old task's cpsr +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @push usr_sp, usr_lr + sub sp, #8 +#endif + ldr r4, =rt_interrupt_from_thread ldr r5, [r4] str sp, [r5] @ store sp in preempted tasks's TCB @@ -182,11 +211,18 @@ rt_hw_context_switch_interrupt_do: ldr r6, [r6] ldr sp, [r6] @ get new task's stack pointer +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task's cpsr to spsr msr spsr_cxsf, r4 ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr +#endif + .macro push_svc_reg sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ stmia sp, {r0 - r12} @/* Calling r0-r12 */ @@ -200,36 +236,86 @@ rt_hw_context_switch_interrupt_do: .endm .align 5 - .globl vector_swi + .globl vector_swi +.weak SVC_Handler +SVC_Handler: vector_swi: push_svc_reg bl rt_hw_trap_swi b . .align 5 - .globl vector_undef + .globl vector_undef vector_undef: push_svc_reg bl rt_hw_trap_undef b . .align 5 - .globl vector_pabt + .globl vector_pabt vector_pabt: push_svc_reg bl rt_hw_trap_pabt b . .align 5 - .globl vector_dabt + .globl vector_dabt vector_dabt: push_svc_reg bl rt_hw_trap_dabt b . .align 5 - .globl vector_resv + .globl vector_resv vector_resv: push_svc_reg bl rt_hw_trap_resv b . + +#ifdef RT_USING_SMP +.global set_secondary_cpu_boot_address +set_secondary_cpu_boot_address: + ldr r0, =secondary_cpu_start + + mvn r1, #0 //0xffffffff + ldr r2, =0x10000034 + str r1, [r2] + str r0, [r2, #-4] + mov pc, lr + +.global secondary_cpu_start +secondary_cpu_start: + mrc p15, 0, r1, c1, c0, 1 + mov r0, #(1<<6) + orr r1, r0 + mcr p15, 0, r1, c1, c0, 1 //enable smp + + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + cps #Mode_IRQ + ldr sp, =irq_stack_2_limit + + cps #Mode_FIQ + ldr sp, =irq_stack_2_limit + + cps #Mode_SVC + ldr sp, =svc_stack_2_limit + + /* initialize the mmu table and enable mmu */ + bl rt_hw_mmu_init + + b secondary_cpu_c_start +#endif + +.bss +.align 2 //align to 2~2=4 +svc_stack_2: + .space (1 << 10) +svc_stack_2_limit: + +irq_stack_2: + .space (1 << 10) +irq_stack_2_limit: + diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index f3b2c26e6d..54628933ff 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -10,13 +10,11 @@ #include #include -#include +#include #include "armv7.h" +#include "interrupt.h" -#include "gic.h" - -extern struct rt_thread *rt_current_thread; #ifdef RT_USING_FINSH extern long list_thread(void); #endif @@ -130,48 +128,52 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) void rt_hw_trap_irq(void) { void *param; + int ir; rt_isr_handler_t isr_func; extern struct rt_irq_desc isr_table[]; - // vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0] - // send ack and get ID source - uint32_t vectNum = gic_read_irq_ack(); + ir = rt_hw_interrupt_get_irq(); - // Check that INT_ID isn't 1023 or 1022 (spurious interrupt) - if (vectNum & 0x0200) + if (ir == 1023) { - gic_write_end_of_irq(vectNum); // send end of irq + /* Spurious interrupt */ + return; } - else - { - // copy the local value to the global image of CPUID - unsigned cpu = (vectNum >> 10) & 0x7; - unsigned irq = vectNum & 0x1FF; - /* skip warning */ - cpu = cpu; - - // Call the service routine stored in the handlers array. If there isn't - // one for this IRQ, then call the default handler. - /* get interrupt service routine */ - isr_func = isr_table[irq].handler; + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; #ifdef RT_USING_INTERRUPT_INFO - isr_table[irq].counter++; + isr_table[ir].counter++; #endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(irq, param); - } - - // Signal the end of the irq. - gic_write_end_of_irq(vectNum); + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[ir].param; + /* turn to interrupt service routine */ + isr_func(ir, param); } + + /* end of interrupt */ + rt_hw_interrupt_ack(ir); } void rt_hw_trap_fiq(void) { - /* TODO */ + void *param; + int ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_irq(); + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + param = isr_table[ir].param; + + /* turn to interrupt service routine */ + isr_func(ir, param); + + /* end of interrupt */ + rt_hw_interrupt_ack(ir); } + -- cgit v1.3.1 From bd8f0d04232b5725ed8965bf528946906775f8cf Mon Sep 17 00:00:00 2001 From: BernardXiong Date: Tue, 26 Mar 2019 13:36:01 +0000 Subject: [libcpu] Fix the build directory issue --- libcpu/SConscript | 2 +- libcpu/arc/SConscript | 4 ++-- libcpu/arm/SConscript | 8 +++----- libcpu/avr32/SConscript | 2 +- libcpu/blackfin/SConscript | 2 +- libcpu/c-sky/SConscript | 4 ++-- libcpu/m16c/SConscript | 2 +- libcpu/mips/SConscript | 4 ++-- libcpu/nios/SConscript | 2 +- libcpu/ppc/SConscript | 4 ++-- libcpu/risc-v/SConscript | 4 ++-- libcpu/sim/SConscript | 2 +- libcpu/ti-dsp/SConscript | 2 +- libcpu/unicore32/SConscript | 2 +- libcpu/v850/SConscript | 2 +- libcpu/xilinx/SConscript | 2 +- 16 files changed, 23 insertions(+), 25 deletions(-) (limited to 'libcpu') diff --git a/libcpu/SConscript b/libcpu/SConscript index 774e7f4043..6092707e6d 100644 --- a/libcpu/SConscript +++ b/libcpu/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) if rtconfig.ARCH in list: - group = group + SConscript(os.path.join(cwd, rtconfig.ARCH, 'SConscript')) + group = group + SConscript(os.path.join(rtconfig.ARCH, 'SConscript')) Return('group') diff --git a/libcpu/arc/SConscript b/libcpu/arc/SConscript index cbec0b5ec1..3c69b578fa 100644 --- a/libcpu/arc/SConscript +++ b/libcpu/arc/SConscript @@ -9,9 +9,9 @@ cwd = GetCurrentDir() group = [] # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = group + SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/arm/SConscript b/libcpu/arm/SConscript index 36a214327b..f6ea13fb91 100644 --- a/libcpu/arm/SConscript +++ b/libcpu/arm/SConscript @@ -5,14 +5,12 @@ from building import * Import('rtconfig') -cwd = GetCurrentDir() -group = [] -list = os.listdir(cwd) +cwd = GetCurrentDir() # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/avr32/SConscript b/libcpu/avr32/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/avr32/SConscript +++ b/libcpu/avr32/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/blackfin/SConscript b/libcpu/blackfin/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/blackfin/SConscript +++ b/libcpu/blackfin/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/c-sky/SConscript b/libcpu/c-sky/SConscript index 36a214327b..640e46a4fb 100644 --- a/libcpu/c-sky/SConscript +++ b/libcpu/c-sky/SConscript @@ -10,9 +10,9 @@ group = [] list = os.listdir(cwd) # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = group + SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/m16c/SConscript b/libcpu/m16c/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/m16c/SConscript +++ b/libcpu/m16c/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/mips/SConscript b/libcpu/mips/SConscript index 36a214327b..640e46a4fb 100644 --- a/libcpu/mips/SConscript +++ b/libcpu/mips/SConscript @@ -10,9 +10,9 @@ group = [] list = os.listdir(cwd) # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = group + SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/nios/SConscript b/libcpu/nios/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/nios/SConscript +++ b/libcpu/nios/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/ppc/SConscript b/libcpu/ppc/SConscript index 36a214327b..640e46a4fb 100644 --- a/libcpu/ppc/SConscript +++ b/libcpu/ppc/SConscript @@ -10,9 +10,9 @@ group = [] list = os.listdir(cwd) # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = group + SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/risc-v/SConscript b/libcpu/risc-v/SConscript index 36a214327b..640e46a4fb 100644 --- a/libcpu/risc-v/SConscript +++ b/libcpu/risc-v/SConscript @@ -10,9 +10,9 @@ group = [] list = os.listdir(cwd) # add common code files -group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) +group = group + SConscript(os.path.join('common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/sim/SConscript b/libcpu/sim/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/sim/SConscript +++ b/libcpu/sim/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/ti-dsp/SConscript b/libcpu/ti-dsp/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/ti-dsp/SConscript +++ b/libcpu/ti-dsp/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/unicore32/SConscript b/libcpu/unicore32/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/unicore32/SConscript +++ b/libcpu/unicore32/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/v850/SConscript b/libcpu/v850/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/v850/SConscript +++ b/libcpu/v850/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/xilinx/SConscript b/libcpu/xilinx/SConscript index ebdd1357ee..4f1441895c 100644 --- a/libcpu/xilinx/SConscript +++ b/libcpu/xilinx/SConscript @@ -10,6 +10,6 @@ group = [] list = os.listdir(cwd) # cpu porting code files -group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) Return('group') -- cgit v1.3.1 From fcb88f70343f9e2dd8e3ba3ab7cba56497ad1415 Mon Sep 17 00:00:00 2001 From: ZYH Date: Thu, 28 Mar 2019 16:49:43 +0800 Subject: [libcpu][k210]fix stack frame print --- libcpu/risc-v/k210/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libcpu') diff --git a/libcpu/risc-v/k210/interrupt.c b/libcpu/risc-v/k210/interrupt.c index 45b437c099..b582599daf 100644 --- a/libcpu/risc-v/k210/interrupt.c +++ b/libcpu/risc-v/k210/interrupt.c @@ -270,7 +270,7 @@ struct exception_stack_frame void print_stack_frame(uintptr_t * sp) { - struct exception_stack_frame * esf = (struct exception_stack_frame *)sp; + struct exception_stack_frame * esf = (struct exception_stack_frame *)(sp+1); rt_kprintf("\n=================================================================\n"); rt_kprintf("x1 (ra : Return address ) ==> 0x%08x%08x\n", esf->x1 >> 32 , esf->x1 & UINT32_MAX); -- cgit v1.3.1 From fbd40fc5b8b94cf370fdea9a2433991f43e542f6 Mon Sep 17 00:00:00 2001 From: qz721 <295354721@qq.com> Date: Fri, 29 Mar 2019 20:22:25 +0800 Subject: Add standard rt-thread cache interfaces for arm/cortex-a. Add cache invalidate and clean interfaces. Adjust the default cache type of memory to 'WriteBach with WriteAllocate'. --- libcpu/arm/cortex-a/cache.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ libcpu/arm/cortex-a/mmu.h | 3 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 libcpu/arm/cortex-a/cache.c (limited to 'libcpu') diff --git a/libcpu/arm/cortex-a/cache.c b/libcpu/arm/cortex-a/cache.c new file mode 100644 index 0000000000..6d28d9e9f9 --- /dev/null +++ b/libcpu/arm/cortex-a/cache.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-29 quanzhao the first version + */ +#include +#include + +rt_inline rt_uint32_t rt_cpu_icache_line_size(void) +{ + rt_uint32_t ctr; + asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr)); + return 4 << (ctr & 0xF); +} + +rt_inline rt_uint32_t rt_cpu_dcache_line_size(void) +{ + rt_uint32_t ctr; + asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr)); + return 4 << ((ctr >> 16) & 0xF); +} + +void rt_hw_cpu_icache_invalidate(void *addr, int size) +{ + rt_uint32_t line_size = rt_cpu_icache_line_size(); + rt_uint32_t start_addr = (rt_uint32_t)addr; + rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + + start_addr &= ~(line_size-1); + end_addr &= ~(line_size-1); + while (start_addr < end_addr) + { + asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r"(start_addr)); /* icimvau */ + start_addr += line_size; + } +} + +void rt_hw_cpu_dcache_invalidate(void *addr, int size) +{ + rt_uint32_t line_size = rt_cpu_dcache_line_size(); + rt_uint32_t start_addr = (rt_uint32_t)addr; + rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + + start_addr &= ~(line_size-1); + end_addr &= ~(line_size-1); + while (start_addr < end_addr) + { + asm volatile ("mcr p15, 0, %0, c7, c6, 1" :: "r"(start_addr)); /* dcimvac */ + start_addr += line_size; + } +} + +void rt_hw_cpu_dcache_clean(void *addr, int size) +{ + rt_uint32_t line_size = rt_cpu_dcache_line_size(); + rt_uint32_t start_addr = (rt_uint32_t)addr; + rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + + start_addr &= ~(line_size-1); + end_addr &= ~(line_size-1); + while (start_addr < end_addr) + { + asm volatile ("mcr p15, 0, %0, c7, c10, 1" :: "r"(start_addr)); /* dccmvac */ + start_addr += line_size; + } +} + +void rt_hw_cpu_icache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_INVALIDATE) + rt_hw_cpu_icache_invalidate(addr, size); +} + +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) + rt_hw_cpu_dcache_clean(addr, size); + else if (ops == RT_HW_CACHE_INVALIDATE) + rt_hw_cpu_dcache_invalidate(addr, size); +} + +rt_base_t rt_hw_cpu_icache_status(void) +{ + return 0; +} + +rt_base_t rt_hw_cpu_dcache_status(void) +{ + return 0; +} diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h index deec690c69..fbce6df935 100644 --- a/libcpu/arm/cortex-a/mmu.h +++ b/libcpu/arm/cortex-a/mmu.h @@ -13,6 +13,7 @@ #include #define DESC_SEC (0x2) +#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */ #define MEMWB (3<<2) /* write back, no write allocate */ #define MEMWT (2<<2) /* write through, no write allocate */ #define SHAREDEVICE (1<<2) /* shared device */ @@ -34,7 +35,7 @@ /* device mapping type */ #define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN) /* normal memory mapping type */ -#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC) +#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC) struct mem_desc { -- cgit v1.3.1 From 5d166c389d6c81fbeea3e175100d4922453991ee Mon Sep 17 00:00:00 2001 From: xuzhuoyi Date: Sun, 31 Mar 2019 15:44:24 +0800 Subject: [bsp][gd32e230k-start] Add GD32E230K-START BSP port --- bsp/gd32e230k-start/.config | 288 +++ bsp/gd32e230k-start/Kconfig | 72 + .../Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h | 212 ++ .../CMSIS/GD/GD32E230/Include/system_gd32e230.h | 58 + .../GD/GD32E230/Source/ARM/startup_gd32e230.s | 256 +++ .../GD/GD32E230/Source/IAR/startup_gd32e230.s | 303 +++ .../CMSIS/GD/GD32E230/Source/system_gd32e230.c | 371 ++++ .../Include/gd32e230_adc.h | 351 ++++ .../Include/gd32e230_cmp.h | 162 ++ .../Include/gd32e230_crc.h | 120 ++ .../Include/gd32e230_dbg.h | 123 ++ .../Include/gd32e230_dma.h | 264 +++ .../Include/gd32e230_exti.h | 278 +++ .../Include/gd32e230_fmc.h | 272 +++ .../Include/gd32e230_fwdgt.h | 119 ++ .../Include/gd32e230_gpio.h | 388 ++++ .../Include/gd32e230_i2c.h | 389 ++++ .../Include/gd32e230_misc.h | 86 + .../Include/gd32e230_pmu.h | 146 ++ .../Include/gd32e230_rcu.h | 672 +++++++ .../Include/gd32e230_rtc.h | 561 ++++++ .../Include/gd32e230_spi.h | 424 ++++ .../Include/gd32e230_syscfg.h | 187 ++ .../Include/gd32e230_timer.h | 760 ++++++++ .../Include/gd32e230_usart.h | 614 ++++++ .../Include/gd32e230_wwdgt.h | 88 + .../Source/gd32e230_adc.c | 844 ++++++++ .../Source/gd32e230_cmp.c | 180 ++ .../Source/gd32e230_crc.c | 206 ++ .../Source/gd32e230_dbg.c | 140 ++ .../Source/gd32e230_dma.c | 562 ++++++ .../Source/gd32e230_exti.c | 254 +++ .../Source/gd32e230_fmc.c | 814 ++++++++ .../Source/gd32e230_fwdgt.c | 252 +++ .../Source/gd32e230_gpio.c | 399 ++++ .../Source/gd32e230_i2c.c | 797 ++++++++ .../Source/gd32e230_misc.c | 142 ++ .../Source/gd32e230_pmu.c | 301 +++ .../Source/gd32e230_rcu.c | 1034 ++++++++++ .../Source/gd32e230_rtc.c | 965 +++++++++ .../Source/gd32e230_spi.c | 1003 ++++++++++ .../Source/gd32e230_syscfg.c | 207 ++ .../Source/gd32e230_timer.c | 2059 ++++++++++++++++++++ .../Source/gd32e230_usart.c | 1318 +++++++++++++ .../Source/gd32e230_wwdgt.c | 148 ++ bsp/gd32e230k-start/Libraries/SConscript | 33 + bsp/gd32e230k-start/SConscript | 14 + bsp/gd32e230k-start/SConstruct | 39 + bsp/gd32e230k-start/applications/SConscript | 11 + bsp/gd32e230k-start/applications/main.c | 27 + bsp/gd32e230k-start/drivers/SConscript | 33 + bsp/gd32e230k-start/drivers/board.c | 87 + bsp/gd32e230k-start/drivers/board.h | 47 + bsp/gd32e230k-start/drivers/drv_gpio.c | 539 +++++ bsp/gd32e230k-start/drivers/drv_gpio.h | 18 + bsp/gd32e230k-start/drivers/drv_i2c.c | 381 ++++ bsp/gd32e230k-start/drivers/drv_i2c.h | 29 + bsp/gd32e230k-start/drivers/drv_spi.c | 290 +++ bsp/gd32e230k-start/drivers/drv_spi.h | 19 + bsp/gd32e230k-start/drivers/drv_usart.c | 381 ++++ bsp/gd32e230k-start/drivers/drv_usart.h | 19 + bsp/gd32e230k-start/drivers/gd32e230_libopt.h | 60 + bsp/gd32e230k-start/gd32_rom.icf | 40 + bsp/gd32e230k-start/gd32_rom.ld | 142 ++ bsp/gd32e230k-start/gd32_rom.sct | 15 + bsp/gd32e230k-start/project.uvoptx | 1301 +++++++++++++ bsp/gd32e230k-start/project.uvprojx | 952 +++++++++ bsp/gd32e230k-start/rtconfig.h | 158 ++ bsp/gd32e230k-start/rtconfig.py | 126 ++ bsp/gd32e230k-start/template.uvoptx | 185 ++ bsp/gd32e230k-start/template.uvprojx | 400 ++++ libcpu/arm/cortex-m23/SConscript | 23 + libcpu/arm/cortex-m23/context_gcc.S | 210 ++ libcpu/arm/cortex-m23/context_iar.S | 202 ++ libcpu/arm/cortex-m23/context_rvds.S | 207 ++ libcpu/arm/cortex-m23/cpuport.c | 403 ++++ 76 files changed, 25580 insertions(+) create mode 100644 bsp/gd32e230k-start/.config create mode 100644 bsp/gd32e230k-start/Kconfig create mode 100644 bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h create mode 100644 bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h create mode 100644 bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s create mode 100644 bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s create mode 100644 bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c create mode 100644 bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c create mode 100644 bsp/gd32e230k-start/Libraries/SConscript create mode 100644 bsp/gd32e230k-start/SConscript create mode 100644 bsp/gd32e230k-start/SConstruct create mode 100644 bsp/gd32e230k-start/applications/SConscript create mode 100644 bsp/gd32e230k-start/applications/main.c create mode 100644 bsp/gd32e230k-start/drivers/SConscript create mode 100644 bsp/gd32e230k-start/drivers/board.c create mode 100644 bsp/gd32e230k-start/drivers/board.h create mode 100644 bsp/gd32e230k-start/drivers/drv_gpio.c create mode 100644 bsp/gd32e230k-start/drivers/drv_gpio.h create mode 100644 bsp/gd32e230k-start/drivers/drv_i2c.c create mode 100644 bsp/gd32e230k-start/drivers/drv_i2c.h create mode 100644 bsp/gd32e230k-start/drivers/drv_spi.c create mode 100644 bsp/gd32e230k-start/drivers/drv_spi.h create mode 100644 bsp/gd32e230k-start/drivers/drv_usart.c create mode 100644 bsp/gd32e230k-start/drivers/drv_usart.h create mode 100644 bsp/gd32e230k-start/drivers/gd32e230_libopt.h create mode 100644 bsp/gd32e230k-start/gd32_rom.icf create mode 100644 bsp/gd32e230k-start/gd32_rom.ld create mode 100644 bsp/gd32e230k-start/gd32_rom.sct create mode 100644 bsp/gd32e230k-start/project.uvoptx create mode 100644 bsp/gd32e230k-start/project.uvprojx create mode 100644 bsp/gd32e230k-start/rtconfig.h create mode 100644 bsp/gd32e230k-start/rtconfig.py create mode 100644 bsp/gd32e230k-start/template.uvoptx create mode 100644 bsp/gd32e230k-start/template.uvprojx create mode 100644 libcpu/arm/cortex-m23/SConscript create mode 100644 libcpu/arm/cortex-m23/context_gcc.S create mode 100644 libcpu/arm/cortex-m23/context_iar.S create mode 100644 libcpu/arm/cortex-m23/context_rvds.S create mode 100644 libcpu/arm/cortex-m23/cpuport.c (limited to 'libcpu') diff --git a/bsp/gd32e230k-start/.config b/bsp/gd32e230k-start/.config new file mode 100644 index 0000000000..40cac74cf7 --- /dev/null +++ b/bsp/gd32e230k-start/.config @@ -0,0 +1,288 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +CONFIG_RT_ALIGN_SIZE=4 +# 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=100 +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=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=256 +# 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 is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB 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 is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +# CONFIG_RT_USING_MODULE is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 + +# +# 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_ECHO_DISABLE_DEFAULT is not set +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=437 +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=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +CONFIG_RT_DFS_ELM_REENTRANT=y +CONFIG_RT_USING_DFS_DEVFS=y +# 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_SERIAL_USING_DMA=y +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_USING_I2C_BITOPS is not set +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 is not set +CONFIG_RT_USING_SFUD=y +# CONFIG_RT_SFUD_USING_SFDP is not set +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +# CONFIG_RT_SFUD_DEBUG 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 is not set +# 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 is not set +# CONFIG_RT_USING_LWIP141 is not set +# CONFIG_RT_USING_LWIP202 is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS 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 +# + +# +# RT-Thread GUI Engine +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT 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_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_ONENET is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_IPERF is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_SAMPLES is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_RT_USING_USART0=y +CONFIG_RT_USING_USART1=y +# CONFIG_RT_USING_USART2 is not set +# CONFIG_RT_USING_UART3 is not set +# CONFIG_RT_USING_UART4 is not set +CONFIG_RT_USING_SPI0=y +CONFIG_RT_USING_SPI1=y +# CONFIG_RT_USING_SPI2 is not set +CONFIG_RT_USING_I2C0=y +# CONFIG_RT_USING_I2C1 is not set diff --git a/bsp/gd32e230k-start/Kconfig b/bsp/gd32e230k-start/Kconfig new file mode 100644 index 0000000000..e4706f4d4f --- /dev/null +++ b/bsp/gd32e230k-start/Kconfig @@ -0,0 +1,72 @@ +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" + +config RT_USING_USART0 + bool "Using USART0" + select RT_USING_SERIAL + default y + +config RT_USING_USART1 + bool "Using USART1" + select RT_USING_SERIAL + default n + +config RT_USING_USART2 + bool "Using USART2" + select RT_USING_SERIAL + default n + +config RT_USING_UART3 + bool "Using UART3" + select RT_USING_SERIAL + default n + +config RT_USING_UART4 + bool "Using UART4" + select RT_USING_SERIAL + default n + +config RT_USING_SPI0 + bool "Using SPI0" + select RT_USING_SPI + default y + +config RT_USING_SPI1 + bool "Using SPI1" + select RT_USING_SPI + default n + +config RT_USING_SPI2 + bool "Using SPI2" + select RT_USING_SPI + default n + +config RT_USING_I2C0 + bool "Using I2C0" + select RT_USING_I2C + default n + +config RT_USING_I2C1 + bool "Using I2C1" + select RT_USING_I2C + default n + + + diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h new file mode 100644 index 0000000000..60838636f7 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h @@ -0,0 +1,212 @@ +/*! + \file gd32e230.h + \brief general definitions for GD32E230 + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_H +#define GD32E230_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* define GD32E230 */ +#if !defined (GD32E230) + #define GD32E230 +#endif /* define GD32E230 */ +#if !defined (GD32E230) + #error "Please select the target GD32E230 device used in your application (in gd32e230.h file)" +#endif /* undefine GD32E230 tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0800) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */ +#if !defined (IRC8M_VALUE) +#define IRC8M_VALUE ((uint32_t)8000000) +#endif /* internal 8MHz RC oscillator value */ + +/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */ +#if !defined (IRC8M_STARTUP_TIMEOUT) +#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 8MHz RC oscillator startup timeout */ + +/* define value of internal RC oscillator for ADC in Hz */ +#if !defined (IRC28M_VALUE) +#define IRC28M_VALUE ((uint32_t)28000000) +#endif /* IRC28M_VALUE */ + +#if !defined (IRC48M_VALUE) +#define IRC48M_VALUE ((uint32_t)48000000) +#endif /* IRC48M_VALUE */ + +/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */ +#if !defined (IRC40K_VALUE) +#define IRC40K_VALUE ((uint32_t)40000) +#endif /* internal 40KHz RC oscillator value */ + +/* define value of low speed crystal oscillator (LXTAL)in Hz */ +#if !defined (LXTAL_VALUE) +#define LXTAL_VALUE ((uint32_t)32768) +#endif /* low speed crystal oscillator value */ + +/* GD32E1x0 firmware library version number V1.0 */ +#define __GD32E230_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __GD32E230_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32E230_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32E230_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32E230_STDPERIPH_VERSION ((__GD32E230_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32E230_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32E230_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32E230_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M23 processor and core peripherals */ +#define __CM23_REV 0x0100U /*!< Core revision r1p0 */ +#define __SAUREGION_PRESENT 0U /*!< SAU regions are not present */ +#define __MPU_PRESENT 0U /*!< MPU is present */ +#define __VTOR_PRESENT 1U /*!< VTOR is present */ +#define __NVIC_PRIO_BITS 2U /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ + +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M23 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< non maskable interrupt */ + HardFault_IRQn = -13, /*!< hardfault interrupt */ + + SVCall_IRQn = -5, /*!< sv call interrupt */ + + PendSV_IRQn = -2, /*!< pend sv interrupt */ + SysTick_IRQn = -1, /*!< system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + RTC_IRQn = 2, /*!< RTC through EXTI line interrupt */ + FMC_IRQn = 3, /*!< FMC interrupt */ + RCU_IRQn = 4, /*!< RCU interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI line 0 and 1 interrupts */ + EXTI2_3_IRQn = 6, /*!< EXTI line 2 and 3 interrupts */ + EXTI4_15_IRQn = 7, /*!< EXTI line 4 to 15 interrupts */ + DMA_Channel0_IRQn = 9, /*!< DMA channel 0 interrupt */ + DMA_Channel1_2_IRQn = 10, /*!< DMA channel 1 and channel 2 interrupts */ + DMA_Channel3_4_IRQn = 11, /*!< DMA channel 3 and channel 4 interrupts */ + ADC_CMP_IRQn = 12, /*!< ADC, CMP interrupts */ + TIMER0_BRK_UP_TRG_COM_IRQn = 13, /*!< TIMER0 break, update, trigger and commutation interrupts */ + TIMER0_Channel_IRQn = 14, /*!< TIMER0 channel capture compare interrupts */ + TIMER2_IRQn = 16, /*!< TIMER2 interrupt */ + TIMER5_IRQn = 17, /*!< TIMER5 interrupt */ + TIMER13_IRQn = 19, /*!< TIMER13 interrupt */ + TIMER14_IRQn = 20, /*!< TIMER14 interrupt */ + TIMER15_IRQn = 21, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 22, /*!< TIMER16 interrupt */ + I2C0_EV_IRQn = 23, /*!< I2C0 event interrupt */ + I2C1_EV_IRQn = 24, /*!< I2C1 event interrupt */ + SPI0_IRQn = 25, /*!< SPI0 interrupt */ + SPI1_IRQn = 26, /*!< SPI1 interrupt */ + USART0_IRQn = 27, /*!< USART0 interrupt */ + USART1_IRQn = 28, /*!< USART1 interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm23.h" +#include "system_gd32e230.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ +/* SRAM and peripheral base bit-band region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define RTC_BASE (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address */ +#define CMP_BASE (APB2_BUS_BASE + 0x0000001CU) /*!< CMP base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMA_CHANNEL_BASE (DMA_BASE + 0x00000008U) /*!< DMA channel base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00001000U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x00002000U) /*!< FMC base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address */ +/* advanced high performance bus 2 memory map */ +#define GPIO_BASE (AHB2_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0x40015800U) /*!< DBG base address */ + +#include "gd32e230_libopt.h" + +#ifdef __cplusplus +} +#endif + +#endif /* GD32E230_H */ diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h new file mode 100644 index 0000000000..45441bd546 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32e230.h + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Header File for + GD32E230 Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32E230_H +#define SYSTEM_GD32E230_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit (void); +/* update the SystemCoreClock with current core clock retrieved from cpu registers */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32E230_H */ diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s new file mode 100644 index 0000000000..8b001a390f --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s @@ -0,0 +1,256 @@ +;/*! +; \file startup_gd32e230.s +; \brief start up file +; +; \version 2018-6-19, V1.0.0, firmware for GD32E230 +;*/ +; +;/* +; Copyright (c) 2018, GigaDevice Semiconductor Inc. +; +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without modification, +;are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, this +; list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of the copyright holder nor the names of its contributors +; may be used to endorse or promote products derived from this software without +; specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +;OF SUCH DAMAGE. +;*/ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD 0 ; Reserved + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel Capture Compare + DCD 0 ; Reserved + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_IRQHandler ; 33:TIMER5 + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA_Channel0_IRQHandler [WEAK] + EXPORT DMA_Channel1_2_IRQHandler [WEAK] + EXPORT DMA_Channel3_4_IRQHandler [WEAK] + EXPORT ADC_CMP_IRQHandler [WEAK] + EXPORT TIMER0_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIMER0_Channel_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER5_IRQHandler [WEAK] + EXPORT TIMER13_IRQHandler [WEAK] + EXPORT TIMER14_IRQHandler [WEAK] + EXPORT TIMER15_IRQHandler [WEAK] + EXPORT TIMER16_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +RTC_IRQHandler +FMC_IRQHandler +RCU_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA_Channel0_IRQHandler +DMA_Channel1_2_IRQHandler +DMA_Channel3_4_IRQHandler +ADC_CMP_IRQHandler +TIMER0_BRK_UP_TRG_COM_IRQHandler +TIMER0_Channel_IRQHandler +TIMER2_IRQHandler +TIMER5_IRQHandler +TIMER13_IRQHandler +TIMER14_IRQHandler +TIMER15_IRQHandler +TIMER16_IRQHandler +I2C0_EV_IRQHandler +I2C1_EV_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +I2C0_ER_IRQHandler +I2C1_ER_IRQHandler + + B . + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s new file mode 100644 index 0000000000..a491356ce0 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s @@ -0,0 +1,303 @@ +;/*! +; \file startup_gd32e230.s +; \brief start up file +; +; \version 2018-06-19, V1.0.0, firmware for GD32E230 +;*/ +; +;/* +; Copyright (c) 2018, GigaDevice Semiconductor Inc. +; +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without modification, +;are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, this +; list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of the copyright holder nor the names of its contributors +; may be used to endorse or promote products derived from this software without +; specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +;OF SUCH DAMAGE. +;*/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Vector Number 1,Reset Handler + + DCD NMI_Handler ; Vector Number 2,NMI Handler + DCD HardFault_Handler ; Vector Number 3,Hard Fault Handler + DCD MemManage_Handler ; Vector Number 4,MPU Fault Handler + DCD BusFault_Handler ; Vector Number 5,Bus Fault Handler + DCD UsageFault_Handler ; Vector Number 6,Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; Vector Number 11,SVCall Handler + DCD DebugMon_Handler ; Vector Number 12,Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; Vector Number 14,PendSV Handler + DCD SysTick_Handler ; Vector Number 15,SysTick Handler + + ; External Interrupts + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD 0 ; Reserved + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel Capture Compare + DCD 0 ; Reserved + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_IRQHandler ; 33:TIMER5 + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK LVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LVD_IRQHandler + B LVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_IRQHandler + B RCU_IRQHandler + + PUBWEAK EXTI0_1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_1_IRQHandler + B EXTI0_1_IRQHandler + + PUBWEAK EXTI2_3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_3_IRQHandler + B EXTI2_3_IRQHandler + + PUBWEAK EXTI4_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_15_IRQHandler + B EXTI4_15_IRQHandler + + PUBWEAK DMA_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel0_IRQHandler + B DMA_Channel0_IRQHandler + + PUBWEAK DMA_Channel1_2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel1_2_IRQHandler + B DMA_Channel1_2_IRQHandler + + PUBWEAK DMA_Channel3_4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel3_4_IRQHandler + B DMA_Channel3_4_IRQHandler + + PUBWEAK ADC_CMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_CMP_IRQHandler + B ADC_CMP_IRQHandler + + PUBWEAK TIMER0_BRK_UP_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_UP_TRG_COM_IRQHandler + B TIMER0_BRK_UP_TRG_COM_IRQHandler + + PUBWEAK TIMER0_Channel_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_Channel_IRQHandler + B TIMER0_Channel_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_IRQHandler + B TIMER5_IRQHandler + + PUBWEAK TIMER13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER13_IRQHandler + B TIMER13_IRQHandler + + PUBWEAK TIMER14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER14_IRQHandler + B TIMER14_IRQHandler + + PUBWEAK TIMER15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER15_IRQHandler + B TIMER15_IRQHandler + + PUBWEAK TIMER16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER16_IRQHandler + B TIMER16_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + END \ No newline at end of file diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c new file mode 100644 index 0000000000..a4768d181f --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c @@ -0,0 +1,371 @@ +/*! + \file system_gd32e230.c + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Source File for + GD32E1x0 Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32e230.h" + +/* system frequency define */ +#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ + +#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) +//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) +#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) + +#define SEL_IRC8M 0x00 +#define SEL_HXTAL 0x01 +#define SEL_PLL 0x02 + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_8M_HXTAL +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL; +static void system_clock_8m_hxtal(void); + +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; +static void system_clock_72m_hxtal(void); + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2; +static void system_clock_72m_irc8m(void); + +#else +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M; +static void system_clock_8m_irc8m(void); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit (void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV); + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~(RCU_CFG1_PREDV); + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL); + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCPSC2; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_INT = 0x00000000U; + + /* configure system clock */ + system_clock_config(); + +#ifdef VECT_TAB_SRAM + nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET); +#else + nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET); +#endif +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_8M_HXTAL + system_clock_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) + system_clock_72m_irc8m(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2) + system_clock_72m_irc48m(); +#else + system_clock_8m_irc8m(); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ +} + +#ifdef __SYSTEM_CLOCK_8M_HXTAL +/*! + \brief configure the system clock to 8M by HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_HXTAL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +/*! + \brief configure the system clock to 72M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + while(1){ + } + } + + FMC_WS &= ~FMC_WS_WSCNT; + FMC_WS |= WS_WSCNT_2; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* PLL = HXTAL * 9 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_IRC8MSTB); + } + while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + while(1){ + } + } + + FMC_WS &= ~FMC_WS_WSCNT; + FMC_WS |= WS_WSCNT_2; + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + /* PLL = (IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#else +/*! + \brief configure the system clock to 8M by IRC8M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC8M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC8M; + + /* wait until IRC8M is selected as system clock */ + while(0U != (RCU_CFG0 & RCU_SCSS_IRC8M)){ + } +} +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate (void) +{ + uint32_t sws = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + SystemCoreClock = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else if(15U == pllmf){ + pllmf = 16U; + }else{ + pllmf += 2U; + } + + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf; + }else{ + SystemCoreClock = (IRC8M_VALUE >> 1) * pllmf; + } + break; + /* IRC8M is selected as CK_SYS */ + default: + SystemCoreClock = IRC8M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock >>= clk_exp; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h new file mode 100644 index 0000000000..2ffbec390e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h @@ -0,0 +1,351 @@ +/*! + \file gd32e230_adc.h + \brief definitions for the ADC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_ADC_H +#define GD32E230_ADC_H + +#include "gd32e230.h" + +/* ADC definitions */ +#define ADC ADC_BASE + +/* registers definitions */ +#define ADC_STAT REG32(ADC + 0x00U) /*!< ADC status register */ +#define ADC_CTL0 REG32(ADC + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1 REG32(ADC + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0 REG32(ADC + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1 REG32(ADC + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0 REG32(ADC + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1 REG32(ADC + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2 REG32(ADC + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3 REG32(ADC + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT REG32(ADC + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT REG32(ADC + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0 REG32(ADC + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1 REG32(ADC + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2 REG32(ADC + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ REG32(ADC + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0 REG32(ADC + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1 REG32(ADC + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2 REG32(ADC + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3 REG32(ADC + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA REG32(ADC + 0x4CU) /*!< ADC regular data register */ +#define ADC_OVSAMPCTL REG32(ADC + 0x80U) /*!< ADC oversampling control register */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion flag */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion flag */ +#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(12,14) /*!< external trigger select for inserted channel */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */ +#define ADC_CTL1_ETSRC BITS(17,19) /*!< external trigger select for regular channel */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger enable for regular channel */ +#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */ +#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */ +#define ADC_CTL1_TSVREN BIT(23) /*!< enable channel 16 and 17 */ + +/* ADC_SAMPTx x=0,1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel n(n=0..9,16 and 17) sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ + +/* ADC_WDHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WDLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx x=0..2 */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< n conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< n conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted channel x conversion data */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular channel data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ + +/* constants definitions */ +/* ADC flag definitions */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion flag */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted channel group conversion flag */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< start flag of inserted channel group */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< start flag of regular channel group */ + +/* adc_ctl0 register value */ +#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< number of conversions in discontinuous mode */ + +/* ADC special function */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< right alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< left alignment */ + +/* external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< TIMER0 CH0 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< TIMER0 CH1 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< TIMER0 CH2 event select */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< TIMER2 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T14_CH0 CTL1_ETSRC(5) /*!< TIMER14 CH0 event select */ +#define ADC_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */ +#define ADC_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */ + +/* external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< TIMER2 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T14_TRGO CTL1_ETSIC(5) /*!< TIMER14 TRGO event select */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */ +#define ADC_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */ + +/* adc_samptx register value */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */ +#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */ +#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */ +#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */ +#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */ +#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */ +#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */ +#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */ + +/* ADC data offset for inserted channel x*/ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog high threshold */ +#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog low threshold */ +#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC regular channel group length */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) + +/* ADC inserted channel group length */ +#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) + +/* ADC resolution definitions */ +#define CTL0_DRES(regval) (BITS(24,25) & ((regval) << 24)) /*!< ADC resolution */ +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ + +/* ADC oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* ADC oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* ADC triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0U /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1U /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< ADC regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ + +/* ADC interrupt definitions */ +#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ +#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt flag */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */ + +/* function declarations */ +/* reset ADC */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(void); +/* disable ADC interface */ +void adc_disable(void); + +/* ADC calibration and reset calibration */ +void adc_calibration_enable(void); +/* enable DMA request */ +void adc_dma_mode_enable(void); +/* disable DMA request */ +void adc_dma_mode_disable(void); + +/* enable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_enable(void); +/* disable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_disable(void); + +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length); +/* configure ADC special function */ +void adc_special_function_config(uint32_t function, ControlStatus newvalue); + +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t data_alignment); +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint8_t channel_group, uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset); +/* enable ADC external trigger */ +void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint8_t channel_group); + +/* read ADC regular group data register */ +uint16_t adc_regular_data_read(void); +/* read ADC inserted group data register */ +uint16_t adc_inserted_data_read(uint8_t inserted_channel); + +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t flag); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t flag); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t flag); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t interrupt); + +/* configure ADC analog watchdog single channel */ +void adc_watchdog_single_channel_enable(uint8_t channel); +/* configure ADC analog watchdog group channel */ +void adc_watchdog_group_channel_enable(uint8_t channel_group); +/* disable ADC analog watchdog */ +void adc_watchdog_disable(void); +/* configure ADC analog watchdog threshold */ +void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold); + +/* configure ADC resolution */ +void adc_resolution_config(uint32_t resolution); +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(void); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(void); + +#endif /* GD32E230_ADC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h new file mode 100644 index 0000000000..aa9d8a9b2c --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h @@ -0,0 +1,162 @@ +/*! + \file gd32e230_cmp.h + \brief definitions for the CMP + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_CMP_H +#define GD32E230_CMP_H + +#include "gd32e230.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP_CS REG32((CMP) + 0x00U) /*!< CMP control and status register */ + +/* CMP_CS bits definitions */ +#define CMP_CS_CMPEN BIT(0) /*!< CMP enable */ +#define CMP_CS_CMPSW BIT(1) /*!< CMP switch */ +#define CMP_CS_CMPM BITS(2,3) /*!< CMP mode */ +#define CMP_CS_CMPMSEL BITS(4,6) /*!< COMP_M input selection */ +#define CMP_CS_CMPOSEL BITS(8,10) /*!< CMP output selection */ +#define CMP_CS_CMPPL BIT(11) /*!< polarity of CMP output */ +#define CMP_CS_CMPHST BITS(12,13) /*!< CMP hysteresis */ +#define CMP_CS_CMPO BIT(14) /*!< CMP output */ +#define CMP_CS_CMPLK BIT(15) /*!< CMP lock */ + +/* consts definitions */ +/* operating mode */ +typedef enum{ + CMP_HIGHSPEED = 0, /*!< high speed mode */ + CMP_MIDDLESPEED, /*!< medium speed mode */ + CMP_LOWSPEED, /*!< low speed mode */ + CMP_VERYLOWSPEED /*!< very-low speed mode */ +}operating_mode_enum; + +/* inverting input */ +typedef enum{ + CMP_1_4VREFINT = 0, /*!< VREFINT /4 input */ + CMP_1_2VREFINT, /*!< VREFINT /2 input */ + CMP_3_4VREFINT, /*!< VREFINT *3/4 input */ + CMP_VREFINT, /*!< VREFINT input */ + CMP_PA4, /*!< PA4 input */ + CMP_PA5, /*!< PA5 input */ + CMP_PA0, /*!< PA0 input */ + CMP_PA2 /*!< PA2 input */ +}inverting_input_enum; + +/* hysteresis */ +typedef enum{ + CMP_HYSTERESIS_NO = 0, /*!< output no hysteresis */ + CMP_HYSTERESIS_LOW, /*!< output low hysteresis */ + CMP_HYSTERESIS_MIDDLE, /*!< output middle hysteresis */ + CMP_HYSTERESIS_HIGH /*!< output high hysteresis */ +}cmp_hysteresis_enum; + +/* output */ +typedef enum{ + CMP_OUTPUT_NONE = 0x0U, /*!< output no selection */ + CMP_OUTPUT_TIMER0BKIN = 0x1U, /*!< TIMER 0 break input */ + CMP_OUTPUT_TIMER0IC0 = 0x2U, /*!< TIMER 0 channel0 input capture */ + CMP_OUTPUT_TIMER0OCPRECLR = 0x3U, /*!< TIMER 0 OCPRE_CLR input */ + CMP_OUTPUT_TIMER2IC0 = 0x06U, /*!< TIMER 2 channel0 input capture */ + CMP_OUTPUT_TIMER2OCPRECLR = 0x7U /*!< TIMER 2 OCPRE_CLR input */ +}cmp_output_enum; + +/* CMP mode */ +#define CS_CMPM(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define CS_CMPM_HIGHSPEED CS_CMPM(0) /*!< CMP mode high speed */ +#define CS_CMPM_MIDDLESPEED CS_CMPM(1) /*!< CMP mode middle speed */ +#define CS_CMPM_LOWSPEED CS_CMPM(2) /*!< CMP mode low speed */ +#define CS_CMPM_VERYLOWSPEED CS_CMPM(3) /*!< CMP mode very low speed */ + +/* comparator inverting input */ +#define CS_CMPMSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CS_CMPMSEL_1_4VREFINT CS_CMPMSEL(0) /*!< CMP inverting input 1/4 Vrefint */ +#define CS_CMPMSEL_1_2VREFINT CS_CMPMSEL(1) /*!< CMP inverting input 1/2 Vrefint */ +#define CS_CMPMSEL_3_4VREFINT CS_CMPMSEL(2) /*!< CMP inverting input 3/4 Vrefint */ +#define CS_CMPMSEL_VREFINT CS_CMPMSEL(3) /*!< CMP inverting input Vrefint */ +#define CS_CMPMSEL_PA4 CS_CMPMSEL(4) /*!< CMP inverting input PA4*/ +#define CS_CMPMSEL_PA5 CS_CMPMSEL(5) /*!< CMP inverting input PA5*/ +#define CS_CMPMSEL_PA0 CS_CMPMSEL(6) /*!< CMP inverting input PA0*/ +#define CS_CMPMSEL_PA2 CS_CMPMSEL(7) /*!< CMP inverting input PA2*/ + +/* CMP output */ +#define CS_CMPOSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define CS_CMPOSEL_OUTPUT_NONE CS_CMPOSEL(0) /*!< CMP output none */ +#define CS_CMPOSEL_OUTPUT_TIMER0BKIN CS_CMPOSEL(1) /*!< CMP output TIMER 0 break input */ +#define CS_CMPOSEL_OUTPUT_TIMER0IC0 CS_CMPOSEL(2) /*!< CMP output TIMER 0 channel 0 input capture */ +#define CS_CMPOSEL_OUTPUT_TIMER0OCPRECLR CS_CMPOSEL(3) /*!< CMP output TIMER 0 ocpreclear input */ +#define CS_CMPOSEL_OUTPUT_TIMER2IC0 CS_CMPOSEL(6) /*!< CMP output TIMER 2 channle 0 input capture */ +#define CS_CMPOSEL_OUTPUT_TIMER2OCPRECLR CS_CMPOSEL(7) /*!< CMP output TIMER 2 ocpreclear input */ + +/* CMP hysteresis */ +#define CS_CMPHST(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define CS_CMPHST_HYSTERESIS_NO CS_CMPHST(0) /*!< CMP output no hysteresis */ +#define CS_CMPHST_HYSTERESIS_LOW CS_CMPHST(1) /*!< CMP output low hysteresis */ +#define CS_CMPHST_HYSTERESIS_MIDDLE CS_CMPHST(2) /*!< CMP output middle hysteresis */ +#define CS_CMPHST_HYSTERESIS_HIGH CS_CMPHST(3) /*!< CMP output high hysteresis */ + +/* CMP output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001) /*!< comparator output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000) /*!< comparator output low */ + +/* output polarity of comparator */ +#define CMP_OUTPUT_POLARITY_INVERTED ((uint32_t)0x00000001) /*!< output is inverted */ +#define CMP_OUTPUT_POLARITY_NOINVERTED ((uint32_t)0x00000000) /*!< output is not inverted */ + +/* function declarations */ + +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(void); +/* CMP mode init */ +void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis); +/* CMP output init */ +void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity); +/* enable CMP */ +void cmp_enable(void); +/* disable CMP */ +void cmp_disable(void); +/* enable CMP switch */ +void cmp_switch_enable(void); +/* disable CMP switch */ +void cmp_switch_disable(void); +/* get output level */ +uint32_t cmp_output_level_get(void); +/* lock the CMP */ +void cmp_lock_enable(void); + +#endif /* GD32E230_CMP_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h new file mode 100644 index 0000000000..619ce47970 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h @@ -0,0 +1,120 @@ +/*! + \file gd32e230_crc.h + \brief definitions for the CRC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_CRC_H +#define GD32E230_CRC_H + +#include "gd32e230.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32((CRC) + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32((CRC) + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32((CRC) + 0x08U) /*!< CRC control register */ +#define CRC_IDATA REG32((CRC) + 0x10U) /*!< CRC initialization data register */ +#define CRC_POLY REG32((CRC) + 0x14U) /*!< CRC polynomial register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC data bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#define CRC_CTL_PS BITS(3,4) /*!< size of polynomial function bits */ +#define CRC_CTL_REV_I BITS(5,6) /*!< input data reverse function bits */ +#define CRC_CTL_REV_O BIT(7) /*!< output data reverse function bit */ + +/* CRC_INIT */ +#define CRC_IDATA_IDATA BITS(0,31) /*!< CRC initialization data bits */ + +/* CRC_POLY */ +#define CRC_POLY_POLY BITS(0,31) /*!< CRC polynomial value bits */ + +/* constants definitions */ +/* size of polynomial function */ +#define CTL_PS(regval) (BITS(3, 4) & ((regval) << 3)) +#define CRC_CTL_PS_32 CTL_PS(0) /*!< 32-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_16 CTL_PS(1) /*!< 16-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_8 CTL_PS(2) /*!< 8-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_7 CTL_PS(3) /*!< 7-bit polynomial for CRC calculation */ + +/* input data reverse function */ +#define CTL_REV_I(regval) (BITS(5, 6) & ((regval) << 5)) +#define CRC_INPUT_DATA_NOT CTL_REV_I(0) /*!< input data not reverse */ +#define CRC_INPUT_DATA_BYTE CTL_REV_I(1) /*!< input data reversed by byte type */ +#define CRC_INPUT_DATA_HALFWORD CTL_REV_I(2) /*!< input data reversed by half-word type */ +#define CRC_INPUT_DATA_WORD CTL_REV_I(3) /*!< input data reversed by word type */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); + +/* enable the reverse operation of output data */ +void crc_reverse_output_data_enable(void); +/* disable the reverse operation of output data */ +void crc_reverse_output_data_disable(void); + +/* reset data register to the value of initializaiton data register */ +void crc_data_register_reset(void); +/* read the data register */ +uint32_t crc_data_register_read(void); + +/* read the free data register */ +uint8_t crc_free_data_register_read(void); +/* write the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* write the initial value register */ +void crc_init_data_register_write(uint32_t init_data); +/* configure the CRC input data function */ +void crc_input_data_reverse_config(uint32_t data_reverse); + +/* configure the CRC size of polynomial function */ +void crc_polynomial_size_set(uint32_t poly_size); +/* configure the CRC polynomial value function */ +void crc_polynomial_set(uint32_t poly); + +/* CRC calculate a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* CRC calculate a 32-bit data array */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32E230_CRC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h new file mode 100644 index 0000000000..4a07da903e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h @@ -0,0 +1,123 @@ +/*! + \file gd32e230_dbg.h + \brief definitions for the DBG + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_DBG_H +#define GD32E230_DBG_H + +#include "gd32e230.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL0_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL0_TIMER0_HOLD BIT(10) /*!< TIMER0 counter kept when core is halted */ +#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< TIMER2 counter kept when core is halted */ +#define DBG_CTL0_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL0_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL0_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL0_TIMER13_HOLD BIT(27) /*!< hold TIMER13 counter when core is halted */ + +/* DBG_CTL1 */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_TIMER14_HOLD BIT(16) /*!< hold TIMER14 counter when core is halted */ +#define DBG_CTL1_TIMER15_HOLD BIT(17) /*!< hold TIMER15 counter when core is halted */ +#define DBG_CTL1_TIMER16_HOLD BIT(18) /*!< hold TIMER16 counter when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* define the peripheral debug hold bit position and its register index offset */ +#define DBG_REGIDX_BIT(regidx, bitpos) (((regidx) << 6) | (bitpos)) +#define DBG_REG_VAL(periph) (REG32(DBG + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +enum dbg_reg_idx +{ + DBG_IDX_CTL0 = 0x04U, + DBG_IDX_CTL1 = 0x08U, +}; + +/* peripherals hold bit */ +typedef enum +{ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< FWDGT hold bit */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< WWDGT hold bit */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U), /*!< TIMER0 hold bit */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< TIMER2 hold bit */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U), /*!< TIMER5 hold bit */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U), /*!< TIMER13 hold bit */ + DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U), /*!< TIMER14 hold bit */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U), /*!< TIMER15 hold bit */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U), /*!< TIMER16 hold bit */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< I2C0 hold bit */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< I2C1 hold bit */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< RTC hold bit */ +}dbg_periph_enum; + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); + +#endif /* GD32E230_DBG_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h new file mode 100644 index 0000000000..2205e1bdce --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h @@ -0,0 +1,264 @@ +/*! + \file gd32e230_dma.h + \brief definitions for the DMA + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_DMA_H +#define GD32E230_DMA_H + +#include "gd32e230.h" + +/* DMA definitions */ +#define DMA DMA_BASE /*!< DMA base address */ + +/* registers definitions */ +#define DMA_INTF REG32(DMA + 0x00U) /*!< DMA interrupt flag register */ +#define DMA_INTC REG32(DMA + 0x04U) /*!< DMA interrupt flag clear register */ +#define DMA_CH0CTL REG32(DMA + 0x08U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT REG32(DMA + 0x0CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR REG32(DMA + 0x10U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR REG32(DMA + 0x14U) /*!< DMA channel 0 memory base address register */ +#define DMA_CH1CTL REG32(DMA + 0x1CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT REG32(DMA + 0x20U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR REG32(DMA + 0x24U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR REG32(DMA + 0x28U) /*!< DMA channel 1 memory base address register */ +#define DMA_CH2CTL REG32(DMA + 0x30U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT REG32(DMA + 0x34U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR REG32(DMA + 0x38U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR REG32(DMA + 0x3CU) /*!< DMA channel 2 memory base address register */ +#define DMA_CH3CTL REG32(DMA + 0x44U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT REG32(DMA + 0x48U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR REG32(DMA + 0x4CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR REG32(DMA + 0x50U) /*!< DMA channel 3 memory base address register */ +#define DMA_CH4CTL REG32(DMA + 0x58U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT REG32(DMA + 0x5CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR REG32(DMA + 0x60U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR REG32(DMA + 0x64U) /*!< DMA channel 4 memory base address register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */ +#define DMA_INTF_FTFIF BIT(1) /*!< full transfer finish flag of channel */ +#define DMA_INTF_HTFIF BIT(2) /*!< half transfer finish flag of channel */ +#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */ + +/* DMA_INTC */ +#define DMA_INTC_GIFC BIT(0) /*!< clear global interrupt flag of channel */ +#define DMA_INTC_FTFIFC BIT(1) /*!< clear transfer finish flag of channel */ +#define DMA_INTC_HTFIFC BIT(2) /*!< clear half transfer finish flag of channel */ +#define DMA_INTC_ERRIFC BIT(3) /*!< clear error flag of channel */ + +/* DMA_CHxCTL,x=0..4 */ +#define DMA_CHXCTL_CHEN BIT(0) /*!< channel x enable */ +#define DMA_CHXCTL_FTFIE BIT(1) /*!< enable bit for channel x transfer complete interrupt */ +#define DMA_CHXCTL_HTFIE BIT(2) /*!< enable bit for channel x transfer half complete interrupt */ +#define DMA_CHXCTL_ERRIE BIT(3) /*!< enable bit for channel x error interrupt */ +#define DMA_CHXCTL_DIR BIT(4) /*!< direction of the data transfer on the channel */ +#define DMA_CHXCTL_CMEN BIT(5) /*!< circulation mode */ +#define DMA_CHXCTL_PNAGA BIT(6) /*!< next address generation algorithm of peripheral */ +#define DMA_CHXCTL_MNAGA BIT(7) /*!< next address generation algorithm of memory */ +#define DMA_CHXCTL_PWIDTH BITS(8,9) /*!< transfer data size of peripheral */ +#define DMA_CHXCTL_MWIDTH BITS(10,11) /*!< transfer data size of memory */ +#define DMA_CHXCTL_PRIO BITS(12,13) /*!< priority level of channelx */ +#define DMA_CHXCTL_M2M BIT(14) /*!< memory to memory mode */ + +/* DMA_CHxCNT,x=0..4 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR,x=0..4 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxMADDR,x=0..4 */ +#define DMA_CHXMADDR_MADDR BITS(0,31) /*!< memory base address */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< DMA Channel0 */ + DMA_CH1, /*!< DMA Channel1 */ + DMA_CH2, /*!< DMA Channel2 */ + DMA_CH3, /*!< DMA Channel3 */ + DMA_CH4, /*!< DMA Channel4 */ +} dma_channel_enum; + +/* DMA initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ + uint8_t periph_inc; /*!< peripheral increasing mode */ + uint8_t memory_inc; /*!< memory increasing mode */ + uint8_t direction; /*!< channel data transfer direction */ +} dma_parameter_struct; + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE (DMA_INTF_GIF | DMA_INTF_FTFIF | \ + DMA_INTF_HTFIF | DMA_INTF_ERRIF) + +#define DMA_FLAG_ADD(flag,shift) ((flag) << ((uint32_t)(shift) * 4U)) /*!< DMA channel flag shift */ + +/* DMA_CHCTL base address */ +#define DMA_CHXCTL_BASE (DMA + 0x08U) /*!< the base address of DMA channel CHXCTL register */ +#define DMA_CHXCNT_BASE (DMA + 0x0CU) /*!< the base address of DMA channel CHXCNT register */ +#define DMA_CHXPADDR_BASE (DMA + 0x10U) /*!< the base address of DMA channel CHXPADDR register */ +#define DMA_CHXMADDR_BASE (DMA + 0x14U) /*!< the base address of DMA channel CHXMADDR register */ + +/* DMA channel shift bit */ +#define DMA_CHCTL(channel) REG32(DMA_CHXCTL_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* DMA_INTF register */ +/* interrupt flag bits */ +#define DMA_INT_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */ +#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_ERR DMA_INTF_ERRIF /*!< error interrupt flag of channel */ + +/* flag bits */ +#define DMA_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */ +#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag of channel */ +#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag of channel */ +#define DMA_FLAG_ERR DMA_INTF_ERRIF /*!< error flag of channel */ + +/* DMA_CHxCTL register */ +/* interrupt enable bits */ +#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< enable bit for channel full transfer finish interrupt */ +#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< enable bit for channel half transfer finish interrupt */ +#define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for channel error interrupt */ + +/* transfer direction */ +#define DMA_PERIPHERAL_TO_MEMORY ((uint32_t)0x00000000U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint32_t)0x00000001U) /*!< read from memory and write to peripheral */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is increasing address mode */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000000U) /*!< next address of memory is fixed address mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000001U) /*!< next address of memory is increasing address mode */ + +/* transfer data size of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((regval) << 8)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PWIDTH(0U) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1U) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2U) /*!< transfer data size of peripheral is 32-bit */ + +/* transfer data size of memory */ +#define CHCTL_MWIDTH(regval) (BITS(10,11) & ((regval) << 10)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0U) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1U) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2U) /*!< transfer data size of memory is 32-bit */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((regval) << 12)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0U) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1U) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2U) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3U) /*!< ultra high priority */ + +/* DMA_CHxCNT register */ +/* transfer counter */ +#define DMA_CHANNEL_CNT_MASK DMA_CHXCNT_CNT + +/* function declarations */ +/* deinitialize DMA a channel registers */ +void dma_deinit(dma_channel_enum channelx); +/* initialize the parameters of DMA struct with the default values */ +void dma_struct_para_init(dma_parameter_struct* init_struct); +/* initialize DMA channel */ +void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(dma_channel_enum channelx); + +/* set DMA peripheral base address */ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address); +/* set DMA memory base address */ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t mwidth); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t pwidth); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction); + +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* check DMA flag and interrupt enable bit is set or not */ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source); + +#endif /* GD32E230_DMA_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h new file mode 100644 index 0000000000..4d8b875c4a --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h @@ -0,0 +1,278 @@ +/*! + \file gd32e230_exti.h + \brief definitions for the EXTI + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_EXTI_H +#define GD32E230_EXTI_H + +#include "gd32e230.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ +#define EXTI_INTEN_INTEN23 BIT(23) /*!< interrupt from line 23 */ +#define EXTI_INTEN_INTEN24 BIT(24) /*!< interrupt from line 24 */ +#define EXTI_INTEN_INTEN25 BIT(25) /*!< interrupt from line 25 */ +#define EXTI_INTEN_INTEN26 BIT(26) /*!< interrupt from line 26 */ +#define EXTI_INTEN_INTEN27 BIT(27) /*!< interrupt from line 27 */ + +/* EXTI_EVEN */ +#define EXTI_EVEN_EVEN0 BIT(0) /*!< event from line 0 */ +#define EXTI_EVEN_EVEN1 BIT(1) /*!< event from line 1 */ +#define EXTI_EVEN_EVEN2 BIT(2) /*!< event from line 2 */ +#define EXTI_EVEN_EVEN3 BIT(3) /*!< event from line 3 */ +#define EXTI_EVEN_EVEN4 BIT(4) /*!< event from line 4 */ +#define EXTI_EVEN_EVEN5 BIT(5) /*!< event from line 5 */ +#define EXTI_EVEN_EVEN6 BIT(6) /*!< event from line 6 */ +#define EXTI_EVEN_EVEN7 BIT(7) /*!< event from line 7 */ +#define EXTI_EVEN_EVEN8 BIT(8) /*!< event from line 8 */ +#define EXTI_EVEN_EVEN9 BIT(9) /*!< event from line 9 */ +#define EXTI_EVEN_EVEN10 BIT(10) /*!< event from line 10 */ +#define EXTI_EVEN_EVEN11 BIT(11) /*!< event from line 11 */ +#define EXTI_EVEN_EVEN12 BIT(12) /*!< event from line 12 */ +#define EXTI_EVEN_EVEN13 BIT(13) /*!< event from line 13 */ +#define EXTI_EVEN_EVEN14 BIT(14) /*!< event from line 14 */ +#define EXTI_EVEN_EVEN15 BIT(15) /*!< event from line 15 */ +#define EXTI_EVEN_EVEN16 BIT(16) /*!< event from line 16 */ +#define EXTI_EVEN_EVEN17 BIT(17) /*!< event from line 17 */ +#define EXTI_EVEN_EVEN18 BIT(18) /*!< event from line 18 */ +#define EXTI_EVEN_EVEN19 BIT(19) /*!< event from line 19 */ +#define EXTI_EVEN_EVEN20 BIT(20) /*!< event from line 20 */ +#define EXTI_EVEN_EVEN21 BIT(21) /*!< event from line 21 */ +#define EXTI_EVEN_EVEN22 BIT(22) /*!< event from line 22 */ +#define EXTI_EVEN_EVEN23 BIT(23) /*!< event from line 23 */ +#define EXTI_EVEN_EVEN24 BIT(24) /*!< event from line 24 */ +#define EXTI_EVEN_EVEN25 BIT(25) /*!< event from line 25 */ +#define EXTI_EVEN_EVEN26 BIT(26) /*!< event from line 26 */ +#define EXTI_EVEN_EVEN27 BIT(27) /*!< event from line 27 */ + +/* EXTI_RTEN */ +#define EXTI_RTEN_RTEN0 BIT(0) /*!< rising edge from line 0 */ +#define EXTI_RTEN_RTEN1 BIT(1) /*!< rising edge from line 1 */ +#define EXTI_RTEN_RTEN2 BIT(2) /*!< rising edge from line 2 */ +#define EXTI_RTEN_RTEN3 BIT(3) /*!< rising edge from line 3 */ +#define EXTI_RTEN_RTEN4 BIT(4) /*!< rising edge from line 4 */ +#define EXTI_RTEN_RTEN5 BIT(5) /*!< rising edge from line 5 */ +#define EXTI_RTEN_RTEN6 BIT(6) /*!< rising edge from line 6 */ +#define EXTI_RTEN_RTEN7 BIT(7) /*!< rising edge from line 7 */ +#define EXTI_RTEN_RTEN8 BIT(8) /*!< rising edge from line 8 */ +#define EXTI_RTEN_RTEN9 BIT(9) /*!< rising edge from line 9 */ +#define EXTI_RTEN_RTEN10 BIT(10) /*!< rising edge from line 10 */ +#define EXTI_RTEN_RTEN11 BIT(11) /*!< rising edge from line 11 */ +#define EXTI_RTEN_RTEN12 BIT(12) /*!< rising edge from line 12 */ +#define EXTI_RTEN_RTEN13 BIT(13) /*!< rising edge from line 13 */ +#define EXTI_RTEN_RTEN14 BIT(14) /*!< rising edge from line 14 */ +#define EXTI_RTEN_RTEN15 BIT(15) /*!< rising edge from line 15 */ +#define EXTI_RTEN_RTEN16 BIT(16) /*!< rising edge from line 16 */ +#define EXTI_RTEN_RTEN17 BIT(17) /*!< rising edge from line 17 */ +#define EXTI_RTEN_RTEN19 BIT(19) /*!< rising edge from line 19 */ +#define EXTI_RTEN_RTEN21 BIT(21) /*!< rising edge from line 21 */ + +/* EXTI_FTEN */ +#define EXTI_FTEN_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */ + +/* EXTI_SWIEV */ +#define EXTI_SWIEV_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ + +/* constants definitions */ +/* EXTI line number */ +typedef enum +{ + EXTI_0 = BIT(0), /*!< EXTI line 0 */ + EXTI_1 = BIT(1), /*!< EXTI line 1 */ + EXTI_2 = BIT(2), /*!< EXTI line 2 */ + EXTI_3 = BIT(3), /*!< EXTI line 3 */ + EXTI_4 = BIT(4), /*!< EXTI line 4 */ + EXTI_5 = BIT(5), /*!< EXTI line 5 */ + EXTI_6 = BIT(6), /*!< EXTI line 6 */ + EXTI_7 = BIT(7), /*!< EXTI line 7 */ + EXTI_8 = BIT(8), /*!< EXTI line 8 */ + EXTI_9 = BIT(9), /*!< EXTI line 9 */ + EXTI_10 = BIT(10), /*!< EXTI line 10 */ + EXTI_11 = BIT(11), /*!< EXTI line 11 */ + EXTI_12 = BIT(12), /*!< EXTI line 12 */ + EXTI_13 = BIT(13), /*!< EXTI line 13 */ + EXTI_14 = BIT(14), /*!< EXTI line 14 */ + EXTI_15 = BIT(15), /*!< EXTI line 15 */ + EXTI_16 = BIT(16), /*!< EXTI line 16 */ + EXTI_17 = BIT(17), /*!< EXTI line 17 */ + EXTI_18 = BIT(18), /*!< EXTI line 18 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_20 = BIT(20), /*!< EXTI line 20 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22), /*!< EXTI line 22 */ + EXTI_23 = BIT(23), /*!< EXTI line 23 */ + EXTI_24 = BIT(24), /*!< EXTI line 24 */ + EXTI_25 = BIT(25), /*!< EXTI line 25 */ + EXTI_26 = BIT(26), /*!< EXTI line 26 */ + EXTI_27 = BIT(27), /*!< EXTI line 27 */ +}exti_line_enum; + +/* external interrupt and event */ +typedef enum +{ + EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ + EXTI_EVENT /*!< EXTI event mode */ +}exti_mode_enum; + +/* interrupt trigger mode */ +typedef enum +{ + EXTI_TRIG_RISING = 0, /*!< EXTI rising edge trigger */ + EXTI_TRIG_FALLING, /*!< EXTI falling edge trigger */ + EXTI_TRIG_BOTH /*!< EXTI rising and falling edge trigger */ +}exti_trig_type_enum; + +/* function declarations */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* enable the configuration of EXTI initialize */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); +/* EXTI software interrupt event enable */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* EXTI software interrupt event disable */ +void exti_software_interrupt_disable(exti_line_enum linex); + +#endif /* GD32E230_EXTI_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h new file mode 100644 index 0000000000..50f6d4b8bd --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h @@ -0,0 +1,272 @@ +/*! + \file gd32e230_fmc.h + \brief definitions for the FMC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_FMC_H +#define GD32E230_FMC_H + +#include "gd32e230.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */ +#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */ +#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */ +#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC write protection register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_SPC_USER REG32((OB) + 0x00U) /*!< option byte security protection value and user value */ +#define OB_DATA REG32((OB) + 0x04U) /*!< option byte data value*/ +#define OB_WP REG32((OB) + 0x08U) /*!< option byte write protection */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ +#define FMC_WS_PFEN BIT(4) /*!< pre-fetch enable */ +#define FMC_WS_PGW BIT(15) /*!< program width to flash memory */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_STAT */ +#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */ +#define FMC_STAT_PGAERR BIT(3) /*!< program alignment error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< flash write protection error flag bit */ +#define FMC_STAT_ENDF BIT(5) /*!< end of operation flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_PER BIT(1) /*!< main flash page erase bit */ +#define FMC_CTL_MER BIT(2) /*!< main flash mass erase bit */ +#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */ +#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */ +#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL_LK BIT(7) /*!< flash lock bit */ +#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */ +#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_OBRLD BIT(13) /*!< option bytes reload bit */ + +/* FMC_ADDR */ +#define FMC_ADDR_ADDR BITS(0,31) /*!< flash command address bits */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit */ +#define FMC_OBSTAT_PLEVEL_BIT0 BIT(1) /*!< protection level bit 0 */ +#define FMC_OBSTAT_PLEVEL_BIT1 BIT(2) /*!< protection level bit 1 */ +#define FMC_OBSTAT_USER BITS(8,15) /*!< option bytes user bits */ +#define FMC_OBSTAT_DATA BITS(16,31) /*!< option byte data bits */ + +/* FMC_WP */ +#define FMC_WP_WP BITS(0,15) /*!< store WP[15:0] of option byte block after system reset */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* fmc state */ +typedef enum +{ + FMC_READY, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_PGERR, /*!< program error */ + FMC_PGAERR, /*!< program alignment error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_TOERR, /*!< timeout error */ + FMC_OB_HSPC /*!< option byte security protection code high */ +}fmc_state_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +/* wait state counter value */ +#define WS_WSCNT_0 ((uint8_t)0x00U) /*!< 0 wait state added */ +#define WS_WSCNT_1 ((uint8_t)0x01U) /*!< 1 wait state added */ +#define WS_WSCNT_2 ((uint8_t)0x02U) /*!< 2 wait state added */ + +/* read protect configure */ +#define FMC_NSPC ((uint16_t)0x5AA5U) /*!< no security protection */ +#define FMC_LSPC ((uint16_t)0x44BBU) /*!< low security protection, any value except 0xA5 or 0xCC */ +#define FMC_HSPC ((uint16_t)0x33CCU) /*!< high security protection */ + +#define LOW_16BITS_MASK ((uint32_t)0x0000FFFFU) /*!< low 16 bits mask */ +#define HIGH_16BITS_MASK ((uint32_t)0xFFFF0000U) /*!< high 16 bits mask */ + +/* option byte address */ +#define OB_SPC_USER_ADDRESS ((uint32_t)0x1FFFF800U) /*!< address of option byte security protection and user */ +#define OB_DATA_ADDRESS ((uint32_t)0x1FFFF804U) /*!< address of option byte data */ +#define OB_WP_ADDRESS ((uint32_t)0x1FFFF808U) /*!< address of option byte write protection */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* option byte software/hardware free watchdog timer */ +#define OB_FWDGT_HW ((uint8_t)(~BIT(0))) /*!< hardware free watchdog timer */ +#define OB_FWDGT_SW ((uint8_t)BIT(0)) /*!< software free watchdog timer */ + +/* option byte reset or not entering deep sleep mode */ +#define OB_DEEPSLEEP_RST ((uint8_t)(~BIT(1))) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST ((uint8_t)BIT(1)) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OB_STDBY_RST ((uint8_t)(~BIT(2))) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST ((uint8_t)BIT(2)) /*!< no reset when entering deepsleep mode */ + +/* option byte OB_BOOT1_n set */ +#define OB_BOOT1_SET_1 ((uint8_t)(~BIT(4))) /*!< BOOT1 bit is 1 */ +#define OB_BOOT1_SET_0 ((uint8_t)BIT(4)) /*!< BOOT1 bit is 0 */ + +/* option byte VDDA monitor enable/disable */ +#define OB_VDDA_DISABLE ((uint8_t)(~BIT(5))) /*!< disable VDDA monitor */ +#define OB_VDDA_ENABLE ((uint8_t)BIT(5)) /*!< enable VDDA monitor */ + +/* option byte SRAM parity enable/disable */ +#define OB_SRAM_PARITY_ENABLE ((uint8_t)(~BIT(6))) /*!< enable SRAM parity check */ +#define OB_SRAM_PARITY_DISABLE ((uint8_t)BIT(6)) /*!< disable SRAM parity check */ + +/* option byte security protection level in FMC_OBSTAT register */ +#define OB_OBSTAT_PLEVEL_NO ((uint8_t)0x00U) /*!< no security protection */ +#define OB_OBSTAT_PLEVEL_LOW ((uint8_t)0x01U) /*!< low security protection */ +#define OB_OBSTAT_PLEVEL_HIGH ((uint8_t)0x03U) /*!< high security protection */ + +/* option byte user mask */ +#define OB_USER_MASK ((uint8_t)0x88U) /*!< OB_USER reserved bit mask */ + +/* option byte data address */ +#define OB_DATA_ADDR0 ((uint32_t)0x1FFFF804U) /*!< option byte data address 0 */ +#define OB_DATA_ADDR1 ((uint32_t)0x1FFFF806U) /*!< option byte data address 1 */ + +/* FMC flags */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ +#define FMC_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_FLAG_PGAERR FMC_STAT_PGAERR /*!< FMC program alignment error flag */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt flags */ +#define FMC_INT_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_INT_FLAG_PGAERR FMC_STAT_PGAERR /*!< FMC program alignment error flag */ +#define FMC_INT_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_INT_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt enable */ +#define FMC_INTEN_END FMC_CTL_ENDIE /*!< enable FMC end of operation interrupt */ +#define FMC_INTEN_ERR FMC_CTL_ERRIE /*!< enable FMC error interrupt */ + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< count to judge of FMC timeout */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* set the wait state counter value */ +void fmc_wscnt_set(uint8_t wscnt); + +/* pre-fetch enable */ +void fmc_prefetch_enable(void); +/* pre-fetch disable */ +void fmc_prefetch_disable(void); +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_address); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC program a double word at the corresponding address */ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* reload the option byte and generate a system reset */ +void ob_reset(void); +/* get option byte value */ +uint32_t option_byte_value_get(uint32_t addr); +/* erase option byte */ +fmc_state_enum ob_erase(void); +/* enable option byte write protection (OB_WP) */ +fmc_state_enum ob_write_protection_enable(uint16_t ob_wp); +/* configure read out protect */ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc); +/* write the FMC option byte user */ +fmc_state_enum ob_user_write(uint8_t ob_user); +/* write the FMC option byte data */ +fmc_state_enum ob_data_program(uint16_t data); +/* get the FMC option byte OB_USER */ +uint8_t ob_user_get(void); +/* get the FMC option byte OB_DATA */ +uint16_t ob_data_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection_get(void); +/* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */ +uint32_t ob_obstat_plevel_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t interrupt); +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t flag); +/* get intrrupt flag set or reset */ +FlagStatus fmc_interrupt_flag_get(uint32_t int_flag); +/* clear the FMC interrupt pending flag by writing 1 */ +void fmc_interrupt_flag_clear(uint32_t int_flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32E230_FMC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h new file mode 100644 index 0000000000..101f87a34a --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h @@ -0,0 +1,119 @@ +/*! + \file gd32e230_fwdgt.h + \brief definitions for the FWDGT + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_FWDGT_H +#define GD32E230_FWDGT_H + +#include "gd32e230.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00000000U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x00000004U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x00000008U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0000000CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x00000010U) /*!< FWDGT window register */ + +/* bits definitions */ +/* FWDGT_CTL */ +#define FWDGT_CTL_CMD BITS(0,15) /*!< FWDGT command value */ + +/* FWDGT_PSC */ +#define FWDGT_PSC_PSC BITS(0,2) /*!< FWDGT prescaler divider value */ + +/* FWDGT_RLD */ +#define FWDGT_RLD_RLD BITS(0,11) /*!< FWDGT counter reload value */ + +/* FWDGT_STAT */ +#define FWDGT_STAT_PUD BIT(0) /*!< FWDGT prescaler divider value update */ +#define FWDGT_STAT_RUD BIT(1) /*!< FWDGT counter reload value update */ +#define FWDGT_STAT_WUD BIT(2) /*!< FWDGT counter window value update */ + +/* FWDGT_WND */ +#define FWDGT_WND_WND BITS(0,11) /*!< FWDGT counter window value */ + +/* constants definitions */ +/* FWDGT_PSC register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x00005555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x00000000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0x0000AAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0x0000CCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* function declarations */ +/* enable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* configure the free watchdog timer counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the free watchdog timer counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value); +/* configure the free watchdog timer counter window value */ +ErrStatus fwdgt_window_value_config(uint16_t window_value); +/* reload the counter of FWDGT */ +void fwdgt_counter_reload(void); +/* configure counter reload value, and prescaler divider value */ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div); + +/* get flag state of FWDGT */ +FlagStatus fwdgt_flag_get(uint16_t flag); + +#endif /* GD32E230_FWDGT_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h new file mode 100644 index 0000000000..252383983d --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h @@ -0,0 +1,388 @@ +/*! + \file gd32e230_gpio.h + \brief definitions for the GPIO + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_GPIO_H +#define GD32E230_GPIO_H + +#include "gd32e230.h" + +/* GPIOx(x=A,B,C,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOF (GPIO_BASE + 0x00001400U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* output mode definitions */ +#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */ +#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */ +#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode */ +#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */ + +/* pull-up/pull-down definitions */ +#define PUD_PUPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< floating mode, no pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO pull-up/pull-down values */ +#define GPIO_PUPD_SET(n, pupd) ((uint32_t)((uint32_t)(pupd) << (2U * (n)))) +#define GPIO_PUPD_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD0(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_2MHZ OSPD_OSPD0(0) /*!< output max speed 2MHz */ +#define GPIO_OSPEED_10MHZ OSPD_OSPD0(1) /*!< output max speed 10MHz */ +#define GPIO_OSPEED_50MHZ OSPD_OSPD0(3) /*!< output max speed 50MHz */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) (0xFU << (4U * (n))) + +/* GPIO alternate function */ +#define AF(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define GPIO_AF_0 AF(0) /*!< alternate function 0 selected */ +#define GPIO_AF_1 AF(1) /*!< alternate function 1 selected */ +#define GPIO_AF_2 AF(2) /*!< alternate function 2 selected */ +#define GPIO_AF_3 AF(3) /*!< alternate function 3 selected */ +#define GPIO_AF_4 AF(4) /*!< alternate function 4 selected (port A,B only) */ +#define GPIO_AF_5 AF(5) /*!< alternate function 5 selected (port A,B only) */ +#define GPIO_AF_6 AF(6) /*!< alternate function 6 selected (port A,B only) */ +#define GPIO_AF_7 AF(7) /*!< alternate function 7 selected (port A,B only) */ + +/* function declarations */ +/* reset GPIO port */ +void gpio_deinit(uint32_t gpio_periph); +/* set GPIO mode */ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin); +/* set GPIO output type and speed */ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin); + +/* set GPIO pin bit */ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin); +/* reset GPIO pin bit */ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin); +/* write data to the specified GPIO pin */ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value); +/* write data to the specified GPIO port */ +void gpio_port_write(uint32_t gpio_periph, uint16_t data); + +/* get GPIO pin input status */ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port input status */ +uint16_t gpio_input_port_get(uint32_t gpio_periph); +/* get GPIO pin output status */ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port output status */ +uint16_t gpio_output_port_get(uint32_t gpio_periph); + +/* set GPIO alternate function */ +void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num, uint32_t pin); +/* lock GPIO pin bit */ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin); + +/* toggle GPIO pin status */ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin); +/* toggle GPIO port status */ +void gpio_port_toggle(uint32_t gpio_periph); + +#endif /* GD32E230_GPIO_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h new file mode 100644 index 0000000000..ab07d46987 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h @@ -0,0 +1,389 @@ +/*! + \file gd32e230_i2c.h + \brief definitions for the I2C + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_I2C_H +#define GD32E230_I2C_H + +#include "gd32e230.h" + +/* I2Cx(x=0,1) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE+0x400U) /*!< I2C1 base address */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ +#define I2C_FMPCFG(i2cx) REG32((i2cx) + 0x90U) /*!< I2C fast-mode-plus configure register */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_SS BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_I2CCLK BITS(0,6) /*!< I2CCLK[6:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt inable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ + +/* I2Cx_DATA */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ + +/* I2Cx_STAT0 */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ + +/* I2Cx_STAT1 */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TR BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_PECV BITS(8,15) /*!< packet error checking value */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode or fast mode plus(master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< duty cycle of fast mode or fast mode plus */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,6) /*!< maximum rise time in fast/standard mode or fast mode plus(master mode) */ + +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag */ + +/* I2Cx_FMPCFG */ +#define I2C_FMPCFG_FMPEN BIT(0) /*!< fast mode plus enable bit */ + +/* constants definitions */ +/* define the I2C bit position and its register index offset */ +#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) + +/* register offset */ +#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */ +#define I2C_SAMCS_REG_OFFSET 0x80U /*!< SAMCS register offset */ + +/* I2C flags */ +typedef enum +{ + /* flags in STAT0 register */ + I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */ + I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */ + I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */ + I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */ + I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving */ + I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */ + I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ + I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */ + I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */ + I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */ + I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */ + I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */ + I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */ + /* flags in STAT1 register */ + I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */ + I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */ + I2C_FLAG_TR = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */ + I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */ + I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */ + I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */ + I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + /* flags in SAMCS register */ + I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */ + I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */ + I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */ + I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */ +}i2c_flag_enum; + +/* I2C interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL1 register */ + I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ + I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_INT_FLAG_ADD10SEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving interrupt flag */ + I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode interrupt flag */ + I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data interrupt flag */ + I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus Alert status interrupt flag */ + /* interrupt flags in SAMCS register */ + I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */ + I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */ + I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall interrupt flag */ + I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */ +}i2c_interrupt_flag_enum; + +/* I2C interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL1 register */ + I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt enable */ + I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt enable */ + I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt enable */ + /* interrupt in SAMCS register */ + I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt enable */ + I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt enable */ + I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt enable */ + I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt enable */ +}i2c_interrupt_enum; + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ + +/* I2C transfer direction */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ + +/* whether or not to send an ACK */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE I2C_CTL0_SS /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE ((uint32_t)0x00000000U) /*!< SCL stretching is disabled */ + +/* whether or not to response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ + +/* software reset I2C */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ + +/* PEC transfer */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP enable */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP disable */ + +/* fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_ENABLE I2C_FMPCFG_FMPEN /*!< fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_DISABLE ((uint32_t)0x00000000U) /*!< fast mode plus disable */ + +/* transmit I2C data */ +#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* receive I2C data */ +#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* I2C duty cycle in fast mode or fast mode plus */ +#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ + +/* function declarations */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); +/* SMBus type selection */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master sends slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection); +/* enable dual-address mode */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr); +/* disable dual-address mode */ +void i2c_dualaddr_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); + +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C DMA mode */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* configure whether next DMA EOT is DMA last transfer or not */ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); + +/* check I2C flag is set or not */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag); +/* clear I2C flag */ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); +/* check I2C interrupt flag */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* GD32E230_I2C_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h new file mode 100644 index 0000000000..4bc91a9600 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h @@ -0,0 +1,86 @@ +/*! + \file gd32e230_misc.h + \brief definitions for the MISC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_MISC_H +#define GD32E230_MISC_H + +#include "gd32e230.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) /*!< NVIC vector table offset mask */ + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) /*!< NVIC VECTKEY mask */ + +/* choose the method to enter or exit the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT /*!< low power mode by exiting from ISR */ +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP /*!< DEEPSLEEP mode or SLEEP mode */ +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND /*!< wakeup by all interrupt */ + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority); +/* disable NVIC request */ +void nvic_irq_disable(uint8_t nvic_irq); +/* initiates a system reset request to reset the MCU */ +void nvic_system_reset(void); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32E230_MISC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h new file mode 100644 index 0000000000..1db5b1fb47 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h @@ -0,0 +1,146 @@ +/*! + \file gd32e230_pmu.h + \brief definitions for the PMU + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_PMU_H +#define GD32E230_PMU_H + +#include "gd32e230.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_LDOVS_0 BIT(14) /*!< LDO output voltage select */ +#define PMU_CTL_LDOVS_1 BIT(15) /*!< LDO output voltage select */ +#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN5 BIT(13) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN6 BIT(14) /*!< wakeup pin enable */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.1V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */ + +/* PMU LDO output voltage select definitions */ +#define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14)) +#define PMU_LDOVS_HIGH CTL_LDOVS(1) /*!< LDO output voltage high mode */ +#define PMU_LDOVS_LOW CTL_LDOVS(2) /*!< LDO output voltage low mode */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO operates normally when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< LVD flag status */ + +/* PMU WKUP pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< WKUP Pin 0 (PA0) enable */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< WKUP Pin 1 (PC13) enable */ +#define PMU_WAKEUP_PIN5 PMU_CS_WUPEN5 /*!< WKUP Pin 5 (PB5) enable */ +#define PMU_WAKEUP_PIN6 PMU_CS_WUPEN6 /*!< WKUP Pin 6 (PB15) enable */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP PMU_CTL_WURST /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY PMU_CTL_STBRST /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* select LDO output voltage */ +void pmu_ldo_output_select(uint32_t ldo_output); +/* disable PMU lvd */ +void pmu_lvd_disable(void); + +/* set PMU mode */ +/* PMU work in sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work in deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd); +/* PMU work in standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +/* backup related functions */ +/* enable backup domain write */ +void pmu_backup_write_enable(void); +/* disable backup domain write */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag_clear); +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); + +#endif /* GD32E230_PMU_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h new file mode 100644 index 0000000000..53f2e34e34 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h @@ -0,0 +1,672 @@ +/*! + \file gd32e230_rcu.h + \brief definitions for the RCU + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_RCU_H +#define GD32E230_RCU_H + +#include "gd32e230.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL0 REG32(RCU + 0x00U) /*!< control register 0 */ +#define RCU_CFG0 REG32(RCU + 0x04U) /*!< configuration register 0 */ +#define RCU_INT REG32(RCU + 0x08U) /*!< interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB enable register */ +#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source /clock register */ +#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x30U) /*!< configuration register 2 */ +#define RCU_CTL1 REG32(RCU + 0x34U) /*!< control register 1 */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ + +/* bits definitions */ +/* RCU_CTL0 */ +#define RCU_CTL0_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL0_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL0_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL0_IRC8MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL0_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL0_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL0_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL0_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL0_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL0_PLLSTB BIT(25) /*!< PLL clock stabilization flag */ + +/* RCU_CFG0 */ +#define RCU_CFG0_SCS BITS(0,1) /*!< system clock switch */ +#define RCU_CFG0_SCSS BITS(2,3) /*!< system clock switch status */ +#define RCU_CFG0_AHBPSC BITS(4,7) /*!< AHB prescaler selection */ +#define RCU_CFG0_APB1PSC BITS(8,10) /*!< APB1 prescaler selection */ +#define RCU_CFG0_APB2PSC BITS(11,13) /*!< APB2 prescaler selection */ +#define RCU_CFG0_ADCPSC BITS(14,15) /*!< ADC clock prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_PLLPREDV BIT(17) /*!< divider for PLL source clock selection */ +#define RCU_CFG0_PLLMF (BIT(27) | BITS(18,21)) /*!< PLL multiply factor */ +#define RCU_CFG0_CKOUTSEL BITS(24,26) /*!< CK_OUT clock source selection */ +#define RCU_CFG0_PLLMF4 BIT(27) /*!< bit 4 of PLLMF */ +#define RCU_CFG0_CKOUTDIV BITS(28,30) /*!< CK_OUT divider which the CK_OUT frequency can be reduced */ +#define RCU_CFG0_PLLDV BIT(31) /*!< CK_PLL divide by 1 or 2 */ + +/* RCU_INT */ +#define RCU_INT_IRC40KSTBIF BIT(0) /*!< IRC40K stabilization interrupt flag */ +#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */ +#define RCU_INT_IRC8MSTBIF BIT(2) /*!< IRC8M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLLSTBIF BIT(4) /*!< PLL stabilization interrupt flag */ +#define RCU_INT_IRC28MSTBIF BIT(5) /*!< IRC28M stabilization interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_IRC40KSTBIE BIT(8) /*!< IRC40K stabilization interrupt enable */ +#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */ +#define RCU_INT_IRC8MSTBIE BIT(10) /*!< IRC8M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLLSTBIE BIT(12) /*!< PLL stabilization interrupt enable */ +#define RCU_INT_IRC28MSTBIE BIT(13) /*!< IRC28M stabilization interrupt enable */ +#define RCU_INT_IRC40KSTBIC BIT(16) /*!< IRC40K stabilization interrupt clear */ +#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL stabilization interrupt clear */ +#define RCU_INT_IRC8MSTBIC BIT(18) /*!< IRC8M stabilization interrupt clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL stabilization interrupt clear */ +#define RCU_INT_PLLSTBIC BIT(20) /*!< PLL stabilization interrupt clear */ +#define RCU_INT_IRC28MSTBIC BIT(21) /*!< IRC28M stabilization interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_CFGRST BIT(0) /*!< system configuration reset */ +#define RCU_APB2RST_ADCRST BIT(9) /*!< ADC reset */ +#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APB2RST_TIMER14RST BIT(16) /*!< TIMER14 reset */ +#define RCU_APB2RST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APB2RST_TIMER16RST BIT(18) /*!< TIMER16 reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 timer reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 timer reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 timer reset */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< window watchdog timer reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< power control reset */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMAEN BIT(0) /*!< DMA clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM interface clock enable */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_PAEN BIT(17) /*!< GPIO port A clock enable */ +#define RCU_AHBEN_PBEN BIT(18) /*!< GPIO port B clock enable */ +#define RCU_AHBEN_PCEN BIT(19) /*!< GPIO port C clock enable */ +#define RCU_AHBEN_PFEN BIT(22) /*!< GPIO port F clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_CFGCMPEN BIT(0) /*!< system configuration and comparator clock enable */ +#define RCU_APB2EN_ADCEN BIT(9) /*!< ADC interface clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 timer clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ +#define RCU_APB2EN_TIMER14EN BIT(16) /*!< TIMER14 timer clock enable */ +#define RCU_APB2EN_TIMER15EN BIT(17) /*!< TIMER15 timer clock enable */ +#define RCU_APB2EN_TIMER16EN BIT(18) /*!< TIMER16 timer clock enable */ +#define RCU_APB2EN_DBGMCUEN BIT(22) /*!< DBGMCU clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 timer clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 timer clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 timer clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< window watchdog timer clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< power interface clock enable */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< external low-speed oscillator stabilization */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_BDCTL_LXTALDRI BITS(3,4) /*!< LXTAL drive capability */ +#define RCU_BDCTL_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_BDCTL_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_BDCTL_BKPRST BIT(16) /*!< backup domain reset */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC40KEN BIT(0) /*!< IRC40K enable */ +#define RCU_RSTSCK_IRC40KSTB BIT(1) /*!< IRC40K stabilization */ +#define RCU_RSTSCK_V12RSTF BIT(23) /*!< V12 domain power reset flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#define RCU_RSTSCK_OBLRSTF BIT(25) /*!< option byte loader reset flag */ +#define RCU_RSTSCK_EPRSTF BIT(26) /*!< external pin reset flag */ +#define RCU_RSTSCK_PORRSTF BIT(27) /*!< power reset flag */ +#define RCU_RSTSCK_SWRSTF BIT(28) /*!< software reset flag */ +#define RCU_RSTSCK_FWDGTRSTF BIT(29) /*!< free watchdog timer reset flag */ +#define RCU_RSTSCK_WWDGTRSTF BIT(30) /*!< window watchdog timer reset flag */ +#define RCU_RSTSCK_LPRSTF BIT(31) /*!< low-power reset flag */ + +/* RCU_AHBRST */ +#define RCU_AHBRST_PARST BIT(17) /*!< GPIO port A reset */ +#define RCU_AHBRST_PBRST BIT(18) /*!< GPIO port B reset */ +#define RCU_AHBRST_PCRST BIT(19) /*!< GPIO port C reset */ +#define RCU_AHBRST_PFRST BIT(22) /*!< GPIO port F reset */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */ + +/* RCU_CFG2 */ +#define RCU_CFG2_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */ +#define RCU_CFG2_ADCSEL BIT(8) /*!< CK_ADC clock source selection */ +#define RCU_CFG2_IRC28MDIV BIT(16) /*!< CK_IRC28M divider 2 or not */ +#define RCU_CFG2_ADCPSC2 BIT(31) /*!< bit 2 of ADCPSC */ + +/* RCU_CTL1 */ +#define RCU_CTL1_IRC28MEN BIT(0) /*!< IRC28M internal 28M RC oscillator enable */ +#define RCU_CTL1_IRC28MSTB BIT(1) /*!< IRC28M internal 28M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC28MADJ BITS(3,7) /*!< internal 28M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC28MCALIB BITS(8,15) /*!< internal 28M RC oscillator calibration value register */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< key of RCU_DSV register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,1) /*!< deep-sleep mode voltage select */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx)<<6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph)>>6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4D) + +/* register index */ +typedef enum +{ + /* peripherals enable */ + IDX_AHBEN = 0x14U, + IDX_APB2EN = 0x18U, + IDX_APB1EN = 0x1CU, + /* peripherals reset */ + IDX_AHBRST = 0x28U, + IDX_APB2RST = 0x0CU, + IDX_APB1RST = 0x10U, + /* clock stabilization */ + IDX_CTL0 = 0x00U, + IDX_BDCTL = 0x20U, + IDX_CTL1 = 0x34U, + /* peripheral reset */ + IDX_RSTSCK = 0x24U, + /* clock stabilization and stuck interrupt */ + IDX_INT = 0x08U, + /* configuration register */ + IDX_CFG0 = 0x04U, + IDX_CFG2 = 0x30U +}reg_idx; + +/* peripheral clock enable */ +typedef enum +{ + /* AHB peripherals */ + RCU_DMA = RCU_REGIDX_BIT(IDX_AHBEN, 0U), /*!< DMA clock */ + RCU_CRC = RCU_REGIDX_BIT(IDX_AHBEN, 6U), /*!< CRC clock */ + RCU_GPIOA = RCU_REGIDX_BIT(IDX_AHBEN, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(IDX_AHBEN, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(IDX_AHBEN, 19U), /*!< GPIOC clock */ + RCU_GPIOF = RCU_REGIDX_BIT(IDX_AHBEN, 22U), /*!< GPIOF clock */ + + /* APB2 peripherals */ + RCU_CFGCMP = RCU_REGIDX_BIT(IDX_APB2EN, 0U), /*!< CFGCMP clock */ + RCU_ADC = RCU_REGIDX_BIT(IDX_APB2EN, 9U), /*!< ADC clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(IDX_APB2EN, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(IDX_APB2EN, 12U), /*!< SPI0 clock */ + RCU_USART0 = RCU_REGIDX_BIT(IDX_APB2EN, 14U), /*!< USART0 clock */ + RCU_TIMER14 = RCU_REGIDX_BIT(IDX_APB2EN, 16U), /*!< TIMER14 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(IDX_APB2EN, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(IDX_APB2EN, 18U), /*!< TIMER16 clock */ + RCU_DBGMCU = RCU_REGIDX_BIT(IDX_APB2EN, 22U), /*!< DBGMCU clock */ + + /* APB1 peripherals */ + RCU_TIMER2 = RCU_REGIDX_BIT(IDX_APB1EN, 1U), /*!< TIMER2 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(IDX_APB1EN, 4U), /*!< TIMER5 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(IDX_APB1EN, 8U), /*!< TIMER13 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(IDX_APB1EN, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(IDX_APB1EN, 14U), /*!< SPI1 clock */ + RCU_USART1 = RCU_REGIDX_BIT(IDX_APB1EN, 17U), /*!< USART1 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(IDX_APB1EN, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(IDX_APB1EN, 22U), /*!< I2C1 clock */ + RCU_PMU = RCU_REGIDX_BIT(IDX_APB1EN, 28U), /*!< PMU clock */ + + /* Backup domain control(BDCTL) */ + RCU_RTC = RCU_REGIDX_BIT(IDX_BDCTL, 15U) /*!< RTC clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 2U), /*!< SRAM clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 4U), /*!< FMC clock */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB peripherals reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(IDX_AHBRST, 17U), /*!< GPIOA reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(IDX_AHBRST, 18U), /*!< GPIOB reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(IDX_AHBRST, 19U), /*!< GPIOC reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(IDX_AHBRST, 22U), /*!< GPIOF reset */ + + /* APB2 peripherals reset */ + RCU_CFGCMPRST = RCU_REGIDX_BIT(IDX_APB2RST, 0U), /*!< CFGCMP reset */ + RCU_ADCRST = RCU_REGIDX_BIT(IDX_APB2RST, 9U), /*!< ADC reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(IDX_APB2RST, 11U), /*!< TIMER0 reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(IDX_APB2RST, 12U), /*!< SPI0 reset */ + RCU_USART0RST = RCU_REGIDX_BIT(IDX_APB2RST, 14U), /*!< USART0 reset */ + RCU_TIMER14RST = RCU_REGIDX_BIT(IDX_APB2RST, 16U), /*!< TIMER14 reset */ + RCU_TIMER15RST = RCU_REGIDX_BIT(IDX_APB2RST, 17U), /*!< TIMER15 reset */ + RCU_TIMER16RST = RCU_REGIDX_BIT(IDX_APB2RST, 18U), /*!< TIMER16 reset */ + + /* APB1 peripherals reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(IDX_APB1RST, 1U), /*!< TIMER2 reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(IDX_APB1RST, 4U), /*!< TIMER5 reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(IDX_APB1RST, 8U), /*!< TIMER13 reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(IDX_APB1RST, 11U), /*!< WWDGT reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(IDX_APB1RST, 14U), /*!< SPI1 reset */ + RCU_USART1RST = RCU_REGIDX_BIT(IDX_APB1RST, 17U), /*!< USART1 reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(IDX_APB1RST, 21U), /*!< I2C0 reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(IDX_APB1RST, 22U), /*!< I2C1 reset */ + RCU_PMURST = RCU_REGIDX_BIT(IDX_APB1RST, 28U), /*!< PMU reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_RSTSCK, 1U), /*!< IRC40K stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_BDCTL, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_CTL0, 1U), /*!< IRC8M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_CTL0, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_CTL0, 25U), /*!< PLL stabilization flags */ + RCU_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC28M stabilization flags */ + + RCU_FLAG_V12RST = RCU_REGIDX_BIT(IDX_RSTSCK, 23U), /*!< V12 reset flags */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(IDX_RSTSCK, 25U), /*!< OBL reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 26U), /*!< EPR reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(IDX_RSTSCK, 27U), /*!< power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(IDX_RSTSCK, 28U), /*!< SW reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 31U) /*!< LP reset flags */ +}rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_INT, 0U), /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_INT, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_INT, 2U), /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_INT, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_INT, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_INT, 5U), /*!< IRC28M stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(IDX_INT, 7U), /*!< CKM interrupt flag */ +}rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 16U), /*!< IRC40K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 17U), /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 18U), /*!< IRC8M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 20U), /*!< PLL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC28MSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 21U), /*!< IRC28M stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(IDX_INT, 23U), /*!< CKM interrupt flags clear */ +}rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum +{ + RCU_INT_IRC40KSTB = RCU_REGIDX_BIT(IDX_INT, 8U), /*!< IRC40K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(IDX_INT, 9U), /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC8MSTB = RCU_REGIDX_BIT(IDX_INT, 10U), /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(IDX_INT, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(IDX_INT, 12U), /*!< PLL stabilization interrupt */ + RCU_INT_IRC28MSTB = RCU_REGIDX_BIT(IDX_INT, 13U), /*!< IRC28M stabilization interrupt */ +}rcu_int_enum; + +/* ADC clock source */ +typedef enum +{ + RCU_ADCCK_IRC28M_DIV2 = 0U, /*!< ADC clock source select IRC28M/2 */ + RCU_ADCCK_IRC28M, /*!< ADC clock source select IRC28M */ + RCU_ADCCK_APB2_DIV2, /*!< ADC clock source select APB2/2 */ + RCU_ADCCK_AHB_DIV3, /*!< ADC clock source select AHB/3 */ + RCU_ADCCK_APB2_DIV4, /*!< ADC clock source select APB2/4 */ + RCU_ADCCK_AHB_DIV5, /*!< ADC clock source select AHB/5 */ + RCU_ADCCK_APB2_DIV6, /*!< ADC clock source select APB2/6 */ + RCU_ADCCK_AHB_DIV7, /*!< ADC clock source select AHB/7 */ + RCU_ADCCK_APB2_DIV8, /*!< ADC clock source select APB2/8 */ + RCU_ADCCK_AHB_DIV9 /*!< ADC clock source select AHB/9 */ +}rcu_adc_clock_enum; + +/* oscillator types */ +typedef enum +{ + RCU_HXTAL = RCU_REGIDX_BIT(IDX_CTL0, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(IDX_BDCTL, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(IDX_CTL0, 0U), /*!< IRC8M */ + RCU_IRC28M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC28M */ + RCU_IRC40K = RCU_REGIDX_BIT(IDX_RSTSCK, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(IDX_CTL0, 24U) /*!< PLL */ +}rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum +{ + CK_SYS = 0U, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ + CK_ADC, /*!< ADC clock */ + CK_USART /*!< USART clock */ +}rcu_clock_freq_enum; + +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_CKSYSSRC_IRC8M CFG0_SCS(0) /*!< system clock source select IRC8M */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_PLL CFG0_SCS(2) /*!< system clock source select PLL */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define RCU_SCSS_IRC8M CFG0_SCSS(0) /*!< system clock source select IRC8M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_PLL CFG0_SCSS(2) /*!< system clock source select PLL */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS/2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS/4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS/8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS/16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS/64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS/128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS/256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS/512 */ + +/* APB1 prescaler selection */ +#define CFG0_APB1PSC(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define RCU_APB1_CKAHB_DIV1 CFG0_APB1PSC(0) /*!< APB1 prescaler select CK_AHB */ +#define RCU_APB1_CKAHB_DIV2 CFG0_APB1PSC(4) /*!< APB1 prescaler select CK_AHB/2 */ +#define RCU_APB1_CKAHB_DIV4 CFG0_APB1PSC(5) /*!< APB1 prescaler select CK_AHB/4 */ +#define RCU_APB1_CKAHB_DIV8 CFG0_APB1PSC(6) /*!< APB1 prescaler select CK_AHB/8 */ +#define RCU_APB1_CKAHB_DIV16 CFG0_APB1PSC(7) /*!< APB1 prescaler select CK_AHB/16 */ + +/* APB2 prescaler selection */ +#define CFG0_APB2PSC(regval) (BITS(11,13) & ((uint32_t)(regval) << 11)) +#define RCU_APB2_CKAHB_DIV1 CFG0_APB2PSC(0) /*!< APB2 prescaler select CK_AHB */ +#define RCU_APB2_CKAHB_DIV2 CFG0_APB2PSC(4) /*!< APB2 prescaler select CK_AHB/2 */ +#define RCU_APB2_CKAHB_DIV4 CFG0_APB2PSC(5) /*!< APB2 prescaler select CK_AHB/4 */ +#define RCU_APB2_CKAHB_DIV8 CFG0_APB2PSC(6) /*!< APB2 prescaler select CK_AHB/8 */ +#define RCU_APB2_CKAHB_DIV16 CFG0_APB2PSC(7) /*!< APB2 prescaler select CK_AHB/16 */ + +/* ADC clock prescaler selection */ +#define CFG0_ADCPSC(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) +#define RCU_ADC_CKAPB2_DIV2 CFG0_ADCPSC(0) /*!< ADC clock prescaler select CK_APB2/2 */ +#define RCU_ADC_CKAPB2_DIV4 CFG0_ADCPSC(1) /*!< ADC clock prescaler select CK_APB2/4 */ +#define RCU_ADC_CKAPB2_DIV6 CFG0_ADCPSC(2) /*!< ADC clock prescaler select CK_APB2/6 */ +#define RCU_ADC_CKAPB2_DIV8 CFG0_ADCPSC(3) /*!< ADC clock prescaler select CK_APB2/8 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 (uint32_t)0x00000000U /*!< PLL clock source select IRC8M/2 */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< PLL clock source select HXTAL */ + +/* HXTAL divider for PLL source clock selection */ +#define RCU_PLLPREDV (uint32_t)0x00000000U /*!< HXTAL clock selected */ +#define RCU_PLLPREDV_DIV2 RCU_CFG0_PLLPREDV /*!< HXTAL/2 clock selected */ + +/* PLL multiply factor */ +#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18)) +#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL source clock multiply by 2 */ +#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL source clock multiply by 3 */ +#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL source clock multiply by 4 */ +#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL source clock multiply by 5 */ +#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL source clock multiply by 6 */ +#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL source clock multiply by 7 */ +#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL source clock multiply by 8 */ +#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL source clock multiply by 9 */ +#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL source clock multiply by 10 */ +#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL source clock multiply by 11 */ +#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL source clock multiply by 12 */ +#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL source clock multiply by 13 */ +#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL source clock multiply by 14 */ +#define RCU_PLL_MUL15 CFG0_PLLMF(13) /*!< PLL source clock multiply by 15 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */ +#define RCU_PLL_MUL17 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */ +#define RCU_PLL_MUL18 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */ +#define RCU_PLL_MUL19 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */ +#define RCU_PLL_MUL20 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */ +#define RCU_PLL_MUL21 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */ +#define RCU_PLL_MUL22 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */ +#define RCU_PLL_MUL23 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */ +#define RCU_PLL_MUL24 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */ +#define RCU_PLL_MUL25 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */ +#define RCU_PLL_MUL26 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */ +#define RCU_PLL_MUL27 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */ +#define RCU_PLL_MUL28 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */ +#define RCU_PLL_MUL29 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */ +#define RCU_PLL_MUL30 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */ +#define RCU_PLL_MUL31 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */ +#define RCU_PLL_MUL32 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(15)) /*!< PLL source clock multiply by 32 */ + +/* CK_OUT clock source selection */ +#define CFG0_CKOUTSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUTSRC_NONE CFG0_CKOUTSEL(0) /*!< no clock selected */ +#define RCU_CKOUTSRC_IRC28M CFG0_CKOUTSEL(1) /*!< CK_OUT clock source select IRC28M */ +#define RCU_CKOUTSRC_IRC40K CFG0_CKOUTSEL(2) /*!< CK_OUT clock source select IRC40K */ +#define RCU_CKOUTSRC_LXTAL CFG0_CKOUTSEL(3) /*!< CK_OUT clock source select LXTAL */ +#define RCU_CKOUTSRC_CKSYS CFG0_CKOUTSEL(4) /*!< CK_OUT clock source select CKSYS */ +#define RCU_CKOUTSRC_IRC8M CFG0_CKOUTSEL(5) /*!< CK_OUT clock source select IRC8M */ +#define RCU_CKOUTSRC_HXTAL CFG0_CKOUTSEL(6) /*!< CK_OUT clock source select HXTAL */ +#define RCU_CKOUTSRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_OUT clock source select CK_PLL */ +#define RCU_CKOUTSRC_CKPLL_DIV2 CFG0_CKOUTSEL(7) /*!< CK_OUT clock source select CK_PLL/2 */ + +/* CK_OUT divider */ +#define CFG0_CKOUTDIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define RCU_CKOUT_DIV1 CFG0_CKOUTDIV(0) /*!< CK_OUT is divided by 1 */ +#define RCU_CKOUT_DIV2 CFG0_CKOUTDIV(1) /*!< CK_OUT is divided by 2 */ +#define RCU_CKOUT_DIV4 CFG0_CKOUTDIV(2) /*!< CK_OUT is divided by 4 */ +#define RCU_CKOUT_DIV8 CFG0_CKOUTDIV(3) /*!< CK_OUT is divided by 8 */ +#define RCU_CKOUT_DIV16 CFG0_CKOUTDIV(4) /*!< CK_OUT is divided by 16 */ +#define RCU_CKOUT_DIV32 CFG0_CKOUTDIV(5) /*!< CK_OUT is divided by 32 */ +#define RCU_CKOUT_DIV64 CFG0_CKOUTDIV(6) /*!< CK_OUT is divided by 64 */ +#define RCU_CKOUT_DIV128 CFG0_CKOUTDIV(7) /*!< CK_OUT is divided by 128 */ + +/* CK_PLL divide by 1 or 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL_DIV2 (uint32_t)0x00000000U /*!< CK_PLL divide by 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL RCU_CFG0_PLLDV /*!< CK_PLL divide by 1 for CK_OUT */ + +/* LXTAL drive capability */ +#define BDCTL_LXTALDRI(regval) (BITS(3,4) & ((uint32_t)(regval) << 3)) +#define RCU_LXTAL_LOWDRI BDCTL_LXTALDRI(0) /*!< lower driving capability */ +#define RCU_LXTAL_MED_LOWDRI BDCTL_LXTALDRI(1) /*!< medium low driving capability */ +#define RCU_LXTAL_MED_HIGHDRI BDCTL_LXTALDRI(2) /*!< medium high driving capability */ +#define RCU_LXTAL_HIGHDRI BDCTL_LXTALDRI(3) /*!< higher driving capability */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_RTCSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as RTC source clock */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as RTC source clock */ +#define RCU_RTCSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as RTC source clock */ + +/* CK_HXTAL divider previous PLL */ +#define CFG1_PREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PLL_PREDV1 CFG1_PREDV(0) /*!< PLL not divided */ +#define RCU_PLL_PREDV2 CFG1_PREDV(1) /*!< PLL divided by 2 */ +#define RCU_PLL_PREDV3 CFG1_PREDV(2) /*!< PLL divided by 3 */ +#define RCU_PLL_PREDV4 CFG1_PREDV(3) /*!< PLL divided by 4 */ +#define RCU_PLL_PREDV5 CFG1_PREDV(4) /*!< PLL divided by 5 */ +#define RCU_PLL_PREDV6 CFG1_PREDV(5) /*!< PLL divided by 6 */ +#define RCU_PLL_PREDV7 CFG1_PREDV(6) /*!< PLL divided by 7 */ +#define RCU_PLL_PREDV8 CFG1_PREDV(7) /*!< PLL divided by 8 */ +#define RCU_PLL_PREDV9 CFG1_PREDV(8) /*!< PLL divided by 9 */ +#define RCU_PLL_PREDV10 CFG1_PREDV(9) /*!< PLL divided by 10 */ +#define RCU_PLL_PREDV11 CFG1_PREDV(10) /*!< PLL divided by 11 */ +#define RCU_PLL_PREDV12 CFG1_PREDV(11) /*!< PLL divided by 12 */ +#define RCU_PLL_PREDV13 CFG1_PREDV(12) /*!< PLL divided by 13 */ +#define RCU_PLL_PREDV14 CFG1_PREDV(13) /*!< PLL divided by 14 */ +#define RCU_PLL_PREDV15 CFG1_PREDV(14) /*!< PLL divided by 15 */ +#define RCU_PLL_PREDV16 CFG1_PREDV(15) /*!< PLL divided by 16 */ + +/* USART0 clock source selection */ +#define CFG2_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_USART0SRC_CKAPB2 CFG2_USART0SEL(0) /*!< CK_USART0 select CK_APB2 */ +#define RCU_USART0SRC_CKSYS CFG2_USART0SEL(1) /*!< CK_USART0 select CK_SYS */ +#define RCU_USART0SRC_LXTAL CFG2_USART0SEL(2) /*!< CK_USART0 select LXTAL */ +#define RCU_USART0SRC_IRC8M CFG2_USART0SEL(3) /*!< CK_USART0 select IRC8M */ + +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC28M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_AHB_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ + +/* IRC28M clock divider for ADC */ +#define RCU_ADC_IRC28M_DIV2 (uint32_t)0x00000000U /*!< IRC28M/2 select to ADC clock */ +#define RCU_ADC_IRC28M_DIV1 RCU_CFG2_IRC28MDIV /*!< IRC28M select to ADC clock */ + +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(0) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(1) /*!< core voltage is 0.9V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_8 DSV_DSLPVS(2) /*!< core voltage is 0.8V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(3) /*!< core voltage is 1.2V in deep-sleep mode */ + +/* function declarations */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP */ +void rcu_bkp_reset_enable(void); +/* disable the BKP reset */ +void rcu_bkp_reset_disable(void); + +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the ADC clock source and prescaler selection */ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc); +/* configure the CK_OUT clock source and divider */ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div); + +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); +/* configure the USART clock source selection */ +void rcu_usart_clock_config(uint32_t ck_usart); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the HXTAL divider used as input of PLL */ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv); +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); + +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum stab_int); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum stab_int); + +/* wait until oscillator stabilization flags is SET */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* set the IRC8M adjust value */ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval); +/* set the IRC28M adjust value */ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval); +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); + +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +#endif /* GD32E230_RCU_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h new file mode 100644 index 0000000000..27756b1609 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h @@ -0,0 +1,561 @@ +/*! + \file gd32e230_rtc.h + \brief definitions for the RTC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_RTC_H +#define GD32E230_RTC_H + +#include "gd32e230.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00000000U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x00000004U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x00000008U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0000000CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x00000010U) /*!< RTC time prescaler register */ +#define RTC_ALRM0TD REG32((RTC) + 0x0000001CU) /*!< RTC alarm 0 time and date register */ +#define RTC_WPK REG32((RTC) + 0x00000024U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x00000028U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x0000002CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x00000030U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x00000034U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x00000038U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x0000003CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x00000040U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x00000044U) /*!< RTC alarm 0 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x00000050U) /*!< RTC backup 0 register */ +#define RTC_BKP1 REG32((RTC) + 0x00000054U) /*!< RTC backup 1 register */ +#define RTC_BKP2 REG32((RTC) + 0x00000058U) /*!< RTC backup 2 register */ +#define RTC_BKP3 REG32((RTC) + 0x0000005CU) /*!< RTC backup 3 register */ +#define RTC_BKP4 REG32((RTC) + 0x00000060U) /*!< RTC backup 4 register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm configuration can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm occurs flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamp 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamp 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< recalibration pending flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_ALRM0TD */ +#define RTC_ALRM0TD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRM0TD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRM0TD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRM0TD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRM0TD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRM0TD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRM0TD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_HRT BITS(20,21) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRM0TD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRM0TD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRM0TD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRM0TD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRM0TD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second units in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< tamper 1 event trigger edge for RTC tamp 1 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TAMP_PC13VAL BIT(18) /*!< alarm output type control/PC13 output value */ +#define RTC_TAMP_PC13MDE BIT(19) /*!< PC13 mode */ +#define RTC_TAMP_PC14VAL BIT(20) /*!< PC14 output value */ +#define RTC_TAMP_PC14MDE BIT(21) /*!< PC14 mode */ +#define RTC_TAMP_PC15VAL BIT(22) /*!< PC15 output value */ +#define RTC_TAMP_PC15MDE BIT(23) /*!< PC15 mode */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_BKP0 */ +#define RTC_BKP0_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP4 */ +#define RTC_BKP4_DATA BITS(0,31) /*!< backup domain registers */ + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct +{ + uint8_t rtc_year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t rtc_month; /*!< RTC month value */ + uint8_t rtc_date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_day_of_week; /*!< RTC weekday value */ + uint8_t rtc_hour; /*!< RTC hour value */ + uint8_t rtc_minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t rtc_factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t rtc_factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t rtc_am_pm; /*!< RTC AM/PM value */ + uint32_t rtc_display_format; /*!< RTC time notation */ +}rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct +{ + uint32_t rtc_alarm_mask; /*!< RTC alarm mask */ + uint32_t rtc_weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t rtc_alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t rtc_alarm_hour; /*!< RTC alarm hour value */ + uint8_t rtc_alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC alarm AM/PM value */ +}rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct +{ + uint8_t rtc_timestamp_month; /*!< RTC time-stamp month value */ + uint8_t rtc_timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t rtc_timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t rtc_timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC time-stamp AM/PM value */ +}rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct +{ + uint32_t rtc_tamper_source; /*!< RTC tamper source */ + uint32_t rtc_tamper_trigger; /*!< RTC tamper trigger */ + uint32_t rtc_tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t rtc_tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus rtc_tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t rtc_tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus rtc_tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +}rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01U) /*!< Monday */ +#define RTC_TUESDAY ((uint8_t)0x02U) /*!< Tuesday */ +#define RTC_WEDSDAY ((uint8_t)0x03U) /*!< Wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04U) /*!< Thursday */ +#define RTC_FRIDAY ((uint8_t)0x05U) /*!< Friday */ +#define RTC_SATURDAY ((uint8_t)0x06U) /*!< Saturday */ +#define RTC_SUNDAY ((uint8_t)0x07U) /*!< Sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +/* ctl register value */ +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21U)) /*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ENABLE CTL_OS(1) /*!< enable alarm flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ (RTC_CTL_COEN | RTC_CTL_COS) /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM_HIGH RTC_CTL_OS /*!< enable alarm flag output with high level */ +#define RTC_ALARM_LOW (RTC_CTL_OS | RTC_CTL_OPOL) /*!< enable alarm flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrm0td register value */ +#define ALRM0TD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0TD_SC bit field */ +#define GET_ALRM0TD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRM0TD_SC bit field */ + +#define ALRM0TD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_ALRM0TD_MN bit field */ +#define GET_ALRM0TD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRM0TD_MN bit field */ + +#define ALRM0TD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_ALRM0TD_HR bit field */ +#define GET_ALRM0TD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRM0TD_HR bit field */ + +#define ALRM0TD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24U)) /*!< write value to RTC_ALRM0TD_DAY bit field */ +#define GET_ALRM0TD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRM0TD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRM0TD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRM0TD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRM0TD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRM0TD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRM0TD_MSKD|RTC_ALRM0TD_MSKH|RTC_ALRM0TD_MSKM|RTC_ALRM0TD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRM0TD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +/* tamp register value */ +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U)) /*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_PRCH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TAMP_PC13VAL /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRM0SS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0SS_SSC bit field */ + +#define ALRM0SS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) /*!< write value to RTC_ALRM0SS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRM0SS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRM0SS_MASKSSC(1) /*!< mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRM0SS_MASKSSC(2) /*!< mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRM0SS_MASKSSC(3) /*!< mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRM0SS_MASKSSC(4) /*!< mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRM0SS_MASKSSC(5) /*!< mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRM0SS_MASKSSC(6) /*!< mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRM0SS_MASKSSC(7) /*!< mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRM0SS_MASKSSC(8) /*!< mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRM0SS_MASKSSC(9) /*!< mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRM0SS_MASKSSC(10) /*!< mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRM0SS_MASKSSC(11) /*!< mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRM0SS_MASKSSC(12) /*!< mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRM0SS_MASKSSC(13) /*!< mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRM0SS_MASKSSC(14) /*!< mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRM0SS_MASKSSC(15) /*!< mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM RTC_CTL_ALRM0IE /*!< RTC alarm interrupt enable */ +#define RTC_INT_TAMP RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ + +/* RTC timeout value */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x00001000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRM0WF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ + +/* RTC flag */ +#define RTC_FLAG_RECALIBRATION RTC_STAT_SCPF /*!< recalibration pending flag */ +#define RTC_FLAG_TAMP1 RTC_STAT_TP1F /*!< tamper 1 event flag */ +#define RTC_FLAG_TAMP0 RTC_STAT_TP0F /*!< tamper 0 event flag */ +#define RTC_FLAG_TIMESTAMP_OVERFLOW RTC_STAT_TSOVRF /*!< time-stamp overflow event flag */ +#define RTC_FLAG_TIMESTAMP RTC_STAT_TSF /*!< time-stamp event flag */ +#define RTC_FLAG_ALARM0 RTC_STAT_ALRM0F /*!< alarm event flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< init mode event flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_YCM RTC_STAT_YCM /*!< year parameter configured event flag */ +#define RTC_FLAG_SHIFT RTC_STAT_SOPF /*!< shift operation pending flag */ +#define RTC_FLAG_ALARM0_WRITTEN RTC_STAT_ALRM0WF /*!< alarm written available flag */ + +/* function declarations */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* configure RTC alarm */ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(void); +/* enable RTC alarm */ +void rtc_alarm_enable(void); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(void); + +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +/* configure RTC alternate output source */ +void rtc_alter_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration register */ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); +/* ajust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* ajust RTC second or subsecond value of current time */ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus); +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +#endif /* GD32E230_RTC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h new file mode 100644 index 0000000000..5be789ff11 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h @@ -0,0 +1,424 @@ +/*! + \file gd32e230_spi.h + \brief definitions for the SPI + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_SPI_H +#define GD32E230_SPI_H + +#include "gd32e230.h" + +/* SPIx(x=0,1) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad mode control register(only SPI1) */ + +/* bits definitions */ +/* SPI_CTL0 */ +#define SPI_CTL0_CKPH BIT(0) /*!< clock phase selection */ +#define SPI_CTL0_CKPL BIT(1) /*!< clock polarity selection */ +#define SPI_CTL0_MSTMOD BIT(2) /*!< master mode enable */ +#define SPI_CTL0_PSC BITS(3,5) /*!< master clock prescaler selection */ +#define SPI_CTL0_SPIEN BIT(6) /*!< SPI enable*/ +#define SPI_CTL0_LF BIT(7) /*!< LSB first mode */ +#define SPI_CTL0_SWNSS BIT(8) /*!< NSS pin selection in NSS software mode */ +#define SPI_CTL0_SWNSSEN BIT(9) /*!< NSS software mode selection */ +#define SPI_CTL0_RO BIT(10) /*!< receive only */ +/* only available in SPI0*/ +#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */ +/* only available in SPI1*/ +#define SPI_CTL0_CRCL BIT(11) /*!< CRC length */ +#define SPI_CTL0_CRCNT BIT(12) /*!< CRC next transfer */ +#define SPI_CTL0_CRCEN BIT(13) /*!< CRC calculation enable */ +#define SPI_CTL0_BDOEN BIT(14) /*!< bidirectional transmit output enable*/ +#define SPI_CTL0_BDEN BIT(15) /*!< bidirectional enable */ + +/* SPI_CTL1 */ +#define SPI_CTL1_DMAREN BIT(0) /*!< receive buffer dma enable */ +#define SPI_CTL1_DMATEN BIT(1) /*!< transmit buffer dma enable */ +#define SPI_CTL1_NSSDRV BIT(2) /*!< drive NSS output */ +#define SPI_CTL1_NSSP BIT(3) /*!< SPI NSS pulse mode enable */ +#define SPI_CTL1_TMOD BIT(4) /*!< SPI TI mode enable */ +#define SPI_CTL1_ERRIE BIT(5) /*!< errors interrupt enable */ +#define SPI_CTL1_RBNEIE BIT(6) /*!< receive buffer not empty interrupt enable */ +#define SPI_CTL1_TBEIE BIT(7) /*!< transmit buffer empty interrupt enable */ +/* only available in SPI1 */ +#define SPI_CTL1_DZ BITS(8,11) /*!< data size */ +#define SPI_CTL1_BYTEN BIT(12) /*!< byte access to FIFO enable */ +#define SPI_CTL1_RXDMA_ODD BIT(13) /*!< odd bytes in RX DMA channel */ +#define SPI_CTL1_TXDMA_ODD BIT(14) /*!< odd bytes in TX DMA channel */ + +/* SPI_STAT */ +#define SPI_STAT_RBNE BIT(0) /*!< receive buffer not empty */ +#define SPI_STAT_TBE BIT(1) /*!< transmit buffer empty */ +#define SPI_STAT_I2SCH BIT(2) /*!< I2S channel side */ +#define SPI_STAT_TXURERR BIT(3) /*!< I2S transmission underrun error bit */ +#define SPI_STAT_CRCERR BIT(4) /*!< SPI CRC error bit */ +#define SPI_STAT_CONFERR BIT(5) /*!< SPI configuration error bit */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going bit */ +#define SPI_STAT_FERR BIT(8) /*!< format error bit */ +/* only available in SPI1 */ +#define SPI_STAT_RXLVL BITS(9,10) /*!< RXFIFO level */ +#define SPI_STAT_TXLVL BITS(11,12) /*!< TXFIFO level */ + +/* SPI_DATA */ +#define SPI_DATA_DATA BITS(0,15) /*!< data transfer register */ + +/* SPI_CRCPOLY */ +#define SPI_CRCPOLY_CRCPOLY BITS(0,15) /*!< CRC polynomial value */ + +/* SPI_RCRC */ +#define SPI_RCRC_RCRC BITS(0,15) /*!< RX CRC value */ + +/* SPI_TCRC */ +#define SPI_TCRC_TCRC BITS(0,15) /*!< TX CRC value */ + +/* SPI_I2SCTL */ +#define SPI_I2SCTL_CHLEN BIT(0) /*!< channel length */ +#define SPI_I2SCTL_DTLEN BITS(1,2) /*!< data length */ +#define SPI_I2SCTL_CKPL BIT(3) /*!< idle state clock polarity */ +#define SPI_I2SCTL_I2SSTD BITS(4,5) /*!< I2S standard selection */ +#define SPI_I2SCTL_PCMSMOD BIT(7) /*!< PCM frame synchronization mode */ +#define SPI_I2SCTL_I2SOPMOD BITS(8,9) /*!< I2S operation mode */ +#define SPI_I2SCTL_I2SEN BIT(10) /*!< I2S enable */ +#define SPI_I2SCTL_I2SSEL BIT(11) /*!< I2S mode selection */ + +/* SPI_I2SPSC */ +#define SPI_I2SPSC_DIV BITS(0,7) /*!< dividing factor for the prescaler */ +#define SPI_I2SPSC_OF BIT(8) /*!< odd factor for the prescaler */ +#define SPI_I2SPSC_MCKOEN BIT(9) /*!< I2S MCK output enable */ + +/* SPIx_QCTL(x=1) */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad-SPI mode enable */ +#define SPI_QCTL_QRD BIT(1) /*!< quad-SPI mode read select */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 enable */ + +/* constants definitions */ +/* SPIx and I2Sx parameter struct definitions */ +typedef struct +{ + uint32_t device_mode; /*!< SPI master or slave */ + uint32_t trans_mode; /*!< SPI transtype */ + uint32_t frame_size; /*!< SPI frame size */ + uint32_t nss; /*!< SPI NSS control by handware or software */ + uint32_t endian; /*!< SPI big endian or little endian */ + uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ + uint32_t prescale; /*!< SPI prescale factor */ +}spi_parameter_struct; + +/* SPI mode definitions */ +#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +/* SPI bidirectional transfer direction */ +#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CTL0_BDOEN) /*!< SPI work in receive-only mode */ + +/* SPI transmit type */ +#define SPI_TRANSMODE_FULLDUPLEX ((uint32_t)0x00000000U) /*!< SPI receive and send data at fullduplex communication */ +#define SPI_TRANSMODE_RECEIVEONLY SPI_CTL0_RO /*!< SPI only receive data */ +#define SPI_TRANSMODE_BDRECEIVE SPI_CTL0_BDEN /*!< bidirectional receive data */ +#define SPI_TRANSMODE_BDTRANSMIT (SPI_CTL0_BDEN | SPI_CTL0_BDOEN) /*!< bidirectional transmit data*/ + +/* SPI NSS control mode */ +#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI NSS control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI NSS control by hardware */ + +/* SPI transmit way */ +#define SPI_ENDIAN_MSB ((uint32_t)0x00000000U) /*!< SPI transmit way is big endian: transmit MSB first */ +#define SPI_ENDIAN_LSB SPI_CTL0_LF /*!< SPI transmit way is little endian: transmit LSB first */ + +/* SPI clock phase and polarity */ +#define SPI_CK_PL_LOW_PH_1EDGE ((uint32_t)0x00000000U) /*!< SPI clock polarity is low level and phase is first edge */ +#define SPI_CK_PL_HIGH_PH_1EDGE SPI_CTL0_CKPL /*!< SPI clock polarity is high level and phase is first edge */ +#define SPI_CK_PL_LOW_PH_2EDGE SPI_CTL0_CKPH /*!< SPI clock polarity is low level and phase is second edge */ +#define SPI_CK_PL_HIGH_PH_2EDGE (SPI_CTL0_CKPL | SPI_CTL0_CKPH) /*!< SPI clock polarity is high level and phase is second edge */ + +/* SPI clock prescale factor */ +#define CTL0_PSC(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* SPIx frame size */ +#define CTL1_FRAMESIZE(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define SPI_FRAMESIZE_4BIT CTL1_FRAMESIZE(3) /*!< SPI frame size is 4 bits */ +#define SPI_FRAMESIZE_5BIT CTL1_FRAMESIZE(4) /*!< SPI frame size is 5 bits */ +#define SPI_FRAMESIZE_6BIT CTL1_FRAMESIZE(5) /*!< SPI frame size is 6 bits */ +#define SPI_FRAMESIZE_7BIT CTL1_FRAMESIZE(6) /*!< SPI frame size is 7 bits */ +#define SPI_FRAMESIZE_8BIT CTL1_FRAMESIZE(7) /*!< SPI frame size is 8 bits */ +#define SPI_FRAMESIZE_9BIT CTL1_FRAMESIZE(8) /*!< SPI frame size is 9 bits */ +#define SPI_FRAMESIZE_10BIT CTL1_FRAMESIZE(9) /*!< SPI frame size is 10 bits */ +#define SPI_FRAMESIZE_11BIT CTL1_FRAMESIZE(10) /*!< SPI frame size is 11 bits */ +#define SPI_FRAMESIZE_12BIT CTL1_FRAMESIZE(11) /*!< SPI frame size is 12 bits */ +#define SPI_FRAMESIZE_13BIT CTL1_FRAMESIZE(12) /*!< SPI frame size is 13 bits */ +#define SPI_FRAMESIZE_14BIT CTL1_FRAMESIZE(13) /*!< SPI frame size is 14 bits */ +#define SPI_FRAMESIZE_15BIT CTL1_FRAMESIZE(14) /*!< SPI frame size is 15 bits */ +#define SPI_FRAMESIZE_16BIT CTL1_FRAMESIZE(15) /*!< SPI frame size is 16 bits */ + +/* SPIx CRC length(x=1) */ +#define SPI_CRC_8BIT ((uint32_t)0x00000000U) /*!< SPI CRC length is 8 bits */ +#define SPI_CRC_16BIT SPI_CTL0_CRCL /*!< SPI CRC length is 16 bits */ + +/* SPIx byte access enable(x=1) */ +#define SPI_HALFWORD_ACCESS ((uint32_t)0x00000000U) /*!< SPI half-word access to FIFO */ +#define SPI_BYTE_ACCESS SPI_CTL1_BYTEN /*!< SPI byte access to FIFO */ + +/* SPIx odd bytes in TX DMA channel(x=1) */ +#define SPI_TXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in TX DMA channel is even */ +#define SPI_TXDMA_ODD SPI_CTL1_TXDMA_ODD /*!< SPI number of byte in TX DMA channel is odd */ + +/* SPIx odd bytes in RX DMA channel(x=1) */ +#define SPI_RXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in RX DMA channel is even */ +#define SPI_RXDMA_ODD SPI_CTL1_RXDMA_ODD /*!< SPI number of byte in RX DMA channel is odd */ + +/* SPIx TXFIFO level(x=1) */ +#define CTL1_TXLVL(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#define SPI_TXLVL_EMPTY CTL1_RXLVL(0) /*!< SPI TXFIFO is empty */ +#define SPI_TXLVL_QUARTER_FULL CTL1_RXLVL(1) /*!< SPI TXFIFO is a quarter of full */ +#define SPI_TXLVL_HAlF_FULL CTL1_RXLVL(2) /*!< SPI TXFIFO is a half of full */ +#define SPI_TXLVL_FULL CTL1_RXLVL(3) /*!< SPI TXFIFO is full */ + +/* SPIx RXFIFO level(x=1) */ +#define CTL1_RXLVL(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define SPI_RXLVL_EMPTY CTL1_RXLVL(0) /*!< SPI RXFIFO is empty */ +#define SPI_RXLVL_QUARTER_FULL CTL1_RXLVL(1) /*!< SPI RXFIFO is a quarter of full */ +#define SPI_RXLVL_HAlF_FULL CTL1_RXLVL(2) /*!< SPI RXFIFO is a half of full */ +#define SPI_RXLVL_FULL CTL1_RXLVL(3) /*!< SPI RXFIFO is full */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt flag */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt flag */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt flag */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode config error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< receive overrun error flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< channel side flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ + +/* function declarations */ +/* SPI/I2S deinitialization and initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with the default values */ +void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize SPI parameter */ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl); +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* NSS functions */ +/* enable SPI NSS output */ +void spi_nss_output_enable(uint32_t spi_periph); +/* disable SPI NSS output */ +void spi_nss_output_disable(uint32_t spi_periph); +/* SPI NSS pin high level in software mode */ +void spi_nss_internal_high(uint32_t spi_periph); +/* SPI NSS pin low level in software mode */ +void spi_nss_internal_low(uint32_t spi_periph); + +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma); + +/* configure SPI/I2S data frame format */ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* SPI transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); +/* SPI receive data */ +uint16_t spi_i2s_data_receive(uint32_t spi_periph); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); + +/* SPI CRC functions */ +/* set SPI CRC polynomial */ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly); +/* get SPI CRC polynomial */ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph); +/* turn on SPI CRC function */ +void spi_crc_on(uint32_t spi_periph); +/* turn off SPI CRC function */ +void spi_crc_off(uint32_t spi_periph); +/* SPI next data is CRC value */ +void spi_crc_next(uint32_t spi_periph); +/* get SPI CRC send value or receive value */ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc); + +/* SPI TI mode functions */ +/* enable SPI TI mode */ +void spi_ti_mode_enable(uint32_t spi_periph); +/* disable SPI TI mode */ +void spi_ti_mode_disable(uint32_t spi_periph); + +/* SPI NSS pulse mode functions */ +/* enable SPI NSS pulse mode */ +void spi_nssp_mode_enable(uint32_t spi_periph); +/* disable SPI NSS pulse mode */ +void spi_nssp_mode_disable(uint32_t spi_periph); + +/* quad wire SPI functions */ +/* enable quad wire SPI */ +void qspi_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void qspi_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void qspi_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void qspi_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_disable(uint32_t spi_periph); + +/* flag and interrupt functions */ +/* enable SPI and I2S interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt); +/* disable SPI and I2S interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S interrupt status */ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* only for SPI1 FIFO added */ +/* configure SPI access size to FIFO(8-bit or 16-bit) */ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size); +/* configure SPI total number of data transmitting by DMA is odd or not */ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd); +/* configure SPI total number of data receiving by DMA is odd or not */ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd); +/* set CRC length */ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length); + +#endif /* GD32E230_SPI_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h new file mode 100644 index 0000000000..9109a89602 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h @@ -0,0 +1,187 @@ +/*! + \file GD32e230_syscfg.h + \brief definitions for the SYSCFG + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_SYSCFG_H +#define GD32E230_SYSCFG_H + +#include "gd32e230.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x18U) /*!< system configuration register 2 */ +#define SYSCFG_CPU_IRQ_LAT REG32(SYSCFG + 0x100U) /*!< IRQ Latency register */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_PA11_PA12_RMP BIT(4) /*!< PA11 and PA12 remapping bit for small packages (28 and 20 pins) */ +#define SYSCFG_CFG0_ADC_DMA_RMP BIT(8) /*!< ADC DMA remap config */ +#define SYSCFG_CFG0_USART0_TX_DMA_RMP BIT(9) /*!< USART0 Tx DMA remap config */ +#define SYSCFG_CFG0_USART0_RX_DMA_RMP BIT(10) /*!< USART0 Rx DMA remap config */ +#define SYSCFG_CFG0_TIMER15_DMA_RMP BIT(11) /*!< TIMER 15 DMA remap config */ +#define SYSCFG_CFG0_TIMER16_DMA_RMP BIT(12) /*!< TIMER 16 DMA remap config */ +#define SYSCFG_CFG0_PB9_HCCE BIT(19) /*!< PB9 pin high current capability enable */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_CFG2 bits definitions */ +#define SYSCFG_CFG2_LOCKUP_LOCK BIT(0) /*!< enable and lock the LOCKUP (Hardfault) output of Cortex-M23 with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK BIT(1) /*!< enable and lock the SRAM_PARITY error signal with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_LVD_LOCK BIT(2) /*!< enable and lock the LVD connection with TIMER0 break input and also the LVD_EN and LVDSEL[2:0] bits of the power control interface */ +#define SYSCFG_CFG2_SRAM_PCEF BIT(8) /*!< SRAM parity check error flag */ + +/* SYSCFG_CPU_IRQ_LAT bits definitions */ +#define SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY BITS(0,7) /*!< IRQ_LATENCY specifies the minimum number of cycles between an interrupt */ + +/* constants definitions */ +/* DMA remap definitions */ +#define SYSCFG_PA11_REMAP_PA12 SYSCFG_CFG0_PA11_PA12_RMP /*!< PA11 PA12 remap */ +#define SYSCFG_DMA_REMAP_ADC SYSCFG_CFG0_ADC_DMA_RMP /*!< ADC DMA remap */ +#define SYSCFG_DMA_REMAP_USART0TX SYSCFG_CFG0_USART0_TX_DMA_RMP /*!< USART0_TX DMA remap */ +#define SYSCFG_DMA_REMAP_USART0RX SYSCFG_CFG0_USART0_RX_DMA_RMP /*!< USART0_RX DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER15 SYSCFG_CFG0_TIMER15_DMA_RMP /*!< TIMER15 DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER16 SYSCFG_CFG0_TIMER16_DMA_RMP /*!< TIMER16 DMA remap */ + +/* high current definitions */ +#define SYSCFG_HIGH_CURRENT_ENABLE SYSCFG_CFG0_PB9_HCCE /*!< high current enable */ +#define SYSCFG_HIGH_CURRENT_DISABLE (~SYSCFG_CFG0_PB9_HCCE) /*!< high current disable */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI source pin definitions */ +#define EXTI_SOURCE_PIN0 ((uint8_t)0x00U) /*!< EXTI GPIO pin0 configuration */ +#define EXTI_SOURCE_PIN1 ((uint8_t)0x01U) /*!< EXTI GPIO pin1 configuration */ +#define EXTI_SOURCE_PIN2 ((uint8_t)0x02U) /*!< EXTI GPIO pin2 configuration */ +#define EXTI_SOURCE_PIN3 ((uint8_t)0x03U) /*!< EXTI GPIO pin3 configuration */ +#define EXTI_SOURCE_PIN4 ((uint8_t)0x04U) /*!< EXTI GPIO pin4 configuration */ +#define EXTI_SOURCE_PIN5 ((uint8_t)0x05U) /*!< EXTI GPIO pin5 configuration */ +#define EXTI_SOURCE_PIN6 ((uint8_t)0x06U) /*!< EXTI GPIO pin6 configuration */ +#define EXTI_SOURCE_PIN7 ((uint8_t)0x07U) /*!< EXTI GPIO pin7 configuration */ +#define EXTI_SOURCE_PIN8 ((uint8_t)0x08U) /*!< EXTI GPIO pin8 configuration */ +#define EXTI_SOURCE_PIN9 ((uint8_t)0x09U) /*!< EXTI GPIO pin9 configuration */ +#define EXTI_SOURCE_PIN10 ((uint8_t)0x0AU) /*!< EXTI GPIO pin10 configuration */ +#define EXTI_SOURCE_PIN11 ((uint8_t)0x0BU) /*!< EXTI GPIO pin11 configuration */ +#define EXTI_SOURCE_PIN12 ((uint8_t)0x0CU) /*!< EXTI GPIO pin12 configuration */ +#define EXTI_SOURCE_PIN13 ((uint8_t)0x0DU) /*!< EXTI GPIO pin13 configuration */ +#define EXTI_SOURCE_PIN14 ((uint8_t)0x0EU) /*!< EXTI GPIO pin14 configuration */ +#define EXTI_SOURCE_PIN15 ((uint8_t)0x0FU) /*!< EXTI GPIO pin15 configuration */ + +/* lock definitions */ +#define SYSCFG_LOCK_LOCKUP SYSCFG_CFG2_LOCKUP_LOCK /*!< LOCKUP output lock */ +#define SYSCFG_LOCK_SRAM_PARITY_ERROR SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK /*!< SRAM parity error lock */ +#define SYSCFG_LOCK_LVD SYSCFG_CFG2_LVD_LOCK /*!< LVD lock */ + +/* SRAM parity check error flag definitions */ +#define SYSCFG_SRAM_PCEF SYSCFG_CFG2_SRAM_PCEF /*!< SRAM parity check error flag */ + +/* SYSCFG_CPU_IRQ_LAT register IRQ_LATENCY value */ +#define IRQ_LATENCY(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to IRQ_LATENCY bits field */ + +/* function declarations */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* enable the DMA channels remapping */ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap); +/* disable the DMA channels remapping */ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap); + +/* enable PB9 high current capability */ +void syscfg_high_current_enable(void); +/* disable PB9 high current capability */ +void syscfg_high_current_disable(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* connect TIMER0/14/15/16 break input to the selected parameter */ +void syscfg_lock_config(uint32_t syscfg_lock); + +/* set the IRQ_LATENCY value */ +void irq_latency_set(uint8_t irq_latency); + +/* check if the specified flag in SYSCFG_CFG2 is set or not */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag); +/* clear the flag in SYSCFG_CFG2 by writing 1 */ +void syscfg_flag_clear(uint32_t syscfg_flag); + +#endif /* GD32E230_SYSCFG_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h new file mode 100644 index 0000000000..c69aa8f895 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h @@ -0,0 +1,760 @@ +/*! + \file gd32e230_timer.h + \brief definitions for the TIMER + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_TIMER_H +#define GD32E230_TIMER_H + +#include "gd32e230.h" + +/* TIMERx(x=0,1,2,5,13..16) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER13 (TIMER_BASE + 0x00002000U) +#define TIMER14 (TIMER_BASE + 0x00014000U) +#define TIMER15 (TIMER_BASE + 0x00014400U) +#define TIMER16 (TIMER_BASE + 0x00014800U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_OCRC BIT(3) /*!< OCPRE clear source selection */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation interrupt request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 capture/compare interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture/compare interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture/compare interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture/compare interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 overcapture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 overcapture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 overcapture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 overcapture flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRKG BIT(7) /*!< break event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS BITS(0,1) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMFEN BIT(2) /*!< channel 0 output compare fast enable */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare mode */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMFEN BIT(10) /*!< channel 1 output compare fast enable */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare mode */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL0_CH0CAPPSC BITS(2,3) /*!< channel 0 input capture prescaler */ +#define TIMER_CHCTL0_CH0CAPFLT BITS(4,7) /*!< channel 0 input capture filter control */ +#define TIMER_CHCTL0_CH1CAPPSC BITS(10,11) /*!< channel 1 input capture prescaler */ +#define TIMER_CHCTL0_CH1CAPFLT BITS(12,15) /*!< channel 1 input capture filter control */ + +/* TIMER_CHCTL1 */ +/* output compare mode */ +#define TIMER_CHCTL1_CH2MS BITS(0,1) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMFEN BIT(2) /*!< channel 2 output compare fast enable */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare mode */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMFEN BIT(10) /*!< channel 3 output compare fast enable */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare mode */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 capture/compare function enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture/compare function polarity */ +#define TIMER_CHCTL2_CH0NEN BIT(2) /*!< channel 0 complementary output enable */ +#define TIMER_CHCTL2_CH0NP BIT(3) /*!< channel 0 complementary output polarity */ +#define TIMER_CHCTL2_CH1EN BIT(4) /*!< channel 1 capture/compare function enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture/compare function polarity */ +#define TIMER_CHCTL2_CH1NEN BIT(6) /*!< channel 1 complementary output enable */ +#define TIMER_CHCTL2_CH1NP BIT(7) /*!< channel 1 complementary output polarity */ +#define TIMER_CHCTL2_CH2EN BIT(8) /*!< channel 2 capture/compare function enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture/compare function polarity */ +#define TIMER_CHCTL2_CH2NEN BIT(10) /*!< channel 2 complementary output enable */ +#define TIMER_CHCTL2_CH2NP BIT(11) /*!< channel 2 complementary output polarity */ +#define TIMER_CHCTL2_CH3EN BIT(12) /*!< channel 3 capture/compare function enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture/compare function polarity */ +#define TIMER_CHCTL2_CH3NP BIT(15) /*!< channel 3 complementary output polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT16 BITS(0,15) /*!< 16 bit timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL16 BITS(0,15) /*!< 16 bit counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER13_IRMP_CI0_RMP BITS(0,1) /*!< TIMER13 channel 0 input remap */ + +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ + +/* constants definitions */ +/* TIMER init parameter struct definitions*/ +typedef struct +{ + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + uint16_t clockdivision; /*!< clock division value */ + uint32_t period; /*!< period value */ + uint8_t repetitioncounter; /*!< the counter repetition value */ +}timer_parameter_struct; + +/* break parameter struct definitions*/ +typedef struct +{ + uint16_t runoffstate; /*!< run mode off-state */ + uint16_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< dead time */ + uint16_t breakpolarity; /*!< break polarity */ + uint16_t outputautostate; /*!< output automatic enable */ + uint16_t protectmode; /*!< complementary register protect control */ + uint16_t breakstate; /*!< break enable */ +}timer_break_parameter_struct; + +/* channel output parameter struct definitions */ +typedef struct +{ + uint16_t outputstate; /*!< channel output state */ + uint16_t outputnstate; /*!< channel complementary output state */ + uint16_t ocpolarity; /*!< channel output polarity */ + uint16_t ocnpolarity; /*!< channel complementary output polarity */ + uint16_t ocidlestate; /*!< idle state of channel output */ + uint16_t ocnidlestate; /*!< idle state of channel complementary output */ +}timer_oc_parameter_struct; + +/* channel input parameter struct definitions */ +typedef struct +{ + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +}timer_ic_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK TIMER_INTF_BRKIF + +/* TIMER DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)TIMER_DMAINTEN_CH1DEN) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)TIMER_DMAINTEN_CH2DEN) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)TIMER_DMAINTEN_CH3DEN) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)TIMER_DMAINTEN_CMTDEN) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)TIMER_DMAINTEN_TRGDEN) /*!< trigger DMA enable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< the prescaler is loaded at the next update event */ + +/* count direction */ +#define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ +#define TIMER_COUNTER_DOWN ((uint16_t)TIMER_CTL0_DIR) /*!< counter down direction */ + +/* specify division ratio between TIMER clock and dead-time and sampling clock */ +#define CTL0_CKDIV(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CKDIV_DIV1 CTL0_CKDIV(0) /*!< clock division value is 1, fDTS=fTIMER_CK */ +#define TIMER_CKDIV_DIV2 CTL0_CKDIV(1) /*!< clock division value is 2, fDTS= fTIMER_CK/2 */ +#define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS= fTIMER_CK/4 */ + +/* single pulse mode */ +#define TIMER_SP_MODE_SINGLE TIMER_CTL0_SPM /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint16_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, he channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)TIMER_CCHP_BRKP) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)TIMER_CCHP_BRKEN) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0(TIMERx(x=0,2,13..16)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0,2,14)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0,2)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0,2)) */ +#define TIMER_CH_0_1 ((uint16_t)0x0004U) /*!< TIMER channel 0 and 1 for function parameter */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint32_t)0x00000001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint32_t)0x00000000U) /*!< channel disable */ + +/* channel complementary output enable state*/ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000) /*!< channel output fast function disable */ + +/* channel output compare clear enable */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint32_t)0x00000000U) /*!< the shadow registers are updated when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI TIMER_CTL1_CCUC /*!< the shadow registers are updated when CMTG bit is set or an rising edge of TRGI occurs */ + +/* channel input capture polarity */ +#define TIMER_IC_POLARITY_RISING ((uint16_t)0x0000U) /*!< input capture rising edge */ +#define TIMER_IC_POLARITY_FALLING ((uint16_t)0x0002U) /*!< input capture falling edge */ +#define TIMER_IC_POLARITY_BOTH_EDGE ((uint16_t)0x000AU) /*!< input capture both edge */ + +/* TIMER input capture selection */ +#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel y is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel y is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel y is configured as input and icy is mapped on ITS */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4*/ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 Edge Detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< external trigger */ + +/* master mode control */ +#define CTL1_MMC(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT_SRC_RESET CTL1_MMC(0) /*!< the UPG bit as trigger output */ +#define TIMER_TRI_OUT_SRC_ENABLE CTL1_MMC(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */ +#define TIMER_TRI_OUT_SRC_UPDATE CTL1_MMC(2) /*!< update event as trigger output */ +#define TIMER_TRI_OUT_SRC_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */ +#define TIMER_TRI_OUT_SRC_O0CPRE CTL1_MMC(4) /*!< O0CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O1CPRE CTL1_MMC(5) /*!< O1CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O2CPRE CTL1_MMC(6) /*!< O2CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O3CPRE CTL1_MMC(7) /*!< O3CPRE as trigger output */ + +/* slave mode control */ +#define SMCFG_SMC(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0U)) +#define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ +#define TIMER_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ +#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ +#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ + +/* OCPRE clear source selection */ +#define TIMER_OCPRE_CLEAR_SOURCE_CLR ((uint8_t)0x00U) /*!< OCPRE_CLR_INT is connected to the OCPRE_CLR input */ +#define TIMER_OCPRE_CLEAR_SOURCE_ETIF ((uint8_t)0x01U) /*!< OCPRE_CLR_INT is connected to ETIF */ +#define TIMER_OCPRE_CLEAR_SOURCE_DISABLE ((uint8_t)0x02U) /*!< OCRC=0, and disable ETI */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE TIMER_SMCFG_MSM /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< master slave mode disable */ + +/* external trigger prescaler */ +#define SMCFG_ETPSC(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12U)) +#define TIMER_EXT_TRI_PSC_OFF SMCFG_ETPSC(0) /*!< no divided */ +#define TIMER_EXT_TRI_PSC_DIV2 SMCFG_ETPSC(1) /*!< divided by 2 */ +#define TIMER_EXT_TRI_PSC_DIV4 SMCFG_ETPSC(2) /*!< divided by 4 */ +#define TIMER_EXT_TRI_PSC_DIV8 SMCFG_ETPSC(3) /*!< divided by 8 */ + +/* external trigger polarity */ +#define TIMER_ETP_FALLING TIMER_SMCFG_ETP /*!< active low or falling edge active */ +#define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */ + +/* TIMERx(x=0,2,13,14,15,16) write cc register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CC register selection enable */ + +/* the output value selection */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< output value selection enable */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection enable */ + +/* timer13 channel 0 input remap */ +#define TIMER13_IRMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER13_CI0_RMP_GPIO TIMER13_IRMP(0) /*!< timer13 channel 0 input is connected to GPIO(TIMER13_CH0) */ +#define TIMER13_CI0_RMP_RTCCLK TIMER13_IRMP(1) /*!< timer13 channel 0 input is connected to the RTCCLK */ +#define TIMER13_CI0_RMP_HXTAL_DIV32 TIMER13_IRMP(2) /*!< timer13 channel 0 input is connected to HXTAL/32 clock */ +#define TIMER13_CI0_RMP_CKOUTSEL TIMER13_IRMP(3) /*!< timer13 channel 0 input is connected to CKOUTSEL */ + +/* function declarations */ +/* TIMER timebase*/ +/* deinit a TIMER */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER init parameter struct */ +void timer_struct_para_init(timer_parameter_struct* initpara); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara); +/* enable a TIMER */ +void timer_enable(uint32_t timer_periph); +/* disable a TIMER */ +void timer_disable(uint32_t timer_periph); +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph , uint16_t counter); +/* read TIMER counter value */ +uint32_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); +/* OCPRE clear source selection */ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear); + +/* TIMER interrupt and flag*/ +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get timer interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); + +/* timer DMA and event*/ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr, uint32_t dma_lenth); +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event); + +/* TIMER channel complementary protection */ +/* initialize TIMER break parameter struct */ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara); +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara); +/* enable TIMER break function */ +void timer_break_enable(uint32_t timer_periph); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph); +/* enable TIMER output automatic function */ +void timer_automatic_output_enable(uint32_t timer_periph); +/* disable TIMER output automatic function */ +void timer_automatic_output_disable(uint32_t timer_periph); +/* enable or disable TIMER primary output function */ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue); +/* enable or disable channel capture/compare control shadow register */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph,uint16_t channel, timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel,uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t channel,uint16_t occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate); + +/* TIMER channel input */ +/* initialize TIMER channel input parameter struct */ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara); +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode); + +/* TIMER master and slave */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph,uint32_t slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity); +/* configure TIMER internal clock mode */ +void timer_internal_clock_config(uint32_t timer_periph); +/* configure TIMER the internal trigger as external clock input */ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity,uint32_t extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); +/* configure TIMER channel remap function */ +void timer_channel_remap_config(uint32_t timer_periph,uint32_t remap); + +/* TIMER configure */ +/* configure TIMER write CHxVAL register selection */ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel); + +#endif /* GD32E230_TIMER_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h new file mode 100644 index 0000000000..6cb6f61056 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h @@ -0,0 +1,614 @@ +/*! + \file gd32e230_usart.h + \brief definitions for the USART + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_USART_H +#define GD32E230_USART_H + +#include "gd32e230.h" + +/* USARTx(x=0,1) definitions */ +#define USART0 (USART_BASE + 0x0000F400U) +#define USART1 USART_BASE + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00000000U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x00000004U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x00000008U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0000000CU) /*!< USART baud rate register */ +#define USART_GP(usartx) REG32((usartx) + 0x00000010U) /*!< USART guard time and prescaler register */ +#define USART_RT(usartx) REG32((usartx) + 0x00000014U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x00000018U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x0000001CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x00000020U) /*!< USART status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x00000024U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x00000028U) /*!< USART transmit data register */ +#define USART_CHC(usartx) REG32((usartx) + 0x000000C0U) /*!< USART coherence control register */ +#define USART_RFCS(usartx) REG32((usartx) + 0x000000D0U) /*!< USART receive FIFO control and status register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< USART enable */ +#define USART_CTL0_UESM BIT(1) /*!< USART enable in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter register empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity control enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< mute mode enable */ +#define USART_CTL0_AMIE BIT(14) /*!< address match interrupt enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< driver enable deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< driver enable assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< receiver timeout interrupt enable */ +#define USART_CTL0_EBIE BIT(27) /*!< end of block interrupt enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDM BIT(4) /*!< address detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detection interrupt enable */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< ck pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_ABDEN BIT(20) /*!< auto baud rate enable */ +#define USART_CTL1_ABDM BITS(21,22) /*!< auto baud rate mode */ +#define USART_CTL1_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< overrun disable */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< driver enable mode */ +#define USART_CTL2_DEP BIT(15) /*!< driver enable polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< wakeup from deep-sleep mode interrupt enable */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_ABDCMD BIT(0) /*!< auto baudrate detection command */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_ABDE BIT(14) /*!< auto baudrate detection error */ +#define USART_STAT_ABDF BIT(15) /*!< auto baudrate detection flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF BIT(17) /*!< address match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< parity error clear */ +#define USART_INTC_FEC BIT(1) /*!< frame error flag clear */ +#define USART_INTC_NEC BIT(2) /*!< noise detected clear */ +#define USART_INTC_OREC BIT(3) /*!< overrun error clear */ +#define USART_INTC_IDLEC BIT(4) /*!< idle line detected clear */ +#define USART_INTC_TCC BIT(6) /*!< transmission complete clear */ +#define USART_INTC_LBDC BIT(8) /*!< LIN break detected clear */ +#define USART_INTC_CTSC BIT(9) /*!< CTS change clear */ +#define USART_INTC_RTC BIT(11) /*!< receiver timeout clear */ +#define USART_INTC_EBC BIT(12) /*!< end of timeout clear */ +#define USART_INTC_AMC BIT(17) /*!< address match clear */ +#define USART_INTC_WUC BIT(20) /*!< wakeup from deep-sleep mode clear */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,8) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,8) /*!< transmit data value */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* USARTx_RFCS */ +#define USART_RFCS_ELNACK BIT(0) /*!< early NACK */ +#define USART_RFCS_RFEN BIT(8) /*!< receive FIFO enable */ +#define USART_RFCS_RFFIE BIT(9) /*!< receive FIFO full interrupt enable */ +#define USART_RFCS_RFE BIT(10) /*!< receive FIFO empty flag */ +#define USART_RFCS_RFF BIT(11) /*!< receive FIFO full flag */ +#define USART_RFCS_RFCNT BITS(12,14) /*!< receive FIFO counter number */ +#define USART_RFCS_RFFINT BIT(15) /*!< receive FIFO full interrupt flag */ + +/* constants definitions */ + +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET 0x00000000U /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x00000004U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x00000008U /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET 0x0000001CU /*!< STAT register offset */ +#define USART_CHC_REG_OFFSET 0x000000C0U /*!< CHC register offset */ +#define USART_RFCS_REG_OFFSET 0x000000D0U /*!< RFCS register offset */ + +/* USART flags */ +typedef enum{ + /* flags in STAT register */ + USART_FLAG_REA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 22U), /*!< receive enable acknowledge flag */ + USART_FLAG_TEA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 21U), /*!< transmit enable acknowledge flag */ + USART_FLAG_WU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 20U), /*!< wakeup from Deep-sleep mode flag */ + USART_FLAG_RWU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 19U), /*!< receiver wakeup from mute mode */ + USART_FLAG_SB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 18U), /*!< send break flag */ + USART_FLAG_AM = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 17U), /*!< ADDR match flag */ + USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_ABD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U), /*!< auto baudrate detection flag */ + USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U), /*!< auto baudrate detection error */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ + /* flags in RFCS register */ + USART_FLAG_RFFINT = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt flag */ + USART_FLAG_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 11U), /*!< receive FIFO full flag */ + USART_FLAG_RFE = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 10U), /*!< receive FIFO empty flag */ +}usart_flag_enum; + +/* USART interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 27U, USART_STAT_REG_OFFSET, 12U), /*!< end of block interrupt and flag */ + USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout interrupt and flag */ + USART_INT_FLAG_AM = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U), /*!< address match interrupt and flag */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */ + /* interrupt flags in CTL1 register */ + USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_WU = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 22U, USART_STAT_REG_OFFSET, 20U), /*!< wakeup from deep-sleep mode interrupt and flag */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ + /* interrupt flags in RFCS register */ + USART_INT_FLAG_RFF = USART_REGIDX_BIT2(USART_RFCS_REG_OFFSET, 9U, USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt and flag */ +}usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL0 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */ + USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt in CTL1 register */ + USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt in CTL2 register */ + USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ + /* interrupt in RFCS register */ + USART_INT_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 9U), /*!< receive FIFO full interrupt */ +}usart_interrupt_enum; + +/* USART invert configure */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE, /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* USART receiver configure */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* USART transmitter configure */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address match */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART address detection mode */ +#define CTL1_ADDM(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM_4BIT CTL1_ADDM(0) /*!< 4-bit address detection */ +#define USART_ADDM_FULLBIT CTL1_ADDM(1) /*!< full-bit address detection */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 bit */ +#define USART_STB_0_5BIT CTL1_STB(1) /*!< 0.5 bit */ +#define USART_STB_2BIT CTL1_STB(2) /*!< 2 bits */ +#define USART_STB_1_5BIT CTL1_STB(3) /*!< 1.5 bits */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL1_MSBF(regval) (BIT(19) & ((uint32_t)(regval) << 19)) +#define USART_MSBF_LSB CTL1_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL1_MSBF(1) /*!< MSB first */ + +/* USART auto baud rate detection mode bits definitions */ +#define CTL1_ABDM(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define USART_ABDM_FTOR CTL1_ABDM(0) /*!< falling edge to rising edge measurement */ +#define USART_ABDM_FTOF CTL1_ABDM(1) /*!< falling edge to falling edge measurement */ + +/* USART IrDA low-power enable */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* DMA enable for reception */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CTL2_DENR(1) /*!< enable for reception */ +#define USART_DENR_DISABLE CTL2_DENR(0) /*!< disable for reception */ + +/* DMA enable for transmission */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CTL2_DENT(1) /*!< enable for transmission */ +#define USART_DENT_DISABLE CTL2_DENT(0) /*!< disable for transmission */ + +/* USART RTS hardware flow control configure */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* USART CTS hardware flow control configure */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* USART hardware flow control coherence mode */ +#define CHC_HCM(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define USART_HCM_NONE CHC_HCM(0) /*!< nRTS signal equals to the rxne status register */ +#define USART_HCM_EN CHC_HCM(1) /*!< nRTS signal is set when the last data bit has been sampled */ + +/* function declarations */ +/* initialization functions */ +/* reset USART */ +void usart_deinit(uint32_t usart_periph); +/* configure USART baud rate value */ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval); +/* configure USART parity function */ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg); +/* configure USART word length */ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen); +/* configure USART stop bit length */ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen); +/* enable USART */ +void usart_enable(uint32_t usart_periph); +/* disable USART */ +void usart_disable(uint32_t usart_periph); +/* configure USART transmitter */ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig); +/* configure USART receiver */ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig); + +/* USART normal mode communication */ +/* data is transmitted/received with the LSB/MSB first */ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf); +/* configure USART inverted */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* enable the USART overrun function */ +void usart_overrun_enable(uint32_t usart_periph); +/* disable the USART overrun function */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint32_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); + +/* auto baud rate detection */ +/* enable auto baud rate detection */ +void usart_autobaud_detection_enable(uint32_t usart_periph); +/* disable auto baud rate detection */ +void usart_autobaud_detection_disable(uint32_t usart_periph); +/* configure auto baud rate detection mode */ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* configure address detection mode */ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* enable mute mode */ +void usart_mute_mode_enable(uint32_t usart_periph); +/* disable mute mode */ +void usart_mute_mode_disable(uint32_t usart_periph); +/* configure wakeup method in mute mode */ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod); + +/* LIN mode communication */ +/* enable LIN mode */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* disable LIN mode */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* enable half-duplex mode */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* disable half-duplex mode */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* enable clock */ +void usart_clock_enable(uint32_t usart_periph); +/* disable clock */ +void usart_clock_disable(uint32_t usart_periph); +/* configure USART synchronous mode parameters */ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl); + +/* smartcard communication */ +/* configure guard time value in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* enable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph); +/* disable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* enable RS485 driver */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* disable RS485 driver */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* configure driver enable assertion time */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* configure driver enable de-assertion time */ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime); +/* configure driver enable polarity mode */ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep); + +/* USART DMA */ +/* configure USART DMA for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* enable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* disable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* configure the USART wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* USART receive FIFO */ +/* enable receive FIFO */ +void usart_receive_fifo_enable(uint32_t usart_periph); +/* disable receive FIFO */ +void usart_receive_fifo_disable(uint32_t usart_periph); +/* read receive FIFO counter number */ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph); + +/* flag & interrupt functions */ +/* get flag in STAT/RFCS register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear USART status */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); +/* clear USART interrupt flag */ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag); + +#endif /* GD32E230_USART_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h new file mode 100644 index 0000000000..38445b36de --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h @@ -0,0 +1,88 @@ +/*! + \file gd32e230_wwdgt.h + \brief definitions for the WWDGT + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_WWDGT_H +#define GD32E230_WWDGT_H + +#include "gd32e230.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00000000U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x00000004U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x00000008U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< WWDGT early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< WWDGT early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7U)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 ((uint32_t)CFG_PSC(0)) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 ((uint32_t)CFG_PSC(1)) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 ((uint32_t)CFG_PSC(2)) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 ((uint32_t)CFG_PSC(3)) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32E230_WWDGT_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c new file mode 100644 index 0000000000..d0f7065336 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c @@ -0,0 +1,844 @@ +/*! + \file gd32e230_adc.c + \brief ADC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_adc.h" + +/*! + \brief reset ADC + \param[in] none + \param[out] none + \retval none +*/ +void adc_deinit(void) +{ + rcu_periph_reset_enable(RCU_ADCRST); + rcu_periph_reset_disable(RCU_ADCRST); +} + +/*! + \brief enable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(void) +{ + if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){ + ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] none + \param[out] none + \retval none +*/ +void adc_calibration_enable(void) +{ + /* reset the selected ADC calibration register */ + ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1 & ADC_CTL1_RSTCLB)){ + } + + /* enable ADC calibration process */ + ADC_CTL1 |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1 & ADC_CTL1_CLB)){ + } +} + +/*! + \brief enable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(void) +{ + ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief enable the temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_enable(void) +{ + /* enable the temperature sensor and Vrefint channel */ + ADC_CTL1 |= ADC_CTL1_TSVREN; +} + +/*! + \brief disable the temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_disable(void) +{ + /* disable the temperature sensor and Vrefint channel */ + ADC_CTL1 &= ~ADC_CTL1_TSVREN; +} + +/*! + \brief configure ADC discontinuous mode + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular and inserted channel + \param[in] length: number of conversions in discontinuous mode, the number can be 1..8 + for regular channel, the number has no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length) +{ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the number of conversions in discontinuous mode */ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0 |= CTL0_DISNUM(((uint32_t)length - 1U)); + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + default: + break; + } +} + +/*! + \brief configure ADC special function + \param[in] function: the function to configure + one or more parameters can be selected which is shown as below: + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t function, ControlStatus newvalue) +{ + if(newvalue){ + /* enable ADC scan mode */ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 |= ADC_SCAN_MODE; + } + /* enable ADC inserted channel group convert automatically */ + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO; + } + /* enable ADC continuous mode */ + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 |= ADC_CONTINUOUS_MODE; + } + }else{ + /* disable ADC scan mode */ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 &= ~ADC_SCAN_MODE; + } + /* disable ADC inserted channel group convert automatically */ + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO; + } + /* disable ADC continuous mode */ + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 &= ~ADC_CONTINUOUS_MODE; + } + } +} + +/*! + \brief configure ADC data alignment + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: right alignment + \arg ADC_DATAALIGN_LEFT: left alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT != data_alignment){ + ADC_CTL1 |= ADC_CTL1_DAL; + }else{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint8_t channel_group, uint32_t length) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the length of regular channel group */ + ADC_RSQ0 &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0 |= RSQ0_RL((uint32_t)(length-1U)); + break; + case ADC_INSERTED_CHANNEL: + /* configure the length of inserted channel group */ + ADC_ISQ &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ |= ISQ_IL((uint32_t)(length-1U)); + break; + default: + break; + } +} + +/*! + \brief configure ADC regular channel + \param[in] rank: the regular group sequence rank, this parameter must be between 0 to 15 + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[in] sample_time: the sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* configure ADC regular sequence */ + if(rank < 6U){ + rsq = ADC_RSQ2; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)channel << (5U*rank)); + ADC_RSQ2 = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)channel << (5U*(rank-6U))); + ADC_RSQ1 = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)channel << (5U*(rank-12U))); + ADC_RSQ0 = rsq; + }else{ + } + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t)(sample_time << (3U*channel)); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[in] sample_time: The sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ , 20U , 21U); + + isq = ADC_ISQ; + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U))); + isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U)); + ADC_ISQ = isq; + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t) sample_time << (3U*channel); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel - 10U)))); + sampt |= ((uint32_t)sample_time << (3U*(channel - 10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel offset + \param[in] inserted_channel: insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[in] offset: the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U); + num = 3U - (inserted_length - inserted_channel); + + if(num <= 3U){ + /* calculate the offset of the register */ + num = num * 4U; + /* configure the offset of the selected channels */ + REG32((ADC) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief enable or disable ADC external trigger + \param[in] channel_group: select the channel group + one or more parameters can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue) +{ + if(newvalue){ + /* external trigger enable for regular channel */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETERC; + } + /* external trigger enable for inserted channel */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETEIC; + } + }else{ + /* external trigger disable for regular channel */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETERC; + } + /* external trigger disable for inserted channel */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETEIC; + } + } +} + +/*! + \brief configure ADC external trigger source + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + only one parameter can be selected which is shown as below: + for regular channel: + \arg ADC_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select + \arg ADC_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select + \arg ADC_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select + \arg ADC_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select + \arg ADC_EXTTRIG_REGULAR_T14_CH0: TIMER14 CH0 event select + \arg ADC_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11 + \arg ADC_EXTTRIG_REGULAR_NONE: software trigger + for inserted channel: + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select + \arg ADC_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select + \arg ADC_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select + \arg ADC_EXTTRIG_INSERTED_T14_TRGO: TIMER14 TRGO event select + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \arg ADC_EXTTRIG_INSERTED_NONE: software trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* external trigger select for regular channel */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + /* external trigger select for inserted channel */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger + \param[in] channel_group: select the channel group + one or more parameters can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint8_t channel_group) +{ + /* enable regular group channel software trigger */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWRCST; + } + /* enable inserted channel group software trigger */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWICST; + } +} + +/*! + \brief read ADC regular group data register + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(void) +{ + return ((uint16_t)ADC_RDATA); +} + +/*! + \brief read ADC inserted group data register + \param[in] inserted_channel: inserted channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[out] none + \retval the conversion value +*/ +uint16_t adc_inserted_data_read(uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel){ + case ADC_INSERTED_CHANNEL_0: + idata = ADC_IDATA0; + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1; + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2; + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3; + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief get the ADC flag bits + \param[in] flag: the adc flag bits + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t flag) +{ + FlagStatus reval = RESET; + + if(ADC_STAT & flag){ + reval = SET; + } + return reval; +} + +/*! + \brief clear the ADC flag + \param[in] flag: the adc flag + one or more parameters can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief get the ADC interrupt flag + \param[in] flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + + /* check the interrupt bits */ + switch(flag){ + case ADC_INT_FLAG_WDE: + state = ADC_STAT & ADC_STAT_WDE; + if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + state = ADC_STAT & ADC_STAT_EOC; + if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + state = ADC_STAT & ADC_STAT_EOIC; + if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear ADC interrupt flag + \param[in] flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] interrupt: the adc interrupt + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t interrupt) +{ + /* enable analog watchdog interrupt */ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_WDEIE; + } + + /* enable end of group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_EOCIE; + } + + /* enable end of inserted group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_EOICIE; + } +} + +/*! + \brief disable ADC interrupt + \param[in] interrupt: the adc interrupt flag + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t interrupt) +{ + /* disable analog watchdog interrupt */ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_WDEIE; + } + + /* disable end of group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOCIE; + } + + /* disable end of inserted group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOICIE; + } +} + +/*! + \brief configure ADC analog watchdog single channel + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint8_t channel) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); + + ADC_CTL0 |= (uint32_t)channel; + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); +} + +/*! + \brief configure ADC analog watchdog group channel + \param[in] channel_group: the channel group use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_group_channel_enable(uint8_t channel_group) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); + + /* select the group */ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog_disable(void) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); +} + +/*! + \brief configure ADC analog watchdog threshold + \param[in] low_threshold: analog watchdog low threshold,0..4095 + \param[in] high_threshold: analog watchdog high threshold,0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold) +{ + ADC_WDLT = (uint32_t)WDLT_WDLT(low_threshold); + ADC_WDHT = (uint32_t)WDHT_WDHT(high_threshold); +} + + +/*! + \brief configure ADC resolution + \param[in] resolution: ADC resolution + only one parameter can be selected which is shown as below: + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t resolution) +{ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0 |= (uint32_t)resolution; +} + +/*! + \brief configure ADC oversample mode + \param[in] mode: ADC oversampling mode + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger + \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger + \param[in] shift: ADC oversampling shift + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift + \param[in] ratio: ADC oversampling ratio + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio) +{ + /* configure ADC oversampling mode */ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode){ + ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + + /* configure the shift and ratio */ + ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(void) +{ + ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(void) +{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c new file mode 100644 index 0000000000..46ef66cbcf --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c @@ -0,0 +1,180 @@ +/*! + \file gd32e230_cmp.c + \brief CMP driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_cmp.h" + +/*! + \brief deinitialize comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_deinit(void) +{ + CMP_CS = ((uint32_t)0x00000000U); +} + +/*! + \brief initialize comparator mode + \param[in] operating_mode + \arg CMP_HIGHSPEED: high speed mode + \arg CMP_MIDDLESPEED: medium speed mode + \arg CMP_LOWSPEED: low speed mode + \arg CMP_VERYLOWSPEED: very-low speed mode + \param[in] inverting_input + \arg CMP_1_4VREFINT: VREFINT *1/4 input + \arg CMP_1_2VREFINT: VREFINT *1/2 input + \arg CMP_3_4VREFINT: VREFINT *3/4 input + \arg CMP_VREFINT: VREFINT input + \arg CMP_PA4: PA4 input + \arg CMP_PA5: PA5 input + \arg CMP_PA0: PA0 input + \arg CMP_PA2: PA2 input + \param[in] hysteresis + \arg CMP_HYSTERESIS_NO: output no hysteresis + \arg CMP_HYSTERESIS_LOW: output low hysteresis + \arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis + \arg CMP_HYSTERESIS_HIGH: output high hysteresis + \param[out] none + \retval none +*/ +void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis) +{ + /* initialize comparator mode */ + CMP_CS |= CS_CMPM(operating_mode) | CS_CMPMSEL(inverting_input) | CS_CMPHST(output_hysteresis); + +} + +/*! + \brief initialize comparator output + \param[in] output_slection + \arg CMP_OUTPUT_NONE: output no selection + \arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input + \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture + \arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture + \arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input + \param[in] output_polarity + \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted + \arg CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted + \param[out] none + \retval none +*/ +void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity) +{ + /* initialize comparator output */ + + CMP_CS |= CS_CMPOSEL(output_slection); + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + CMP_CS |= CMP_CS_CMPPL; + }else{ + CMP_CS &= ~CMP_CS_CMPPL; + } + +} + +/*! + \brief enable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_enable(void) +{ + CMP_CS |= CMP_CS_CMPEN; +} + +/*! + \brief disable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_disable(void) +{ + CMP_CS &= ~CMP_CS_CMPEN; +} + +/*! + \brief enable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_enable(void) +{ + CMP_CS |= CMP_CS_CMPSW; +} + +/*! + \brief disable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_disable(void) +{ + CMP_CS &= ~CMP_CS_CMPSW; +} + +/*! + \brief get output level + \param[in] none + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(void) +{ + if(CMP_CS & CMP_CS_CMPO){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + +} + +/*! + \brief lock the comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_lock_enable(void) +{ + CMP_CS |= CMP_CS_CMPLK; +} + diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c new file mode 100644 index 0000000000..59391d7d38 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c @@ -0,0 +1,206 @@ +/*! + \file gd32e230_crc.c + \brief CRC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_crc.h" + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_IDATA = (uint32_t)0xFFFFFFFFU; + CRC_DATA = (uint32_t)0xFFFFFFFFU; + CRC_FDATA = (uint32_t)0x00000000U; + CRC_POLY = (uint32_t)0x04C11DB7U; + CRC_CTL = CRC_CTL_RST; +} + +/*! + \brief enable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_enable(void) +{ + CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O); + CRC_CTL |= (uint32_t)CRC_CTL_REV_O; +} + +/*! + \brief disable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_disable(void) +{ + CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O); +} + +/*! + \brief reset data register to the value of initializaiton data register + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the data register + \param[in] none + \param[out] none + \retval 32-bit value of the data register +*/ +uint32_t crc_data_register_read(void) +{ + uint32_t data; + data = CRC_DATA; + return (data); +} + +/*! + \brief read the free data register + \param[in] none + \param[out] none + \retval 8-bit value of the free data register +*/ +uint8_t crc_free_data_register_read(void) +{ + uint8_t fdata; + fdata = (uint8_t)CRC_FDATA; + return (fdata); +} + +/*! + \brief write the free data register + \param[in] free_data: specify 8-bit data + \param[out] none + \retval none +*/ +void crc_free_data_register_write(uint8_t free_data) +{ + CRC_FDATA = (uint32_t)free_data; +} + +/*! + \brief write the initializaiton data register + \param[in] init_data:specify 32-bit data + \param[out] none + \retval none +*/ +void crc_init_data_register_write(uint32_t init_data) +{ + CRC_IDATA = (uint32_t)init_data; +} + +/*! + \brief configure the CRC input data function + \param[in] data_reverse: specify input data reverse function + \arg CRC_INPUT_DATA_NOT: input data is not reversed + \arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits + \arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits + \arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits + \param[out] none + \retval none +*/ +void crc_input_data_reverse_config(uint32_t data_reverse) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I); + CRC_CTL |= (uint32_t)data_reverse; +} + +/*! + \brief configure the CRC size of polynomial function + \param[in] poly_size: size of polynomial + \arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation + \arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation + \arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation + \arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation + \param[out] none + \retval none +*/ +void crc_polynomial_size_set(uint32_t poly_size) +{ + CRC_CTL &= (uint32_t)(~(CRC_CTL_PS)); + CRC_CTL |= (uint32_t)poly_size; +} + +/*! + \brief configure the CRC polynomial value function + \param[in] poly: configurable polynomial value + \param[out] none + \retval none +*/ +void crc_polynomial_set(uint32_t poly) +{ + CRC_POLY &= (uint32_t)(~CRC_POLY_POLY); + CRC_POLY = poly; +} + +/*! + \brief CRC calculate a 32-bit data + \param[in] sdata: specify 32-bit data + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return(CRC_DATA); +} + +/*! + \brief CRC calculate a 32-bit data array + \param[in] array: pointer to an array of 32 bit data words + \param[in] size: size of the array + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++){ + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c new file mode 100644 index 0000000000..614bd6016e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c @@ -0,0 +1,140 @@ +/*! + \file gd32e230_dbg.c + \brief DBG driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted + \arg DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted + \arg DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c new file mode 100644 index 0000000000..5cdf462001 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c @@ -0,0 +1,562 @@ +/*! + \file gd32e230_dma.c + \brief DMA driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_dma.h" + +/*! + \brief deinitialize DMA a channel registers + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_deinit(dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); +} + +/*! + \brief initialize the parameters of DMA struct with the default values + \param[in] init_struct: the initialization data needed to initialize DMA channel + \param[out] none + \retval none +*/ +void dma_struct_para_init(dma_parameter_struct* init_struct) +{ + /* set the DMA struct with the default values */ + init_struct->periph_addr = 0U; + init_struct->periph_width = 0U; + init_struct->periph_inc = (uint8_t)DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory_addr = 0U; + init_struct->memory_width = 0U; + init_struct->memory_inc = (uint8_t)DMA_MEMORY_INCREASE_DISABLE; + init_struct->number = 0U; + init_struct->direction = (uint8_t)DMA_PERIPHERAL_TO_MEMORY; + init_struct->priority = (uint32_t)DMA_PRIORITY_LOW; +} + +/*! + \brief initialize DMA channel + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] init_struct: the data needed to initialize DMA channel + periph_addr: peripheral base address + periph_width: DMA_PERIPHERAL_WIDTH_8BIT,DMA_PERIPHERAL_WIDTH_16BIT,DMA_PERIPHERAL_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE + memory_addr: memory base address + memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + direction: DMA_PERIPHERAL_TO_MEMORY,DMA_MEMORY_TO_PERIPHERAL + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + \param[out] none + \retval none +*/ +void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct) +{ + uint32_t ctl; + + dma_channel_disable(channelx); + + /* configure peripheral base address */ + DMA_CHPADDR(channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(channelx) = init_struct->memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK); + + /* configure peripheral transfer width,memory transfer width,channel priotity */ + ctl = DMA_CHCTL(channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO); + ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority); + DMA_CHCTL(channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + }else{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(channelx) = address; +} + +/*! + \brief set DMA memory base address + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(channelx) = (number & DMA_CHANNEL_CNT_MASK); +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] priority: priority level of this channel + only one parameter can be selected which is shown as below: + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] mwidth: transfer data width of memory + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(dma_channel_enum channelx, uint32_t mwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= mwidth; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] pwidth: transfer data width of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config(dma_channel_enum channelx, uint32_t pwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= pwidth; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] direction: specify the direction of data transfer + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag is set or not + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){ + reval = SET; + }else{ + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(flag){ + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_ERRIE; + break; + default: + break; + } + + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel interrupt flag + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_G: global interrupt flag of channel + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag,channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) &= ~source; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c new file mode 100644 index 0000000000..894a38c62f --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c @@ -0,0 +1,254 @@ +/*! + \file gd32e230_exti.c + \brief EXTI driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_exti.h" + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN = (uint32_t)0x0F940000U; + EXTI_EVEN = (uint32_t)0x00000000U; + EXTI_RTEN = (uint32_t)0x00000000U; + EXTI_FTEN = (uint32_t)0x00000000U; + EXTI_SWIEV = (uint32_t)0x00000000U; +} + +/*! + \brief initialize the EXTI + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[in] mode: interrupt or event mode, refer to exti_mode_enum + only one parameter can be selected which is shown as below: + \arg EXTI_INTERRUPT: interrupt mode + \arg EXTI_EVENT: event mode + \param[in] trig_type: interrupt trigger type, refer to exti_trig_type_enum + only one parameter can be selected which is shown as below: + \arg EXTI_TRIG_RISING: rising edge trigger + \arg EXTI_TRIG_FALLING: falling trigger + \arg EXTI_TRIG_BOTH: rising and falling trigger + \param[out] none + \retval none +*/ +void exti_init(exti_line_enum linex, \ + exti_mode_enum mode, \ + exti_trig_type_enum trig_type) +{ + /* reset the EXTI line x */ + EXTI_INTEN &= ~(uint32_t)linex; + EXTI_EVEN &= ~(uint32_t)linex; + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ + switch(mode){ + case EXTI_INTERRUPT: + EXTI_INTEN |= (uint32_t)linex; + break; + case EXTI_EVENT: + EXTI_EVEN |= (uint32_t)linex; + break; + default: + break; + } + + /* set the EXTI trigger type */ + switch(trig_type){ + case EXTI_TRIG_RISING: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + break; + case EXTI_TRIG_FALLING: + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + case EXTI_TRIG_BOTH: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + default: + break; + } +} + +/*! + \brief enable the interrupts from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN |= (uint32_t)linex; +} + +/*! + \brief enable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t)linex; +} + +/*! + \brief disable the interrupt from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t)linex; +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief enable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV |= (uint32_t)linex; +} + +/*! + \brief disable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c new file mode 100644 index 0000000000..1489157807 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c @@ -0,0 +1,814 @@ +/*! + \file gd32e230_fmc.c + \brief FMC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_fmc.h" + +/* FMC register bit offset */ +#define OB_HIGH_WP_OFFSET ((uint32_t)8U) +#define FMC_OBSTAT_USER_OFFSET ((uint32_t)8U) +#define FMC_OBSTAT_DATA_OFFSET ((uint32_t)16U) + +/*! + \brief unlock the main FMC operation + it is better to used in pairs with fmc_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))){ + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + it is better to used in pairs with fmc_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief set the wait state counter value + \param[in] wscnt: wait state counter value + \arg WS_WSCNT_0: 0 wait state added + \arg WS_WSCNT_1: 1 wait state added + \arg WS_WSCNT_2: 2 wait state added + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint8_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WS_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief pre-fetch enable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_enable(void) +{ + FMC_WS |= FMC_WS_PFEN; +} + +/*! + \brief pre-fetch disable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_disable(void) +{ + FMC_WS &= ~FMC_WS_PFEN; +} + +/*! + \brief erase page + \param[in] page_address: target page start address + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start page erase */ + FMC_CTL |= FMC_CTL_PER; + FMC_ADDR = page_address; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL &= ~FMC_CTL_PER; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start chip erase */ + FMC_CTL |= FMC_CTL_MER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a double word at the corresponding address in main flash, this + function also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming + \param[in] address: address to program + \param[in] data: double word to program + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + data0 = (uint32_t)(data & 0xFFFFFFFFU); + data1 = (uint32_t)((data>>32U) & 0xFFFFFFFFU); + + /* configure program width */ + FMC_WS |= FMC_WS_PGW; + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + REG32(address) = data0; + REG32(address+4U) = data1; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + FMC_WS &= ~(FMC_WS_PGW); + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address in main flash, this function + also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief unlock the option byte operation + it is better to used in pairs with ob_lock + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } + /* wait until OBWEN bit is set by hardware */ + while(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + } +} + +/*! + \brief lock the option byte operation + it is better to used in pairs with ob_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_lock(void) +{ + /* reset the OBWE bit */ + FMC_CTL &= ~FMC_CTL_OBWEN; +} + +/*! + \brief reload the option byte and generate a system reset + \param[in] none + \param[out] none + \retval none +*/ +void ob_reset(void) +{ + /* set the OBRLD bit */ + FMC_CTL |= FMC_CTL_OBRLD; +} + +/*! + \brief get option byte value + \param[in] addr: address of option byte + \arg OB_SPC_USER_ADDRESS: address of option byte security protection and user + \arg OB_DATA_ADDRESS: address of option byte data + \arg OB_WP_ADDRESS: address of option byte write protection + \param[out] option byte value +*/ +uint32_t option_byte_value_get(uint32_t addr) +{ + return *(volatile uint32_t *)(addr); +} + +/*! + \brief erase the option byte + programmer must ensure FMC & option byte are both unlocked before calling this function + \param[in] none + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_erase(void) +{ + uint16_t fmc_spc; + uint32_t val; + uint32_t fmc_plevel = ob_obstat_plevel_get(); + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* get the original option byte security protection code */ + if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){ + fmc_spc = FMC_NSPC; + }else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){ + fmc_spc = FMC_LSPC; + }else{ + fmc_spc = FMC_HSPC; + fmc_state = FMC_OB_HSPC; + } + val = HIGH_16BITS_MASK | (uint32_t)fmc_spc; + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + /* restore the last get option byte security protection code */ + OB_SPC_USER = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable option byte write protection (OB_WP) + \param[in] ob_wp: write protection configuration data. Notice that set the + bit to 1 if you want to protect the corresponding pages. + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_write_protection_enable(uint16_t ob_wp) +{ + uint32_t ob_wrp_val = 0U; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + ob_wp = (uint16_t)(~ob_wp); + ob_wrp_val |= (uint32_t)ob_wp&0x00FFU; + ob_wrp_val |= (((uint32_t)ob_wp&0xFF00U)>>8U) << 16U; + + if(FMC_READY == fmc_state){ + /* set the OBPG bit*/ + FMC_CTL |= FMC_CTL_OBPG; + + if(0xFFFFFFFFU != ob_wrp_val){ + OB_WP = ob_wrp_val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection code + \arg FMC_NSPC: no security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc) +{ + uint32_t val; + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + val = option_byte_value_get(OB_SPC_USER_ADDRESS); + /* the OB_SPC byte cannot be reprogrammed if protection level is high */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){ + fmc_state = FMC_OB_HSPC; + } + + val &= ~LOW_16BITS_MASK; + val |= (uint32_t)ob_spc; + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC_USER = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option byte + this function can only clear the corresponding bits to be 0 rather than 1. + the function ob_erase is used to set all the bits to be 1. + \param[in] ob_user: user option byte + one or more parameters (bitwise AND) can be selected which are shown as below: + \arg OB_FWDGT_HW: hardware free watchdog timer + \arg OB_DEEPSLEEP_RST: no reset when entering deepsleep mode + \arg OB_STDBY_RST: no reset when entering standby mode + \arg OB_BOOT1_SET_1: BOOT1 bit is 1 + \arg OB_VDDA_DISABLE: disable VDDA monitor + \arg OB_SRAM_PARITY_ENABLE: enable sram parity check + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_user_write(uint8_t ob_user) +{ + uint32_t val_spc_user; + /* check whether FMC is ready or not */ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + val_spc_user = option_byte_value_get(OB_SPC_USER_ADDRESS); + + val_spc_user &= ~HIGH_16BITS_MASK; + + val_spc_user |= ((uint32_t)ob_user<<16U); + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC_USER = val_spc_user; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC data option byte + \param[in] data: the data to be programmed, OB_DATA[0:15] + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_data_program(uint16_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + uint32_t val = 0U; + + val |= (uint32_t)data&0x00FFU; + val |= (((uint32_t)data&0xFF00U)>>8U) << 16U; + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + OB_DATA = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get OB_USER in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_user +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)(FMC_OBSTAT >> FMC_OBSTAT_USER_OFFSET); +} + +/*! + \brief get OB_DATA in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_data +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)(FMC_OBSTAT >> FMC_OBSTAT_DATA_OFFSET); +} + +/*! + \brief get the FMC option byte write protection (OB_WP) in register FMC_WP + \param[in] none + \param[out] none + \retval OB_WP +*/ +uint16_t ob_write_protection_get(void) +{ + return (uint16_t)(FMC_WP); +} + +/*! + \brief get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the value of PLEVEL +*/ +uint32_t ob_obstat_plevel_get(void) +{ + return (FMC_OBSTAT & (FMC_OBSTAT_PLEVEL_BIT0 | FMC_OBSTAT_PLEVEL_BIT1)); +} + +/* FMC interrupts and flags management functions */ +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_CTL |= interrupt; +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_CTL &= ~(uint32_t)interrupt; +} + +/*! + \brief get flag set or reset + \param[in] flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC busy flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + if(FMC_STAT & flag){ + status = SET; + } + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear the FMC pending flag by writing 1 + \param[in] flag: clear FMC flag + one or more parameters can be selected which is shown as below: + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t flag) +{ + /* clear the flags */ + FMC_STAT = flag; +} + +/*! + \brief get intrrupt flag set or reset + \param[in] flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC programming error flag + \arg FMC_INT_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_INT_FLAG_WPERR: FMC write protection error flag + \arg FMC_INT_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + + if(FMC_INT_FLAG_END == int_flag){ + /* get the interrupt enable bit status */ + intenable = FMC_CTL & FMC_INTEN_END; + /* get the corresponding flag bit status */ + flagstatus = FMC_STAT & int_flag; + if(intenable && flagstatus){ + return SET; + }else{ + return RESET; + } + }else{ + /* get the interrupt enable bit status */ + intenable = FMC_CTL & FMC_INTEN_ERR; + /* get the corresponding flag bit status */ + flagstatus = FMC_STAT & int_flag; + if(intenable && flagstatus){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the FMC interrupt pending flag by writing 1 + \param[in] flag: clear FMC flag + one or more parameters can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC programming error flag + \arg FMC_INT_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_INT_FLAG_WPERR: FMC write protection error flag + \arg FMC_INT_FLAG_END: FMC end of programming flag + \param[out] none + \retval none +*/ +void fmc_interrupt_flag_clear(uint32_t int_flag) +{ + /* clear the flags */ + FMC_STAT = int_flag; +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){ + fmc_state = FMC_BUSY; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){ + fmc_state = FMC_WPERR; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){ + fmc_state = FMC_PGERR; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + }while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c new file mode 100644 index 0000000000..d3daa1fc32 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c @@ -0,0 +1,252 @@ +/*! + \file gd32e230_fwdgt.c + \brief FWDGT driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_CTL_CMD bit field */ +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_RLD_RLD bit field */ +/* write value to FWDGT_WND_WND bit field */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */ + +/*! + \brief enable write access to FWDGT_PSC and FWDGT_RLD + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_enable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; +} + +/*! + \brief disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the free watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the free watchdog timer counter prescaler value + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \brief reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if(RESET != (FWDGT_STAT & flag)){ + return SET; + } + return RESET; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c new file mode 100644 index 0000000000..7223c98b85 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c @@ -0,0 +1,399 @@ +/*! + \file gd32e230_gpio.c + \brief GPIO driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] mode: gpio pin mode + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with pull-down resistor + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] otype: gpio pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: gpio pin output max speed + \arg GPIO_OSPEED_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_10MHZ: output max speed 10MHz + \arg GPIO_OSPEED_50MHZ: output max speed 50MHz + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin) +{ + uint16_t i; + uint32_t ospeed; + + if(GPIO_OTYPE_OD == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeed = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeed &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeed |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeed; +} + +/*! + \brief set GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BOP(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief reset GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BC(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief write data to the specified GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value) +{ + if(RESET != bit_value){ + GPIO_BOP(gpio_periph) = (uint32_t)pin; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] data: specify the value to be written to the port output control register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph, uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins input status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_input_port_get(uint32_t gpio_periph) +{ + return (uint16_t)GPIO_ISTAT(gpio_periph); +} + +/*! + \brief get GPIO pin output status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins output status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_output_port_get(uint32_t gpio_periph) +{ + return (uint16_t)GPIO_OCTL(gpio_periph); +} + +/*! + \brief set GPIO alternate function + \param[in] gpio_periph: GPIOx(x = A,B,C) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C) + \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet + \arg GPIO_AF_0: TIMER13, TIMER14, TIMER16, SPI0, SPI1, I2S0, CK_OUT, USART0, + I2C0, I2C1, SWDIO, SWCLK + \arg GPIO_AF_1: USART0, USART1, TIMER2, TIMER14, I2C0, I2C1 + \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, I2S0 + \arg GPIO_AF_3: I2C0, TIMER14 + \arg GPIO_AF_4(port A,B only): USART1, I2C0, I2C1, TIMER13 + \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, I2S0 + \arg GPIO_AF_6(port A,B only): SPI1 + \arg GPIO_AF_7(port A,B only): CMP + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFSEL0(gpio_periph); + afrh = GPIO_AFSEL1(gpio_periph); + + for(i = 0U;i < 8U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for(i = 8U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin) +{ + uint32_t lock = 0x00010000U; + lock |= pin; + + /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */ + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + GPIO_LOCK(gpio_periph) = (uint32_t)pin; + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + lock = GPIO_LOCK(gpio_periph); + lock = GPIO_LOCK(gpio_periph); +} + +/*! + \brief toggle GPIO pin status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_TG(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief toggle GPIO port status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c new file mode 100644 index 0000000000..89fb7f52e9 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c @@ -0,0 +1,797 @@ +/*! + \file gd32e230_i2c.c + \brief I2C driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_i2c.h" + +/* I2C register bit mask */ +#define I2CCLK_MAX ((uint32_t)0x0000007FU) /*!< i2cclk maximum value */ +#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */ +#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */ +#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ +#define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */ + +/* I2C register bit offset */ +#define STAT1_PECV_OFFSET ((uint32_t)8U) /* bit offset of PECV in I2C_STAT1 */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph){ + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + default: + break; + } +} + +/*! + \brief configure I2C clock + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) + and fast mode plus (up to 1MHz) + \param[in] dutycyc: duty cycle in fast mode or fast mode plus + only one parameter can be selected which is shown as below: + \arg I2C_DTCY_2: T_low/T_high=2 + \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \param[out] none + \retval none +*/ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) +{ + uint32_t pclk1, clkc, freq, risetime; + uint32_t temp; + + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C peripheral clock frequency */ + freq = (uint32_t)(pclk1/1000000U); + if(freq >= I2CCLK_MAX){ + freq = I2CCLK_MAX; + } + temp = I2C_CTL1(i2c_periph); + temp &= ~I2C_CTL1_I2CCLK; + temp |= freq; + + I2C_CTL1(i2c_periph) = temp; + + if(100000U >= clkspeed){ + /* the maximum SCL rise time is 1000ns in standard mode */ + risetime = (uint32_t)((pclk1/1000000U)+1U); + if(risetime >= I2CCLK_MAX){ + I2C_RT(i2c_periph) = I2CCLK_MAX; + }else if(risetime <= I2CCLK_MIN){ + I2C_RT(i2c_periph) = I2CCLK_MIN; + }else{ + I2C_RT(i2c_periph) = risetime; + } + clkc = (uint32_t)(pclk1/(clkspeed*2U)); + if(clkc < 0x04U){ + /* the CLKC in standard mode minmum value is 4 */ + clkc = 0x04U; + } + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); + + }else if(400000U >= clkspeed){ + /* the maximum SCL rise time is 300ns in fast mode */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if(0U == (clkc & I2C_CKCFG_CLKC)){ + /* the CLKC in fast mode minmum value is 1 */ + clkc |= 0x0001U; + } + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + }else{ + /* fast mode plus, the maximum SCL rise time is 120ns */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)120U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + /* enable fast mode */ + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + /* enable I2C fast mode plus */ + I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN; + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] mode: + only one parameter can be selected which is shown as below: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + only one parameter can be selected which is shown as below: + \arg I2C_ADDFORMAT_7BITS: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \param[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + addr = addr & I2C_ADDRESS_MASK; + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief SMBus type selection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] type: + only one parameter can be selected which is shown as below: + \arg I2C_SMBUS_DEVICE: device + \arg I2C_SMBUS_HOST: host + \param[out] none + \retval none +*/ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if(I2C_SMBUS_HOST == type){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] ack: + only one parameter can be selected which is shown as below: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + if(I2C_ACK_ENABLE == ack){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \brief configure I2C POAP position + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pos: + only one parameter can be selected which is shown as below: + \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if(I2C_ACKPOS_NEXT == pos){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \brief master sends slave address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + only one parameter can be selected which is shown as below: + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) +{ + /* master is a transmitter or a receiver */ + if(I2C_TRANSMITTER == trandirection){ + addr = addr & I2C_TRANSMITTER; + }else{ + addr = addr | I2C_RECEIVER; + } + /* send slave address */ + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief enable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: the second address in dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) +{ + /* configure address */ + addr = addr & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr); +} + +/*! + \brief disable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_dualaddr_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN); +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval data of received +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief enable I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmastate: + only one parameter can be selected which is shown as below: + \arg I2C_DMA_ON: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief configure whether next DMA EOT is DMA last transfer or not + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmalast: + only one parameter can be selected which is shown as below: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none +*/ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] stretchpara: + only one parameter can be selected which is shown as below: + \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SS); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] gcallpara: + only one parameter can be selected which is shown as below: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief software reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] sreset: + only one parameter can be selected which is shown as below: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none +*/ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C PEC calculation on or off + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PECTRANS_ENABLE: transfer PEC + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none +*/ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV)>>STAT1_PECV_OFFSET); +} + +/*! + \brief I2C issue alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none +*/ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_ARP_ENABLE: enable ARP + \arg I2C_ARP_DISABLE: disable ARP + \param[out] none + \retval none +*/ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief check I2C flag is set or not + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SBSEND: start condition send out + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_BTC: byte transmission finishes + \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_FLAG_STPDET: stop condition detected in slave mode + \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_RXGC: general call address (00h) received + \arg I2C_FLAG_DEFSMB: default address of SMBus device + \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode + \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear I2C flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SMBALT: SMBus Alert status + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error + \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(I2C_FLAG_ADDSEND == flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag)); + } +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief check I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BTC: byte transmission finishes + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag + \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U, bufie; + + /* check BUFIE */ + bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; + + /* get the interrupt enable bit status */ + intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + + if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){ + if(intenable && bufie){ + intenable = 1U; + }else{ + intenable = 0U; + } + } + if((0U != flagstatus) && (0U != intenable)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] intflag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + if(I2C_INT_FLAG_ADDSEND == int_flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag)); + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c new file mode 100644 index 0000000000..eac0dc0958 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c @@ -0,0 +1,142 @@ +/*! + \file gd32e230_misc.c + \brief MISC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_misc.h" + +/*! + \brief enable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_priority: the priority needed to set (0-3) + \param[out] none + \retval none +*/ +void nvic_irq_enable(uint8_t nvic_irq, + uint8_t nvic_irq_priority) +{ + /* set the priority and enable the selected IRQ */ + NVIC_SetPriority((IRQn_Type)nvic_irq, (uint32_t)nvic_irq_priority); + NVIC_EnableIRQ((IRQn_Type)nvic_irq); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC_DisableIRQ((IRQn_Type)nvic_irq); +} + +/* */ +/*! + \brief initiates a system reset request to reset the MCU + \param[in] none + \param[out] none + \retval none +*/ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \arg NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c new file mode 100644 index 0000000000..53e8a2e521 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c @@ -0,0 +1,301 @@ +/*! + \file gd32e230_pmu.c + \brief PMU driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_pmu.h" + +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] lvdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_LVDT_0: voltage threshold is 2.1V + \arg PMU_LVDT_1: voltage threshold is 2.3V + \arg PMU_LVDT_2: voltage threshold is 2.4V + \arg PMU_LVDT_3: voltage threshold is 2.6V + \arg PMU_LVDT_4: voltage threshold is 2.7V + \arg PMU_LVDT_5: voltage threshold is 2.9V + \arg PMU_LVDT_6: voltage threshold is 3.0V + \arg PMU_LVDT_7: voltage threshold is 3.1V + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t lvdt_n) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; + /* clear LVDT bits */ + PMU_CTL &= ~PMU_CTL_LVDT; + /* set LVDT bits according to lvdt_n */ + PMU_CTL |= lvdt_n; + /* enable LVD */ + PMU_CTL |= PMU_CTL_LVDEN; +} + +/*! + \brief select LDO output voltage + these bits set by software when the main PLL closed + \param[in] ldo_output: + only one parameter can be selected which is shown as below: + \arg PMU_LDOVS_LOW: LDO output voltage low mode + \arg PMU_LDOVS_HIGH: LDO output voltage high mode + \param[out] none + \retval none +*/ +void pmu_ldo_output_select(uint32_t ldo_output) +{ + PMU_CTL &= ~PMU_CTL_LDOVS; + PMU_CTL |= ldo_output; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief PMU work at deepsleep mode + \param[in] ldo: + only one parameter can be selected which is shown as below: + \arg PMU_LDO_NORMAL: LDO operates normally when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode + \param[in] deepsleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[ 3 ]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + reg_snap[ 0 ] = REG32( 0xE000E010U ); + reg_snap[ 1 ] = REG32( 0xE000E100U ); + reg_snap[ 2 ] = REG32( 0xE000E104U ); + + REG32( 0xE000E010U ) &= 0x00010004U; + REG32( 0xE000E180U ) = 0XF7FFEF19U; + REG32( 0xE000E184U ) = 0XFFFFFFFFU; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + __SEV(); + __WFE(); + __WFE(); + } + + REG32( 0xE000E010U ) = reg_snap[ 0 ] ; + REG32( 0xE000E100U ) = reg_snap[ 1 ] ; + REG32( 0xE000E104U ) = reg_snap[ 2 ] ; + + /* reset sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work at standby mode + \param[in] standbymodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief enable wakeup pin + \param[in] wakeup_pin: + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief disable wakeup pin + \param[in] wakeup_pin: + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin) +{ + PMU_CS &= ~(wakeup_pin); +} + +/*! + \brief enable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief clear flag bit + \param[in] flag_clear: + one or more parameters can be selected which are shown as below: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag_clear) +{ + if(RESET != (flag_clear & PMU_FLAG_RESET_WAKEUP)){ + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + } + if(RESET != (flag_clear & PMU_FLAG_RESET_STANDBY)){ + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + } +} + +/*! + \brief get flag state + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + FlagStatus ret_status = RESET; + + if(PMU_CS & flag){ + ret_status = SET; + } + + return ret_status; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c new file mode 100644 index 0000000000..9483fa68f9 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c @@ -0,0 +1,1034 @@ +/*! + \file gd32e230_rcu.c + \brief RCU driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_rcu.h" + +/* define clock source */ +#define SEL_IRC8M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLL 0x02U + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000FFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x03FFFFFFU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV); + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~(RCU_CFG1_PREDV); + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL); + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCPSC2; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_INT = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_DBGMCU: DBGMCU clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_enable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_DBGMCU: DBGMCU clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} +/*! + \brief reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_PMURST: reset PMU + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_PMURST: reset PMU + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLL: select CK_PLL as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t cksys_source = 0U; + cksys_source = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + cksys_source &= ~RCU_CFG0_SCS; + RCU_CFG0 = (ck_sys | cksys_source); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_SCSS_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_SCSS_PLL: select CK_PLL as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t ahbpsc = 0U; + ahbpsc = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + ahbpsc &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (ck_ahb | ahbpsc); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t apb1psc = 0U; + apb1psc = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + apb1psc &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (ck_apb1 | apb1psc); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t apb2psc = 0U; + apb2psc = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + apb2psc &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (ck_apb2 | apb2psc); +} + +/*! + \brief configure the ADC clock prescaler selection + \param[in] ck_adc: ADC clock prescaler selection, refer to rcu_adc_clock_enum + only one parameter can be selected which is shown as below: + \arg RCU_ADCCK_IRC28M_DIV2: select CK_IRC28M/2 as CK_ADC + \arg RCU_ADCCK_IRC28M: select CK_IRC28M as CK_ADC + \arg RCU_ADCCK_APB2_DIV2: select CK_APB2/2 as CK_ADC + \arg RCU_ADCCK_AHB_DIV3: select CK_AHB/3 as CK_ADC + \arg RCU_ADCCK_APB2_DIV4: select CK_APB2/4 as CK_ADC + \arg RCU_ADCCK_AHB_DIV5: select CK_AHB/5 as CK_ADC + \arg RCU_ADCCK_APB2_DIV6: select CK_APB2/6 as CK_ADC + \arg RCU_ADCCK_AHB_DIV7: select CK_AHB/7 as CK_ADC + \arg RCU_ADCCK_APB2_DIV8: select CK_APB2/8 as CK_ADC + \arg RCU_ADCCK_AHB_DIV9: select CK_AHB/9 as CK_ADC + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc) +{ + /* reset the ADCPSC, ADCSEL, IRC28MDIV bits */ + RCU_CFG0 &= ~RCU_CFG0_ADCPSC; + RCU_CFG2 &= ~(RCU_CFG2_ADCSEL | RCU_CFG2_IRC28MDIV | RCU_CFG2_ADCPSC2); + + /* set the ADC clock according to ck_adc */ + switch(ck_adc){ + case RCU_ADCCK_IRC28M_DIV2: + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_IRC28M: + RCU_CFG2 |= RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV2: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV3: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV4: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV5: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV6: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV7: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV8: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV9: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + default: + break; + } +} + +/*! + \brief configure the CK_OUT clock source and divider + \param[in] ckout_src: CK_OUT clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUTSRC_NONE: no clock selected + \arg RCU_CKOUTSRC_IRC28M: IRC28M selected + \arg RCU_CKOUTSRC_IRC40K: IRC40K selected + \arg RCU_CKOUTSRC_LXTAL: LXTAL selected + \arg RCU_CKOUTSRC_CKSYS: CKSYS selected + \arg RCU_CKOUTSRC_IRC8M: IRC8M selected + \arg RCU_CKOUTSRC_HXTAL: HXTAL selected + \arg RCU_CKOUTSRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUTSRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout_div: CK_OUT divider + \arg RCU_CKOUT_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div) +{ + uint32_t ckout = 0U; + ckout = RCU_CFG0; + /* reset the CKOUTSEL, CKOUTDIV and PLLDV bits and set according to ckout_src and ckout_div */ + ckout &= ~(RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 = (ckout | ckout_src | ckout_div); +} + +/*! + \brief configure the PLL clock source selection and PLL multiply factor + \param[in] pll_src: PLL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLLSRC_IRC8M_DIV2: select CK_IRC8M/2 as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[in] pll_mul: PLL multiply factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL_MULx(x=2..32): PLL source clock * x + \param[out] none + \retval none +*/ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul) +{ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (pll_src | pll_mul); +} + +/*! + \brief configure the USART clock source selection + \param[in] ck_usart: USART clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USART0SRC_CKAPB2: CK_USART0 select CK_APB2 + \arg RCU_USART0SRC_CKSYS: CK_USART0 select CK_SYS + \arg RCU_USART0SRC_LXTAL: CK_USART0 select CK_LXTAL + \arg RCU_USART0SRC_IRC8M: CK_USART0 select CK_IRC8M + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(uint32_t ck_usart) +{ + /* reset the USART0SEL bits and set according to ck_usart */ + RCU_CFG2 &= ~RCU_CFG2_USART0SEL; + RCU_CFG2 |= ck_usart; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC40K: CK_IRC40K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV32: CK_HXTAL/32 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + /* reset the RTCSRC bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= rtc_clock_source; +} + +/*! + \brief configure the HXTAL divider used as input of PLL + \param[in] hxtal_prediv: HXTAL divider used as input of PLL + only one parameter can be selected which is shown as below: + \arg RCU_PLL_PREDVx(x=1..16): HXTAL divided x used as input of PLL + \param[out] none + \retval none +*/ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv) +{ + uint32_t prediv = 0U; + prediv = RCU_CFG1; + /* reset the PREDV bits and set according to hxtal_prediv */ + prediv &= ~RCU_CFG1_PREDV; + RCU_CFG1 = (prediv | hxtal_prediv); +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTAL_LOWDRI: lower driving capability + \arg RCU_LXTAL_MED_LOWDRI: medium low driving capability + \arg RCU_LXTAL_MED_HIGHDRI: medium high driving capability + \arg RCU_LXTAL_HIGHDRI: higher driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + RCU_BDCTL &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL |= lxtal_dricap; +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_IRC28MSTB: IRC28M stabilization flag + \arg RCU_FLAG_V12RST: V12 domain power reset flag + \arg RCU_FLAG_OBLRST: option byte loader reset flag + \arg RCU_FLAG_EPRST: external pin reset flag + \arg RCU_FLAG_PORRST: power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB: IRC40K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC28MSTB: IRC28M stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC28MSTB_CLR: IRC28M stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int)); +} + + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief wait until oscillator stabilization flags is SET + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + switch(osci){ + case RCU_HXTAL: + /* wait until HXTAL is stabilization and osci_stat is not more than timeout */ + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC8M stable */ + case RCU_IRC8M: + while((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC28M stable */ + case RCU_IRC28M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC28MSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC28MSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC40K stable */ + case RCU_IRC40K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)){ + reval = SUCCESS; + } + break; + + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){ + reval = SUCCESS; + } + break; + + default: + break; + } + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: + case RCU_IRC28M: + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS)); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & (~RCU_BDCTL_LXTALBPS)); + break; + case RCU_IRC8M: + case RCU_IRC28M: + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL0 |= RCU_CTL0_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL0 &= ~RCU_CTL0_CKMEN; +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL0; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + adjust &= ~RCU_CTL0_IRC8MADJ; + RCU_CTL0 = (adjust | (((uint32_t)irc8m_adjval)<<3)); +} + +/*! + \brief set the IRC28M adjust value + \param[in] irc28m_adjval: IRC28M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC28MADJ bits and set according to irc28m_adjval */ + adjust &= ~RCU_CTL1_IRC28MADJ; + RCU_CTL1 = (adjust | (((uint32_t)irc28m_adjval)<<3)); +} + +/*! + \brief unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + /* reset the KEY bits and set 0x1A2B3C4D */ + RCU_VKEY &= ~RCU_VKEY_KEY; + RCU_VKEY |= RCU_VKEY_UNLOCK; +} + +/*! + \brief set voltage in deep sleep mode + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \arg RCU_DEEPSLEEP_V_0_8: the core voltage is 0.8V + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + /* reset the DSLPVS bits and set according to dsvol */ + RCU_DSV &= ~RCU_DSV_DSLPVS; + RCU_DSV |= dsvol; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \arg CK_ADC: ADC clock frequency + \arg CK_USART: USART0 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2, ADC or USRAT0 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws = 0U, adcps = 0U, adcps2 = 0U, ck_freq = 0U; + uint32_t cksys_freq = 0U, ahb_freq = 0U, apb1_freq = 0U, apb2_freq = 0U; + uint32_t adc_freq = 0U, usart_freq = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else if(15U == pllmf){ + pllmf = 16U; + }else{ + pllmf += 2U; + } + + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + cksys_freq = (HXTAL_VALUE / prediv) * pllmf; + }else{ + cksys_freq = (IRC8M_VALUE >> 1) * pllmf; + } + break; + /* IRC8M is selected as CK_SYS */ + default: + cksys_freq = IRC8M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 8, 10); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 11, 13); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + + /* return the clocks frequency */ + switch(clock){ + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + case CK_ADC: + /* calculate ADC clock frequency */ + if(RCU_ADCSRC_AHB_APB2DIV != (RCU_CFG2 & RCU_CFG2_ADCSEL)){ + if(RCU_ADC_IRC28M_DIV1 != (RCU_CFG2 & RCU_CFG2_IRC28MDIV)){ + adc_freq = IRC28M_VALUE >> 1; + }else{ + adc_freq = IRC28M_VALUE; + } + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 or CK_AHB divided by 3/5/7/9 */ + adcps = GET_BITS(RCU_CFG0, 14, 15); + adcps2 = GET_BITS(RCU_CFG2, 31, 31); + if(0U != adcps2){ + /* ADC clock select CK_AHB divided by 3/5/7/9 */ + adc_freq = ahb_freq / (adcps + 1U); + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 */ + adc_freq = apb2_freq / adcps; + } + } + ck_freq = adc_freq; + break; + case CK_USART: + /* calculate USART0 clock frequency */ + if(RCU_USART0SRC_CKAPB2 == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = apb2_freq; + }else if(RCU_USART0SRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = cksys_freq; + }else if(RCU_USART0SRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = LXTAL_VALUE; + }else if(RCU_USART0SRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = IRC8M_VALUE; + }else{ + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c new file mode 100644 index 0000000000..546afa781e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c @@ -0,0 +1,965 @@ +/*! + \file gd32e230_rtc.c + \brief RTC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_rtc.h" + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0x00U, reg_date = 0x00U; + + reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \ + DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \ + DATE_MON(rtc_initpara_struct->rtc_month) | \ + DATE_DAY(rtc_initpara_struct->rtc_date)); + + reg_time = (rtc_initpara_struct->rtc_am_pm| \ + TIME_HR(rtc_initpara_struct->rtc_hour) | \ + TIME_MN(rtc_initpara_struct->rtc_minute) | \ + TIME_SC(rtc_initpara_struct->rtc_second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->rtc_display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +{ + uint32_t temp_tr = 0x00U, temp_dr = 0x00U, temp_pscr = 0x00U, temp_ctlr = 0x00U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0x00U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void) (RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0x00U; + + reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \ + rtc_alarm_time->rtc_weekday_or_date | \ + rtc_alarm_time->rtc_am_pm | \ + ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \ + ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \ + ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \ + ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0TD = (uint32_t)reg_alrm0td; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] mask_subsecond: alarm subsecond mask + only one parameter can be selected which is shown as below: + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0SS = mask_subsecond | subsecond; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_alarm_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_ALRM0EN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(void) +{ + volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief get RTC alarm + \param[in] none + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0x00U; + + /* get the value of RTC_ALRM0TD register */ + reg_alrm0td = RTC_ALRM0TD; + + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK; + rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM); + rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS); + rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td); + rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td); + rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td); + rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td); +} + +/*! + \brief get RTC alarm subsecond + \param[in] none + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(void) +{ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + only one parameter can be selected which is shown as below: + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0x00U; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_timestamp_date: 0x1 - 0x31(BCD format) + rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_timestamp_minute: 0x0 - 0x59(BCD format) + rtc_timestamp_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +{ + uint32_t temp_tts = 0x00U, temp_dts = 0x00U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1 + rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + rtc_tamper_precharge_enable: DISABLE, ENABLE + rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + rtc_tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){ + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + }else{ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter); + } + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + + if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){ + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){ + RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS); + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_RECALIBRATION: recalibration pending flag + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_INIT: init mode event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \arg RTC_FLAG_YCM: year parameter configured event flag + \arg RTC_FLAG_SHIFT: shift operation pending flag + \arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + FlagStatus flag_state = RESET; + + if((uint32_t)RESET != (RTC_STAT & flag)){ + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag + \param[in] flag: specify which flag to clear + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + RTC_STAT &= (uint32_t)(~flag); +} + +/*! + \brief configure rtc alternate output source + \param[in] source: specify signal to output + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high + \arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low + \param[in] mode: specify the output pin (PC13) mode when output alarm signal + only one parameter can be selected which is shown as below: + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alter_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + + /* alarm output */ + if((uint32_t)RESET != (source & RTC_OS_ENABLE)){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL); + RTC_TAMP |= (uint32_t)(mode); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure RTC calibration register + \param[in] window: select calibration window + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief adjust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour ajustment operation + only one parameter can be selected which is shown as below: + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief adjust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + only one parameter can be selected which is shown as below: + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status)); + + temp = RTC_CTL & RTC_CTL_REFEN; + /* check if the function of reference clock detection is disabled */ + if(((uint32_t)RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c new file mode 100644 index 0000000000..a48f5c426a --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c @@ -0,0 +1,1003 @@ +/*! + \file gd32e230_spi.c + \brief SPI driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_spi.h" + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI0 parameter initialization mask */ +#define SPI_FIFO_INIT_MASK1 ((uint32_t)0x00003840U) /*!< SPI1 parameter initialization mask1 */ +#define SPI_FIFO_INIT_MASK2 ((uint32_t)0x0000F0FFU) /*!< SPI1 parameter initialization mask2*/ +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */ + +#define SPI_FRAMESIZE_MASK ((uint32_t)0x00000800U) /*!< SPI0 frame size mask */ +#define SPI_BYTEN_MASK ((uint32_t)0x00001000U) /*!< SPI1 access to FIFO mask */ +#define SPI_TXLVL_EMPTY_MASK ((uint32_t)0x00001800U) /*!< SPI1 TXFIFO empty mask */ +#define SPI_RXLVL_EMPTY_MASK ((uint32_t)0x00000600U) /*!< SPI1 RXFIFO empty mask */ + +/* I2S clock source selection, multiplication and division mask */ +#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< I2S clock prescaler register reset value */ + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + default : + break; + } +} + +/*! + \brief initialize the parameters of SPI struct with the default values + \param[in] spi_struct: SPI parameter stuct + \param[out] none + \retval none +*/ +void spi_struct_para_init(spi_parameter_struct* spi_struct) +{ + /* set the SPI struct with the default values */ + spi_struct->device_mode = SPI_SLAVE; + spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_struct->frame_size = SPI_FRAMESIZE_8BIT; + spi_struct->nss = SPI_NSS_HARD; + spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_struct->prescale = SPI_PSC_2; +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1) + \param[in] spi_struct: SPI parameter initialization stuct members of the structure + and the member values are shown as below: + device_mode: SPI_MASTER, SPI_SLAVE + trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY, + SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT + frame_size: SPI_FRAMESIZE_4BIT, SPI_FRAMESIZE_5BIT + SPI_FRAMESIZE_6BIT, SPI_FRAMESIZE_7BIT + SPI_FRAMESIZE_8BIT, SPI_FRAMESIZE_9BIT + SPI_FRAMESIZE_10BIT, SPI_FRAMESIZE_11BIT + SPI_FRAMESIZE_12BIT, SPI_FRAMESIZE_13BIT + SPI_FRAMESIZE_14BIT, SPI_FRAMESIZE_15BIT + SPI_FRAMESIZE_16BIT + nss: SPI_NSS_SOFT, SPI_NSS_HARD + endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB + clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE + SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE + prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) +{ + uint32_t reg1, reg2, reg3 = 0U; + + reg1 = SPI_CTL0(spi_periph); + reg1 &= SPI_INIT_MASK; + + reg2 = SPI_CTL0(spi_periph); + reg2 &= SPI_FIFO_INIT_MASK1; + + reg3 = SPI_CTL1(spi_periph); + reg3 &= SPI_FIFO_INIT_MASK2; + + if( SPI0 == spi_periph){ + /* select SPI as master or slave */ + reg1 |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg1 |= spi_struct->trans_mode; + /* select SPI NSS use hardware or software */ + reg1 |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg1 |= spi_struct->endian; + /* select SPI polarity and phase */ + reg1 |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg1 |= spi_struct->prescale; + /* select SPI frame size */ + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != spi_struct->frame_size) && (SPI_FRAMESIZE_16BIT != spi_struct->frame_size)) + { + return ERROR; + }else{ + reg1 |= (spi_struct->frame_size & SPI_FRAMESIZE_MASK); + } + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg1; + + }else{ + /* select SPI as master or slave */ + reg2 |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg2 |= spi_struct->trans_mode; + /* select SPI NSS use hardware or software */ + reg2 |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg2 |= spi_struct->endian; + /* select SPI polarity and phase */ + reg2 |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg2 |= spi_struct->prescale; + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg2; + + /* select SPI data size */ + reg3 |= spi_struct->frame_size; + /* write to SPI_CTL0 register */ + SPI_CTL1(spi_periph) = (uint32_t)reg3; + } + + /* select SPI mode */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); + + return SUCCESS; +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(x=0) + \param[in] mode: I2S operation mode + only one parameter can be selected which is shown as below: + \arg I2S_MODE_SLAVETX: I2S slave transmit mode + \arg I2S_MODE_SLAVERX: I2S slave receive mode + \arg I2S_MODE_MASTERTX: I2S master transmit mode + \arg I2S_MODE_MASTERRX: I2S master receive mode + \param[in] standard: I2S standard + only one parameter can be selected which is shown as below: + \arg I2S_STD_PHILLIPS: I2S phillips standard + \arg I2S_STD_MSB: I2S MSB standard + \arg I2S_STD_LSB: I2S LSB standard + \arg I2S_STD_PCMSHORT: I2S PCM short standard + \arg I2S_STD_PCMLONG: I2S PCM long standard + \param[in] ckpl: I2S idle state clock polarity + only one parameter can be selected which is shown as below: + \arg I2S_CKPL_LOW: I2S clock polarity low level + \arg I2S_CKPL_HIGH: I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl) +{ + uint32_t reg = 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)mode; + /* select I2S standard */ + reg |= (uint32_t)standard; + /* select I2S polarity */ + reg |= (uint32_t)ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(x=0) + \param[in] audiosample: I2S audio sample rate + only one parameter can be selected which is shown as below: + \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz + \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz + \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz + \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz + \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz + \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz + \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz + \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz + \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz + \param[in] frameformat: I2S data length and channel length + only one parameter can be selected which is shown as below: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[in] mckout: I2S master clock output + only one parameter can be selected which is shown as below: + \arg I2S_MCKOUT_ENABLE: I2S master clock output enable + \arg I2S_MCKOUT_DISABLE: I2S master clock output disable + \param[out] none + \retval none +*/ +void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET; + + /* get system clock */ + i2sclock = rcu_clock_freq_get(CK_SYS); + + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample); + } + } + + /* remove the floating point */ + clks = (clks + 5U) / 10U; + i2sof = (clks & 0x00000001U); + i2sdiv = ((clks - i2sof) / 2U); + i2sof = (i2sof << 8U); + + /* set the default values */ + if((i2sdiv < 2U) || (i2sdiv > 255U)){ + i2sdiv = 2U; + i2sof = 0U; + } + + /* configure SPI_I2SPSC */ + SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)frameformat; +} + + +/*! + \brief enable I2S + \param[in] spi_periph: SPIx(x=0) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S + \param[in] spi_periph: SPIx(x=0) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief enable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief disable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1) + \param[in] frame_format: SPI frame size + only one parameter can be selected which is shown as below: + \arg SPI_FRAMESIZE_4BIT: SPI frame size is 4 bits + \arg SPI_FRAMESIZE_5BIT: SPI frame size is 5 bits + \arg SPI_FRAMESIZE_6BIT: SPI frame size is 6 bits + \arg SPI_FRAMESIZE_7BIT: SPI frame size is 7 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \arg SPI_FRAMESIZE_9BIT: SPI frame size is 9 bits + \arg SPI_FRAMESIZE_10BIT: SPI frame size is 10 bits + \arg SPI_FRAMESIZE_11BIT: SPI frame size is 11 bits + \arg SPI_FRAMESIZE_12BIT: SPI frame size is 12 bits + \arg SPI_FRAMESIZE_13BIT: SPI frame size is 13 bits + \arg SPI_FRAMESIZE_14BIT: SPI frame size is 14 bits + \arg SPI_FRAMESIZE_15BIT: SPI frame size is 15 bits + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + if(SPI0 == spi_periph) + { + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != frame_format) && (SPI_FRAMESIZE_16BIT != frame_format)) + { + return ERROR; + }else{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= ((uint32_t)frame_format & SPI_FRAMESIZE_MASK); + } + } + else{ + /* clear SPI_CTL1_DZ bits */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DZ); + /* confige SPI_CTL1_DZ bits */ + SPI_CTL1(spi_periph) |= (uint32_t)frame_format; + } + return SUCCESS; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) +{ + uint32_t reg, byten; + if(SPI0 == spi_periph) + { + SPI_DATA(spi_periph) = (uint32_t)data; + } + else + { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(RESET != byten) + { + reg = spi_periph + 0x0CU; + *( uint8_t *)(reg) = (uint8_t)data; + }else + { + SPI_DATA(spi_periph) = (uint16_t)data; + } + } +} + +/*! + \brief SPI receive data + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + uint32_t reg, byten; + if(SPI0 == spi_periph) + { + return ((uint16_t)SPI_DATA(spi_periph)); + } + else + { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(RESET != byten) + { + reg = spi_periph + 0x0CU; + return (uint16_t)(*(uint8_t *)(reg)); + }else + { + return ((uint16_t)SPI_DATA(spi_periph)); + } + } +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1) + \param[in] transfer_direction: SPI transfer direction + only one parameter can be selected which is shown as below: + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \param[out] none + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit-only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive-only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief set SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly) +{ + /* enable SPI CRC */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc) +{ + if(SPI_CRC_TX == crc){ + return ((uint16_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; +} + +/*! + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); +} + +/*! + \brief enable SPI NSS pulse mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP; +} + +/*! + \brief disable SPI NSS pulse mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP); +} + +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ + void qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \brief enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default: + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + break; + default : + break; + } +} + +/*! + \brief get SPI and I2S interrupt flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt flag status + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag + \arg SPI_INT_FLAG_CONFERR: config error interrupt flag + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag + \arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_FLAG_TBE: + reg1 = reg1 & SPI_STAT_TBE; + reg2 = reg2 & SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_FLAG_RBNE: + reg1 = reg1 & SPI_STAT_RBNE; + reg2 = reg2 & SPI_CTL1_RBNEIE; + break; + /* SPI/I2S overrun interrupt */ + case SPI_I2S_INT_FLAG_RXORERR: + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI config error interrupt */ + case SPI_INT_FLAG_CONFERR: + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI CRC error interrupt */ + case SPI_INT_FLAG_CRCERR: + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* I2S underrun error interrupt */ + case I2S_INT_FLAG_TXURERR: + reg1 = reg1 & SPI_STAT_TXURERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI/I2S format error interrupt */ + case SPI_I2S_INT_FLAG_FERR: + reg1 = reg1 & SPI_STAT_FERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if((0U != reg1) && (0U != reg2)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[in] flag: SPI/I2S flag status + one or more parameters can be selected which are shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error interrupt flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + only for SPI1: + \arg SPI_TXLVL_EMPTY: SPI TXFIFO is empty + \arg SPI_TXLVL_QUARTER_FULL: SPI TXFIFO is a quarter of full + \arg SPI_TXLVL_HAlF_FULL: SPI TXFIFO is a half of full + \arg SPI_TXLVL_FULL: SPI TXFIFO is full + \arg SPI_RXLVL_EMPTY: SPI RXFIFO is empty + \arg SPI_RXLVL_QUARTER_FULL: SPI RXFIFO is a quarter of full + \arg SPI_RXLVL_HAlF_FULL: SPI RXFIFO is a half of full + \arg SPI_RXLVL_FULL: SPI RXFIFO is full + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + if(RESET != (SPI_STAT(spi_periph) & flag)){ + return SET; + }else{ + if(SPI1 == spi_periph){ + /* check TXFIFO is empty or not */ + if(SPI_TXLVL_EMPTY == flag){ + if(RESET != (SPI_STAT(spi_periph) & SPI_TXLVL_EMPTY_MASK)){ + return RESET; + }else{ + return SET; + } + } + /* check RXFIFO is empty or not */ + if(SPI_RXLVL_EMPTY == flag){ + if(RESET != (SPI_STAT(spi_periph) & SPI_RXLVL_EMPTY_MASK)){ + return RESET; + }else{ + return SET; + } + } + } + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief configure SPI1 access size to FIFO(8bit or 16bit) + \param[in] spi_periph: SPIx(x=1) + \param[in] fifo_access_size: byte access enable + only one parameter can be selected which is shown as below: + \arg SPI_HALFWORD_ACCESS: half-word access to FIFO + \arg SPI_BYTE_ACCESS: byte access to FIFO + \param[out] none + \retval none +*/ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size) +{ + /* clear SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_BYTEN); + /* confige SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) |= (uint32_t)fifo_access_size; +} + +/*! + \brief configure SPI1 total number of data to transmit by DMA is odd or not + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in TX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_TXDMA_EVEN: number of byte in TX DMA channel is even + \arg SPI_TXDMA_ODD: number of byte in TX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TXDMA_ODD); + /* confige SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)odd; +} + +/*! + \brief configure SPI1 total number of data to receive by DMA is odd or not + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in RX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_RXDMA_EVEN: number of bytes in RX DMA channel is even + \arg SPI_RXDMA_ODD: number of bytes in RX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RXDMA_ODD); + /* confige SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)odd; +} + +/*! + \brief set CRC length + \param[in] spi_periph: SPIx(x=1) + \param[in] crc_length: CRC length + only one parameter can be selected which is shown as below: + \arg SPI_CRC_8BIT: CRC length is 8 bits + \arg SPI_CRC_16BIT: CRC length is 16 bits + \param[out] none + \retval none +*/ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length) +{ + /* clear SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCL); + /* confige SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) |= (uint32_t)crc_length; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c new file mode 100644 index 0000000000..a0e79e4176 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c @@ -0,0 +1,207 @@ + /*! + \file gd32e230_syscfg.h + \brief SYSCFG driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_syscfg.h" + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_CFGCMPRST); + rcu_periph_reset_disable(RCU_CFGCMPRST); +} + +/*! + \brief enable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \arg SYSCFG_PA11_REMAP_PA12: remap PA11 PA12 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 |= syscfg_dma_remap; +} + +/*! + \brief disable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \arg SYSCFG_PA11_REMAP_PA12: remap PA11 PA12 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 &= ~syscfg_dma_remap; +} + +/*! + \brief enable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_enable(void) +{ + SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE; +} + +/*! + \brief disable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_disable(void) +{ + SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE; +} + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + \arg EXTI_SOURCE_GPIOx(x = A,B,C,F): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + \arg EXTI_SOURCE_PINx(GPIOA x = 0..15,GPIOB x = 0..15,GPIOC x = 13..15,GPIOF x = 0.1.6.7): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP){ + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief connect TIMER0/14/15/16 break input to the selected parameter + \param[in] syscfg_lock: Specify the parameter to be connected + \arg SYSCFG_LOCK_LOCKUP: Cortex-M23 lockup output connected to the break input + \arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input + \arg SYSCFG_LOCK_LVD: LVD interrupt connected to the break input + \param[out] none + \retval none +*/ +void syscfg_lock_config(uint32_t syscfg_lock) +{ + SYSCFG_CFG2 |= syscfg_lock; +} + +/*! + \brief set the wait state counter value + \param[in] irq_latency: IRQ_LATENCY value (0x00 - 0xFF) + \param[out] none + \retval none +*/ +void irq_latency_set(uint8_t irq_latency) +{ + uint32_t reg; + + reg = SYSCFG_CPU_IRQ_LAT &(~(uint32_t)SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY); + reg |= (uint32_t)(IRQ_LATENCY(irq_latency)); + + SYSCFG_CPU_IRQ_LAT = (uint32_t)reg; +} +/*! + \brief check if the specified flag in SYSCFG_CFG2 is set or not. + \param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval the syscfg_flag state returned (SET or RESET). + */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag) +{ + if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the flag in SYSCFG_CFG2 by writing 1. + \param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval none +*/ +void syscfg_flag_clear(uint32_t syscfg_flag) +{ + SYSCFG_CFG2 |= (uint32_t) syscfg_flag; +} + diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c new file mode 100644 index 0000000000..3fce2c47f8 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c @@ -0,0 +1,2059 @@ +/*! + \file gd32e230_timer.c + \brief TIMER driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_timer.h" + +/* TIMER init parameter mask */ +#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */ +#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */ +#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */ + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + case TIMER14: + /* reset TIMER14 */ + rcu_periph_reset_enable(RCU_TIMER14RST); + rcu_periph_reset_disable(RCU_TIMER14RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct* initpara) +{ + /* initialize the init parameter struct member with the default value */ + initpara->prescaler = 0U; + initpara->alignedmode = TIMER_COUNTER_EDGE; + initpara->counterdirection = TIMER_COUNTER_UP; + initpara->period = 65535U; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock, 0~65535 + alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN + period: counter auto reload value, 0~65535 + clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value, 0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER2 == timer_periph)){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER0 == timer_periph) || (TIMER2 == timer_periph) || (TIMER13 == timer_periph) + || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] aligned: + only one parameter can be selected which is shown as below: + \arg TIMER_COUNTER_EDGE: edge-aligned mode + \arg TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode + \arg TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode + \arg TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode + \param[out] none + \retval none +*/ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CAM; + TIMER_CTL0(timer_periph) |= (uint32_t)aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] prescaler: prescaler value,0~65535 + \param[in] pscreload: prescaler reload mode + only one parameter can be selected which is shown as below: + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] repetition: the counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] autoreload: the counter auto-reload value,0~65535 + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] counter: the counter value,0~65535 + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)counter; +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0,2,5,14..16) + \param[in] spmode: + only one parameter can be selected which is shown as below: + \arg TIMER_SP_MODE_SINGLE: single pulse mode + \arg TIMER_SP_MODE_REPETITIVE: repetitive pulse mode + \param[out] none + \retval none +*/ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) +{ + if(TIMER_SP_MODE_SINGLE == spmode){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + }else if(TIMER_SP_MODE_REPETITIVE == spmode){ + TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] update: + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger + \arg TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow + \param[out] none + \retval none +*/ +void timer_update_source_config(uint32_t timer_periph, uint32_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(TIMER_UPDATE_SRC_GLOBAL == update){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER OCPRE clear source selection + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] ocpreclear: + only one parameter can be selected which is shown as below: + \arg TIMER_OCPRE_CLEAR_SOURCE_CLR: OCPRE_CLR_INT is connected to the OCPRE_CLR input + \arg TIMER_OCPRE_CLEAR_SOURCE_ETIF: OCPRE_CLR_INT is connected to ETIF + \param[out] none + \retval none +*/ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear) +{ + if(TIMER_OCPRE_CLEAR_SOURCE_ETIF == ocpreclear){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_OCRC; + }else if(TIMER_OCPRE_CLEAR_SOURCE_CLR == ocpreclear){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_OCRC; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt enable source + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt source disable + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0,2,13..16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,14..16) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,14..16) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & interrupt); + if((RESET != (TIMER_INTF(timer_periph) & interrupt) ) && (RESET != val)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0,2,13..16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,14..16) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which is shown as below: + \arg TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request, TIMERx(x=0,14) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to disable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request , TIMERx(x=0,14) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0,2,14..16) + \param[in] dma_request: channel DMA request source selection + only one parameter can be selected which is shown as below: + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0,2,14..16) + \param[in] dma_baseaddr: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0,2,14) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP, TIMERx(x=0,14..16) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0,2,14) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0,14..16) + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG, TIMERx(x=0,2,14..16) + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: please refer to the following parameters + \param[in] event: the timer software event generation sources + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0,2,5,13..16) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0,2,13..16) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0,2,14) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,14..16) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0,2,14) + \arg TIMER_EVENT_SRC_BRKG: break event generation, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->breakpolarity = TIMER_BREAK_POLARITY_LOW; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->breakstate = TIMER_BREAK_DISABLE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + breakpolarity: TIMER_BREAK_POLARITY_LOW,TIMER_BREAK_POLARITY_HIGH + outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2 + breakstate: TIMER_BREAK_ENABLE,TIMER_BREAK_DISABLE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate))| + ((uint32_t)(breakpara->ideloffstate))| + ((uint32_t)(breakpara->deadtime))| + ((uint32_t)(breakpara->breakpolarity))| + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode))| + ((uint32_t)(breakpara->breakstate))) ; +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); + } +} + +/*! + \brief enable or disable channel capture/compare control shadow register + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + }else{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] ccuctl: channel control shadow register update control + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief initialize TIMER channel output parameter struct with a default value + \param[in] ocpara: TIMER channel n output parameter struct + \param[out] none + \retval none +*/ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) +{ + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = (uint16_t)TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,2)) + \param[in] ocpara: TIMER channeln output parameter struct + outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate; + /* reset the CH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + /* set the CH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + /* set the CH0NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U); + + if(TIMER0 == timer_periph){ + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 2U); + } + + if(TIMER14 == timer_periph){ + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + } + + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U); + + if(TIMER0 == timer_periph){ + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 4U); + } + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U); + + if(TIMER0 == timer_periph){ + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U); + } + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocmode: channel output compare mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM0 mode + \arg TIMER_OC_MODE_PWM1: PWM1 mode + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] pulse: channel output pulse value,0~65535 + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocshadow: channel output shadow state + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocfast: channel output fast function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] occlear: channel output clear function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocpolarity: channel output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel2(TIMERx(x=0,2)) + \param[in] ocnpolarity: channel complementary output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] state: TIMER channel enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)state; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,14..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0)) + \param[in] ocnstate: TIMER channel complementary output enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value + \param[in] icpara: TIMER channel intput parameter struct + \param[out] none + \retval none +*/ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) +{ + /* initialize the channel input parameter struct member with the default value */ + icpara->icpolarity = TIMER_IC_POLARITY_RISING; + icpara->icselection = TIMER_IC_SELECTION_DIRECTTI; + icpara->icprescaler = TIMER_IC_PSC_DIV1; + icpara->icfilter = 0U; +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] icpara: TIMER channel intput parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic_parameter_struct* icpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection)); + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P and CH3NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P|TIMER_CHCTL2_CH3NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] prescaler: channel input capture prescaler value + only one parameter can be selected which is shown as below: + \arg TIMER_IC_PSC_DIV1: no prescaler + \arg TIMER_IC_PSC_DIV2: divided by 2 + \arg TIMER_IC_PSC_DIV4: divided by 4 + \arg TIMER_IC_PSC_DIV8: divided by 8 + \param[out] none + \retval none +*/ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel){ + /* read TIMER channel 0 capture compare register value */ + case TIMER_CH_0: + count_value = TIMER_CH0CV(timer_periph); + break; + /* read TIMER channel 1 capture compare register value */ + case TIMER_CH_1: + count_value = TIMER_CH1CV(timer_periph); + break; + /* read TIMER channel 2 capture compare register value */ + case TIMER_CH_2: + count_value = TIMER_CH2CV(timer_periph); + break; + /* read TIMER channel 3 capture compare register value */ + case TIMER_CH_3: + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \param[in] icpwm:TIMER channel intput pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + /* Set channel input polarity */ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + + /* Set channel input mode selection */ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel){ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(icpwm->icprescaler)); + }else{ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] hallmode: + only one parameter can be selected which is shown as below: + \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable + \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable + \param[out] none + \retval none +*/ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == hallmode){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + }else if(TIMER_HALLINTERFACE_DISABLE == hallmode){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger(TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0,2,5,14) + \param[in] outrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0,2,14)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] slavemode: + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable(TIMERx(x=0,2,14)) + \arg TIMER_ENCODER_MODE0: encoder mode 0(TIMERx(x=0,2)) + \arg TIMER_ENCODER_MODE1: encoder mode 1(TIMERx(x=0,2)) + \arg TIMER_ENCODER_MODE2: encoder mode 2(TIMERx(x=0,2)) + \arg TIMER_SLAVE_MODE_RESTART: restart mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_PAUSE: pause mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_EVENT: event mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0(TIMERx(x=0,2,14)) + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] masterslave: + only one parameter can be selected which is shown as below: + \arg TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable + \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable + \param[out] none + \retval none +*/ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] decomode: + only one parameter can be selected which is shown as below: + \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] ic1polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, + uint16_t ic0polarity, uint16_t ic1polarity) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity|((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + timer_input_trigger_source_select(timer_periph, intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] extrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active high or rising edge active + \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, + uint16_t extpolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 8U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + }else{ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)extfilter; + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph,extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief configure TIMER channel remap function + \param[in] timer_periph: TIMERx(x=13) + \param[in] remap: + only one parameter can be selected which is shown as below: + \arg TIMER13_CI0_RMP_GPIO: timer13 channel 0 input is connected to GPIO(TIMER13_CH0) + \arg TIMER13_CI0_RMP_RTCCLK: timer13 channel 0 input is connected to the RTCCLK + \arg TIMER13_CI0_RMP_HXTAL_DIV32: timer13 channel 0 input is connected to HXTAL/32 clock + \arg TIMER13_CI0_RMP_CKOUTSEL: timer13 channel 0 input is connected to CKOUTSEL + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) +{ + TIMER_IRMP(timer_periph) = (uint32_t)remap; +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0,2,13..16) + \param[in] ccsel: + only one parameter can be selected which is shown as below: + \arg TIMER_CHVSEL_DISABLE: no effect + \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored + \param[out] none + \retval none +*/ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) +{ + if(TIMER_CHVSEL_ENABLE == ccsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; + }else if(TIMER_CHVSEL_DISABLE == ccsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] outsel: + only one parameter can be selected which is shown as below: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) +{ + if(TIMER_OUTSEL_ENABLE == outsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + }else if(TIMER_OUTSEL_DISABLE == outsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; + }else{ + /* illegal parameters */ + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c new file mode 100644 index 0000000000..f73723e4be --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c @@ -0,0 +1,1318 @@ +/*! + \file gd32e230_usart.c + \brief USART driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_usart.h" + +/*! + \brief reset USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + /* reset USART0 */ + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + /* reset USART1 */ + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1) + \param[in] baudval: baud rate value + \param[out] none + \retval none +*/ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) +{ + uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk = rcu_clock_freq_get(CK_USART); + break; + case USART1: + /* get USART1 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U*uclk)+baudval/2U)/baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = (udiv>>1U) & 0x00000007U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = udiv & 0x0000000fU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1) + \param[in] paritycfg: USART parity configure + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 PM,PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wlen: USART word length configure + only one parameter can be selected which is shown as below: + \arg USART_WL_8BIT: 8 bits + \arg USART_WL_9BIT: 9 bits + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen; +} + +/*! + \brief configure USART stop bit length + \param[in] usart_periph: USARTx(x=0,1) + \param[in] stblen: USART stop bit configure + only one parameter can be selected which is shown as below: + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5bit + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5bit + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + USART_CTL1(usart_periph) |= stblen; +} + +/*! + \brief enable USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter + \param[in] usart_periph: USARTx(x=0,1) + \param[in] txconfig: enable or disable USART transmitter + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_ENABLE: enable USART transmission + \arg USART_TRANSMIT_DISABLE: enable USART transmission + \param[out] none + \retval none +*/ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_TEN; + /* configure transfer mode */ + USART_CTL0(usart_periph) |= txconfig; +} + +/*! + \brief configure USART receiver + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rxconfig: enable or disable USART receiver + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_ENABLE: enable USART reception + \arg USART_RECEIVE_DISABLE: disable USART reception + \param[out] none + \retval none +*/ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_REN; + /* configure receiver mode */ + USART_CTL0(usart_periph) |= rxconfig; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1) + \param[in] msbf: LSB/MSB + only one parameter can be selected which is shown as below: + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf); +} + +/*! + \brief USART inverted configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] invertpara: refer to usart_invert_enum + only one parameter can be selected which is shown as below: + \arg USART_DINV_ENABLE: data bit level inversion + \arg USART_DINV_DISABLE: data bit level not inversion + \arg USART_TXPIN_ENABLE: TX pin level inversion + \arg USART_TXPIN_DISABLE: TX pin level not inversion + \arg USART_RXPIN_ENABLE: RX pin level inversion + \arg USART_RXPIN_DISABLE: RX pin level not inversion + \arg USART_SWAP_ENABLE: swap TX/RX pins + \arg USART_SWAP_DISABLE: not swap TX/RX pins + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* inverted or not the specified signal */ + switch(invertpara){ + case USART_DINV_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_DINV; + break; + case USART_DINV_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_DINV); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_TXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + default: + break; + } +} + +/*! + \brief enable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* enable overrun function */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief disable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* disable overrun function */ + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] oversamp: oversample value + only one parameter can be selected which is shown as below: + \arg USART_OVSMOD_8: oversampling by 8 + \arg USART_OVSMOD_16: oversampling by 16 + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp; +} + +/*! + \brief configure the sample bit method + \param[in] usart_periph: USARTx(x=0,1) + \param[in] osb: sample bit + only one parameter can be selected which is shown as below: + \arg USART_OSB_1BIT: 1 bit + \arg USART_OSB_3BIT: 3 bits + \param[out] none + \retval none +*/ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= osb; +} + +/*! + \brief enable receiver timeout + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief disable receiver timeout + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief configure receiver timeout threshold + \param[in] usart_periph: USARTx(x=0) + \param[in] rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); +} + +/*! + \brief enable auto baud rate detection + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_ABDEN; +} + +/*! + \brief disable auto baud rate detection + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN); +} + +/*! + \brief configure auto baud rate detection mode + \param[in] usart_periph: USARTx(x=0) + \param[in] abdmod: auto baud rate detection mode + only one parameter can be selected which is shown as below: + \arg USART_ABDM_FTOR: falling edge to rising edge measurement + \arg USART_ABDM_FTOF: falling edge to falling edge measurement + \param[out] none + \retval none +*/ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod) +{ + /* reset ABDM bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM); + USART_CTL1(usart_periph) |= abdmod; +} + +/*! + \brief address of the USART terminal + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << 24)); +} + +/*! + \brief configure address detection mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addmod: address detection mode + only one parameter can be selected which is shown as below: + \arg USART_ADDM_4BIT: 4 bits + \arg USART_ADDM_FULLBIT: full bits + \param[out] none + \retval none +*/ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDM); + USART_CTL1(usart_periph) |= USART_CTL1_ADDM & (addmod); +} + +/*! + \brief enable mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief disable mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief configure wakeup method in mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wmethod: two methods be used to enter or exit the mute mode + only one parameter can be selected which is shown as below: + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0) + \param[in] lblen: LIN break detection length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits break detection + \arg USART_LBLEN_11B: 11 bits break detection + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen); +} + +/*! + \brief enable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable clock + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_clock_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable clock + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_clock_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1) + \param[in] clen: last bit clock pulse + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin + \arg USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset USART_CTL1 CLEN,CPH,CPL bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen); + USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph); + USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl); +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << 8)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_ELNACK; +} + +/*! + \brief disable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~USART_RFCS_ELNACK; +} + +/*! + \brief configure smartcard auto-retry number + \param[in] usart_periph: USARTx(x=0) + \param[in] scrtnum: 0x00000000-0x00000007, smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM); + USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (scrtnum << 17)); +} + +/*! + \brief configure block length + \param[in] usart_periph: USARTx(x=0) + \param[in] bl: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] psc: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= rtsconfig; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~USART_CTL2_CTSEN; + USART_CTL2(usart_periph) |= ctsconfig; +} + + /*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] hcm: + only one parameter can be selected which is shown as below: + \arg USART_HCM_NONE: nRTS signal equals to the rxne status register + \arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled + \param[out] none + \retval none +*/ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_HCM); + USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm); +} + +/*! + \brief enable RS485 driver + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_rs485_driver_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DEM; +} + +/*! + \brief disable RS485 driver + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_rs485_driver_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEM); +} + +/*! + \brief configure driver enable assertion time + \param[in] usart_periph: USARTx(x=0,1) + \param[in] deatime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA); + USART_CTL0(usart_periph) |= (USART_CTL0_DEA & ((deatime) << 21)); +} + +/*! + \brief configure driver enable de-assertion time + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dedtime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DED); + USART_CTL0(usart_periph) |= (USART_CTL0_DED & ((dedtime) << 16)); +} + +/*! + \brief configure driver enable polarity mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dep: DE signal + only one parameter can be selected which is shown as below: + \arg USART_DEP_HIGH: DE signal is active high + \arg USART_DEP_LOW: DE signal is active low + \param[out] none + \retval none +*/ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset DEP bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEP); + USART_CTL2(usart_periph) |= (USART_CTL2_DEP & dep); +} + +/*! + \brief configure USART DMA reception + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for reception + only one parameter can be selected which is shown as below: + \arg USART_DENR_ENABLE: DMA enable for reception + \arg USART_DENR_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENR; + /* configure DMA reception */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for transmission + only one parameter can be selected which is shown as below: + \arg USART_DENT_ENABLE: DMA enable for transmission + \arg USART_DENT_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENT; + /* configure DMA transmission */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief disable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DDRE; +} + +/*! + \brief enable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DDRE); +} + +/*! + \brief enable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief disable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief configure the USART wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[in] wum: wakeup mode + only one parameter can be selected which is shown as below: + \arg USART_WUM_ADDR: WUF active on address match + \arg USART_WUM_STARTB: WUF active on start bit + \arg USART_WUM_RBNE: WUF active on RBNE + \param[out] none + \retval none +*/ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset WUM bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_WUM); + USART_CTL2(usart_periph) |= USART_CTL2_WUM & (wum); +} + +/*! + \brief enable receive FIFO + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_receive_fifo_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_RFEN; +} + +/*! + \brief disable receive FIFO + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_receive_fifo_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~(USART_RFCS_RFEN); +} + +/*! + \brief read receive FIFO counter number + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval receive FIFO counter number +*/ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph) +{ + return (uint8_t)(GET_BITS(USART_RFCS(usart_periph), 12U, 14U)); +} + +/*! + \brief get flag in STAT/CHC/RFCS register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_ABDE: auto baudrate detection error + \arg USART_FLAG_ABD: auto baudrate detection flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_RFE: receive FIFO empty flag + \arg USART_FLAG_RFF: receive FIFO full flag + \arg USART_FLAG_RFFINT: receive FIFO full interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR: overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype) +{ + USART_REG_VAL(usart_periph, inttype) |= BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype) +{ + USART_REG_VAL(usart_periph, inttype) &= ~BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1) + \param[in] cmdtype: command type + only one parameter can be selected which is shown as below: + \arg USART_CMD_ABDCMD: auto baudrate detection command + \arg USART_CMD_SBKCMD: send break command + \arg USART_CMD_MMCMD: mute mode command + \arg USART_CMD_RXFCMD: receive data flush command + \arg USART_CMD_TXFCMD: transmit data flush request + \param[out] none + \retval none +*/ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype) +{ + USART_CMD(usart_periph) |= (cmdtype); +} + +/*! + \brief get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block interrupt and flag + \arg USART_INT_FLAG_RT: receiver timeout interrupt and flag + \arg USART_INT_FLAG_AM: address match interrupt and flag + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag + \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if(flagstatus && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART interrupt flag + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_ERR_FERR: frame error flag + \arg USART_INT_FLAG_ERR_NERR: noise detected flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag) +{ + if(USART_INT_FLAG_RFF == flag){ + USART_RFCS(usart_periph) &= (uint32_t)(~USART_RFCS_RFFINT); + }else{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag)); + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c new file mode 100644 index 0000000000..4d1ad0200c --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c @@ -0,0 +1,148 @@ +/*! + \file gd32e230_wwdgt.c + \brief WWDGT driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32e230_wwdgt.h" +#include "gd32e230_rcu.h" + +/* WWDGT_CTL register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CTL_CNT bit field */ +/* WWDGT_CFG register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CFG_WIN bit field */ + +/*! + \brief reset the window watchdog timer configuration + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_deinit(void) +{ + rcu_periph_reset_enable(RCU_WWDGTRST); + rcu_periph_reset_disable(RCU_WWDGTRST); +} + +/*! + \brief start the window watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the window watchdog timer counter value + \param[in] counter_value: 0x00000000 - 0x0000007F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + uint32_t reg = 0x00000000U; + + reg = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + reg |= (uint32_t)(CTL_CNT(counter_value)); + + WWDGT_CTL = (uint32_t)reg; +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x00000000 - 0x0000007F + \param[in] window: 0x00000000 - 0x0000007F + \param[in] prescaler: wwdgt prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + uint32_t reg_cfg = 0x00000000U, reg_ctl = 0x00000000U; + + /* clear WIN and PSC bits, clear CNT bit */ + reg_cfg = WWDGT_CFG &(~((uint32_t)WWDGT_CFG_WIN|(uint32_t)WWDGT_CFG_PSC)); + reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= (uint32_t)(CFG_WIN(window)); + reg_cfg |= (uint32_t)(prescaler); + reg_ctl |= (uint32_t)(CTL_CNT(counter)); + + WWDGT_CFG = (uint32_t)reg_cfg; + WWDGT_CTL = (uint32_t)reg_ctl; +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if(RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)){ + return SET; + } + return RESET; +} + +/*! + \brief clear early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_flag_clear(void) +{ + WWDGT_STAT &= (uint32_t)(~(uint32_t)WWDGT_STAT_EWIF); +} diff --git a/bsp/gd32e230k-start/Libraries/SConscript b/bsp/gd32e230k-start/Libraries/SConscript new file mode 100644 index 0000000000..eb4cfb77c7 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/SConscript @@ -0,0 +1,33 @@ +import rtconfig +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. + +src = Glob('GD32F30x_standard_peripheral/Source/*.c') +src += [cwd + '/CMSIS/GD/GD32F30x/Source/system_gd32f30x.c'] + +#add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + src += [cwd + '/CMSIS/GD/GD32F30x/Source/GCC/startup_gd32f30x_hd.s'] +elif rtconfig.CROSS_TOOL == 'keil': + src += [cwd + '/CMSIS/GD/GD32F30x/Source/ARM/startup_gd32f30x_hd.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [cwd + '/CMSIS/GD/GD32F30x/Source/IAR/startup_gd32f30x_hd.s'] + +path = [ + cwd + '/CMSIS/GD/GD32F30x/Include', + cwd + '/CMSIS', + cwd + '/GD32F30x_standard_peripheral/Include',] + +if GetDepend(['RT_USING_BSP_USB']): + path += [cwd + '/GD32F30x_usb_driver/Include'] + src += [cwd + '/GD32F30x_usb_driver/Source'] + +CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F30X_HD'] + +group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/gd32e230k-start/SConscript b/bsp/gd32e230k-start/SConscript new file mode 100644 index 0000000000..fe0ae941ae --- /dev/null +++ b/bsp/gd32e230k-start/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +Import('RTT_ROOT') + +cwd = str(Dir('#')) +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/gd32e230k-start/SConstruct b/bsp/gd32e230k-start/SConstruct new file mode 100644 index 0000000000..1cdbaab4a8 --- /dev/null +++ b/bsp/gd32e230k-start/SConstruct @@ -0,0 +1,39 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread-gd32f30x.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map project.map') + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/gd32e230k-start/applications/SConscript b/bsp/gd32e230k-start/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/gd32e230k-start/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32e230k-start/applications/main.c b/bsp/gd32e230k-start/applications/main.c new file mode 100644 index 0000000000..6e190ae3cc --- /dev/null +++ b/bsp/gd32e230k-start/applications/main.c @@ -0,0 +1,27 @@ +/* + * File : main.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2015-07-29 Arda.Fu first implementation + */ +#include +#include + +int main(void) +{ + /* user app entry */ + + return 0; +} + + + + + diff --git a/bsp/gd32e230k-start/drivers/SConscript b/bsp/gd32e230k-start/drivers/SConscript new file mode 100644 index 0000000000..ef03e2dcf0 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/SConscript @@ -0,0 +1,33 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'drivers') + +# add the general drivers. +src = Split(""" +board.c +drv_usart.c +""") + +CPPPATH = [cwd] + +# add spi drivers. +if GetDepend('RT_USING_SPI'): + src += ['drv_spi.c'] + +# add i2c drivers. +if GetDepend('RT_USING_I2C'): + src += ['drv_i2c.c'] + +# add pin drivers. +if GetDepend('RT_USING_PIN'): + src += ['drv_gpio.c'] + +# add spi flash drivers. +if GetDepend('RT_USING_SFUD'): + src += ['drv_spi_flash.c'] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32e230k-start/drivers/board.c b/bsp/gd32e230k-start/drivers/board.c new file mode 100644 index 0000000000..9ca024ec48 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/board.c @@ -0,0 +1,87 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first implementation + */ +#include +#include +#include +#include + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + } + /* USER CODE END Error_Handler */ +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + NVIC_SetPriority(SysTick_IRQn, 0); +} + +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +/** + * This function will initial GD32 board. + */ +void rt_hw_board_init() +{ + /* NVIC Configuration */ +#define NVIC_VTOR_MASK 0x3FFFFF80 +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); +#endif + + SystemClock_Config(); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END); +#endif +} + +/*@}*/ diff --git a/bsp/gd32e230k-start/drivers/board.h b/bsp/gd32e230k-start/drivers/board.h new file mode 100644 index 0000000000..de344e8768 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/board.h @@ -0,0 +1,47 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-09-22 Bernard add board.h to this bsp + */ + +// <<< Use Configuration Wizard in Context Menu >>> +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +// Internal SRAM memory size[Kbytes] <8-64> +// Default: 64 +#ifdef __ICCARM__ +// Use *.icf ram symbal, to avoid hardcode. +extern char __ICFEDIT_region_RAM_end__; +#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__ +#else +#define GD32_SRAM_SIZE 64 +#define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) +#endif + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define HEAP_BEGIN (&__bss_end) +#endif + +#define HEAP_END GD32_SRAM_END + +#endif + +//*** <<< end of configuration section >>> *** diff --git a/bsp/gd32e230k-start/drivers/drv_gpio.c b/bsp/gd32e230k-start/drivers/drv_gpio.c new file mode 100644 index 0000000000..6b9ecf4e34 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_gpio.c @@ -0,0 +1,539 @@ +/* + * File : drv_gpio.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-10-20 ZYH the first version + * 2018-04-23 misonyo port to gd32f30x + */ + +#include "drv_gpio.h" +#include +#include +#include "gd32e230.h" +#include "gd32e230_exti.h" + +#ifdef RT_USING_PIN + +#define __GD32_PIN(index, port, pin) {index, RCU_GPIO##port, GPIO##port, \ + GPIO_PIN_##pin, EXTI_SOURCE_GPIO##port, EXTI_SOURCE_PIN##pin} +#define __GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0} + +/* GD32 GPIO driver */ +struct pin_index +{ + rt_int16_t index; + rcu_periph_enum clk; + rt_uint32_t gpio_periph; + rt_uint32_t pin; + rt_uint32_t port_src; + rt_uint32_t pin_src; +}; + +static const struct pin_index pins[] = +{ + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(7, C, 13), + __GD32_PIN(8, C, 14), + __GD32_PIN(9, C, 15), + __GD32_PIN(10, F, 0), + __GD32_PIN(11, F, 1), + __GD32_PIN(12, F, 2), + __GD32_PIN(13, F, 3), + __GD32_PIN(14, F, 4), + __GD32_PIN(15, F, 5), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(18, F, 6), + __GD32_PIN(19, F, 7), + __GD32_PIN(20, F, 8), + __GD32_PIN(21, F, 9), + __GD32_PIN(22, F, 10), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(26, C, 0), + __GD32_PIN(27, C, 1), + __GD32_PIN(28, C, 2), + __GD32_PIN(29, C, 3), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(34, A, 0), + __GD32_PIN(35, A, 1), + __GD32_PIN(36, A, 2), + __GD32_PIN(37, A, 3), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(40, A, 4), + __GD32_PIN(41, A, 5), + __GD32_PIN(42, A, 6), + __GD32_PIN(43, A, 7), + __GD32_PIN(44, C, 4), + __GD32_PIN(45, C, 5), + __GD32_PIN(46, B, 0), + __GD32_PIN(47, B, 1), + __GD32_PIN(48, B, 2), + __GD32_PIN(49, F, 11), + __GD32_PIN(50, F, 12), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(53, F, 13), + __GD32_PIN(54, F, 14), + __GD32_PIN(55, F, 15), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(69, B, 10), + __GD32_PIN(70, B, 11), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(73, B, 12), + __GD32_PIN(74, B, 13), + __GD32_PIN(75, B, 14), + __GD32_PIN(76, B, 15), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(96, C, 6), + __GD32_PIN(97, C, 7), + __GD32_PIN(98, C, 8), + __GD32_PIN(99, C, 9), + __GD32_PIN(100, A, 8), + __GD32_PIN(101, A, 9), + __GD32_PIN(102, A, 10), + __GD32_PIN(103, A, 11), + __GD32_PIN(104, A, 12), + __GD32_PIN(105, A, 13), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(109, A, 14), + __GD32_PIN(110, A, 15), + __GD32_PIN(111, C, 10), + __GD32_PIN(112, C, 11), + __GD32_PIN(113, C, 12), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(133, B, 3), + __GD32_PIN(134, B, 4), + __GD32_PIN(135, B, 5), + __GD32_PIN(136, B, 6), + __GD32_PIN(137, B, 7), + __GD32_PIN_DEFAULT, + __GD32_PIN(139, B, 8), + __GD32_PIN(140, B, 9), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, +}; + +struct pin_irq_map +{ + rt_uint16_t pinbit; + IRQn_Type irqno; +}; +static const struct pin_irq_map pin_irq_map[] = +{ + {GPIO_PIN_0, EXTI0_1_IRQn}, + {GPIO_PIN_1, EXTI0_1_IRQn}, + {GPIO_PIN_2, EXTI2_3_IRQn}, + {GPIO_PIN_3, EXTI2_3_IRQn}, + {GPIO_PIN_4, EXTI4_15_IRQn}, + {GPIO_PIN_5, EXTI4_15_IRQn}, + {GPIO_PIN_6, EXTI4_15_IRQn}, + {GPIO_PIN_7, EXTI4_15_IRQn}, + {GPIO_PIN_8, EXTI4_15_IRQn}, + {GPIO_PIN_9, EXTI4_15_IRQn}, + {GPIO_PIN_10, EXTI4_15_IRQn}, + {GPIO_PIN_11, EXTI4_15_IRQn}, + {GPIO_PIN_12, EXTI4_15_IRQn}, + {GPIO_PIN_13, EXTI4_15_IRQn}, + {GPIO_PIN_14, EXTI4_15_IRQn}, + {GPIO_PIN_15, EXTI4_15_IRQn}, +}; +struct rt_pin_irq_hdr pin_irq_hdr_tab[] = +{ + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, +}; + +#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) +const struct pin_index *get_pin(rt_uint8_t pin) +{ + const struct pin_index *index; + + if (pin < ITEM_NUM(pins)) + { + index = &pins[pin]; + if (index->index == -1) + index = RT_NULL; + } + else + { + index = RT_NULL; + } + + return index; +}; + +void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + const struct pin_index *index; + rt_uint32_t pin_mode; + rt_uint32_t otype; + rt_uint32_t pull_up_down; + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + /* GPIO Periph clock enable */ + rcu_periph_clock_enable(index->clk); + pin_mode = GPIO_MODE_OUTPUT; + otype = GPIO_OTYPE_PP; + pull_up_down = GPIO_PUPD_NONE; + + switch(mode) + { + case PIN_MODE_OUTPUT: + /* output setting */ + break; + case PIN_MODE_OUTPUT_OD: + /* output setting: od. */ + otype = GPIO_OTYPE_OD; + break; + case PIN_MODE_INPUT: + /* input setting: not pull. */ + pin_mode = GPIO_MODE_INPUT; + break; + case PIN_MODE_INPUT_PULLUP: + /* input setting: pull up. */ + pin_mode = GPIO_MODE_INPUT; + pull_up_down = GPIO_PUPD_PULLUP; + break; + case PIN_MODE_INPUT_PULLDOWN: + /* input setting: pull down. */ + pin_mode = GPIO_MODE_INPUT; + pull_up_down = GPIO_PUPD_PULLDOWN; + break; + default: + break; + } + + gpio_mode_set(index->gpio_periph, pin_mode, pull_up_down, index->pin); + gpio_output_options_set(index->gpio_periph, otype, GPIO_OSPEED_50MHZ, index->pin); + +} + +void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +{ + const struct pin_index *index; + + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value); +} + +int gd32_pin_read(rt_device_t dev, rt_base_t pin) +{ + int value; + const struct pin_index *index; + + value = PIN_LOW; + + index = get_pin(pin); + if (index == RT_NULL) + { + return value; + } + + value = gpio_input_bit_get(index->gpio_periph, index->pin); + + return value; +} + + +rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) +{ + rt_uint8_t i; + for (i = 0; i < 32; i++) + { + if ((0x01 << i) == bit) + { + return i; + } + } + return -1; +} +rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit) +{ + rt_int32_t mapindex = bit2bitno(pinbit); + if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map)) + { + return RT_NULL; + } + return &pin_irq_map[mapindex]; +}; +rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, + rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + const struct pin_index *index; + rt_base_t level; + rt_int32_t hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == pin && + pin_irq_hdr_tab[hdr_index].hdr == hdr && + pin_irq_hdr_tab[hdr_index].mode == mode && + pin_irq_hdr_tab[hdr_index].args == args) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + if (pin_irq_hdr_tab[hdr_index].pin != -1) + { + rt_hw_interrupt_enable(level); + return RT_EFULL; + } + pin_irq_hdr_tab[hdr_index].pin = pin; + pin_irq_hdr_tab[hdr_index].hdr = hdr; + pin_irq_hdr_tab[hdr_index].mode = mode; + pin_irq_hdr_tab[hdr_index].args = args; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} +rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + const struct pin_index *index; + rt_base_t level; + rt_int32_t hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + pin_irq_hdr_tab[hdr_index].pin = -1; + pin_irq_hdr_tab[hdr_index].hdr = RT_NULL; + pin_irq_hdr_tab[hdr_index].mode = 0; + pin_irq_hdr_tab[hdr_index].args = RT_NULL; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} +rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + const struct pin_index *index; + const struct pin_irq_map *irqmap; + rt_base_t level; + rt_int32_t hdr_index = -1; + exti_trig_type_enum trigger_mode; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + if (enabled == PIN_IRQ_ENABLE) + { + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + irqmap = &pin_irq_map[hdr_index]; + + switch (pin_irq_hdr_tab[hdr_index].mode) + { + case PIN_IRQ_MODE_RISING: + trigger_mode = EXTI_TRIG_RISING; + break; + case PIN_IRQ_MODE_FALLING: + trigger_mode = EXTI_TRIG_FALLING; + break; + case PIN_IRQ_MODE_RISING_FALLING: + trigger_mode = EXTI_TRIG_BOTH; + break; + default: + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + + //rcu_periph_clock_enable(RCU_AF); + + /* enable and set interrupt priority */ + nvic_irq_enable(irqmap->irqno, 5U); + + /* connect EXTI line to GPIO pin */ + syscfg_exti_line_config(index->port_src, index->pin_src); + + /* configure EXTI line */ + exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode); + exti_interrupt_flag_clear((exti_line_enum)(index->pin)); + + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + irqmap = get_pin_irq_map(index->pin); + if (irqmap == RT_NULL) + { + return RT_EINVAL; + } + nvic_irq_disable(irqmap->irqno); + } + else + { + return RT_EINVAL; + } + + return RT_EOK; +} +const static struct rt_pin_ops _gd32_pin_ops = +{ + gd32_pin_mode, + gd32_pin_write, + gd32_pin_read, + gd32_pin_attach_irq, + gd32_pin_detach_irq, + gd32_pin_irq_enable, +}; + +int rt_hw_pin_init(void) +{ + int result; + + result = rt_device_pin_register("pin", &_gd32_pin_ops, RT_NULL); + + return result; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); + +rt_inline void pin_irq_hdr(int irqno) +{ + if (pin_irq_hdr_tab[irqno].hdr) + { + pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); + } +} + +void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line) +{ + if(RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line))) + { + pin_irq_hdr(exti_line); + exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line)); + } +} +void EXTI0_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(0); + rt_interrupt_leave(); +} +void EXTI1_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(1); + rt_interrupt_leave(); +} +void EXTI2_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(2); + rt_interrupt_leave(); +} +void EXTI3_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(3); + rt_interrupt_leave(); +} +void EXTI4_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(4); + rt_interrupt_leave(); +} +void EXTI5_9_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(5); + GD32_GPIO_EXTI_IRQHandler(6); + GD32_GPIO_EXTI_IRQHandler(7); + GD32_GPIO_EXTI_IRQHandler(8); + GD32_GPIO_EXTI_IRQHandler(9); + rt_interrupt_leave(); +} +void EXTI10_15_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(10); + GD32_GPIO_EXTI_IRQHandler(11); + GD32_GPIO_EXTI_IRQHandler(12); + GD32_GPIO_EXTI_IRQHandler(13); + GD32_GPIO_EXTI_IRQHandler(14); + GD32_GPIO_EXTI_IRQHandler(15); + rt_interrupt_leave(); +} + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_gpio.h b/bsp/gd32e230k-start/drivers/drv_gpio.h new file mode 100644 index 0000000000..bca532ff2d --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_gpio.h @@ -0,0 +1,18 @@ +/* + * File : drv_gpio.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2015-01-05 Bernard the first version + */ +#ifndef GPIO_H__ +#define GPIO_H__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_i2c.c b/bsp/gd32e230k-start/drivers/drv_i2c.c new file mode 100644 index 0000000000..c0fbd5f7e9 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_i2c.c @@ -0,0 +1,381 @@ +/* + * File : drv_i2c.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 + * 2017-06-05 tanek first implementation. + * 2018-04-19 misonyo Porting for gd32f30x + */ + +#include "drv_i2c.h" +#include +#include "gd32e230.h" + +#ifdef RT_USING_I2C + +#include + +#ifdef RT_USING_I2C_BITOPS + +/*user can change this*/ +#define I2C_BUS_NAME "i2c2" + +/*user should change this to adapt specific board*/ +#define I2C_SCL_PIN GPIO_PIN_4 +#define I2C_SCL_PORT GPIOE +#define I2C_SCL_CLK RCU_GPIOE +#define I2C_SDA_PIN GPIO_PIN_5 +#define I2C_SDA_PORT GPIOE +#define I2C_SDA_CLK RCU_GPIOE + +struct gd32_i2c_bit_data +{ + struct + { + rcu_periph_enum clk; + rt_uint32_t port; + rt_uint32_t pin; + }scl, sda; +}; + +static void gpio_set_sda(void *data, rt_int32_t state) +{ + struct gd32_i2c_bit_data* bd = data; + + if (state) + { + gpio_bit_set(bd->sda.port, bd->sda.pin); + } + else + { + gpio_bit_reset(bd->sda.port, bd->sda.pin); + } +} + +static void gpio_set_scl(void *data, rt_int32_t state) +{ + struct gd32_i2c_bit_data* bd = data; + if (state) + { + gpio_bit_set(bd->scl.port, bd->scl.pin); + } + else + { + gpio_bit_reset(bd->scl.port, bd->scl.pin); + } +} + +static rt_int32_t gpio_get_sda(void *data) +{ + struct gd32_i2c_bit_data* bd = data; + + return gpio_input_bit_get(bd->sda.port, bd->sda.pin); +} + +static rt_int32_t gpio_get_scl(void *data) +{ + struct gd32_i2c_bit_data* bd = data; + + return gpio_input_bit_get(bd->scl.port, bd->scl.pin); +} + +static void gpio_udelay(rt_uint32_t us) +{ + int i = ( rcu_clock_freq_get(CK_SYS) / 4000000 * us); + while(i) + { + i--; + } +} + +static void drv_i2c_gpio_init(const struct gd32_i2c_bit_data* bd) +{ + rcu_periph_clock_enable(bd->sda.clk); + rcu_periph_clock_enable(bd->scl.clk); + gpio_init(bd->sda.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->sda.pin); + gpio_init(bd->scl.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->scl.pin); + + gpio_bit_set(bd->sda.port, bd->sda.pin); + gpio_bit_set(bd->scl.port, bd->scl.pin); +} + +#else /* use hardware i2c */ + +struct gd32_i2c_bus +{ + struct rt_i2c_bus_device parent; + rt_uint32_t i2c_periph; +}; + +static int gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint16_t slave_address, rt_uint8_t* p_buffer, rt_uint16_t data_byte) +{ + /* wait until I2C bus is idle */ + while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)); + + /* send a start condition to I2C bus */ + i2c_start_on_bus(i2c_periph); + + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND)); + + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address<<1, I2C_RECEIVER); + + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND); + + if(1 == data_byte){ + /* disable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_DISABLE); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + } + + /* while there is data to be read */ + while(data_byte) + { + /* wait until the RBNE bit is set and clear it */ + if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE)) + { + /* read a byte from the EEPROM */ + *p_buffer = i2c_data_receive(i2c_periph); + + /* point to the next location where the byte read will be saved */ + p_buffer++; + + /* decrement the read bytes counter */ + data_byte--; + if(1 == data_byte) + { + /* disable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_DISABLE); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + } + } + } + + /* wait until the stop condition is finished */ + while(I2C_CTL0(i2c_periph)&0x0200); + + /* enable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_ENABLE); + + i2c_ackpos_config(i2c_periph,I2C_ACKPOS_CURRENT); + + return 0; +} + +static int gd32_i2c_write(rt_uint32_t i2c_periph, uint16_t slave_address, uint8_t* p_buffer, uint16_t data_byte) +{ + /* wait until I2C bus is idle */ + while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)); + + /* send a start condition to I2C bus */ + i2c_start_on_bus(i2c_periph); + + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND)); + + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address<<1, I2C_TRANSMITTER); + + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND); + + /* wait until the transmit data buffer is empty */ + while(SET != i2c_flag_get( i2c_periph , I2C_FLAG_TBE)); + + /* while there is data to be read */ + while(data_byte) + { + i2c_data_transmit(i2c_periph, *p_buffer); + + /* point to the next byte to be written */ + p_buffer++; + + /* decrement the write bytes counter */ + data_byte --; + + /* wait until BTC bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + } + + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + + /* wait until the stop condition is finished */ + while(I2C_CTL0(i2c_periph)&0x0200); + + return 0; +} + +static rt_size_t gd32_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + rt_uint32_t i; + rt_err_t ret = RT_ERROR; + + struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + + if (msg->flags & RT_I2C_ADDR_10BIT) + { + i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_10BITS,0); + } + else + { + i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0); + } + if (msg->flags & RT_I2C_RD) + { + if (gd32_i2c_read(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + else + { + if (gd32_i2c_write(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + } + + ret = i; + +out: + i2c_dbg("send stop condition\n"); + + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_ops = +{ + gd32_i2c_xfer, + RT_NULL, + RT_NULL +}; + +#endif /* RT_USING_I2C_BITOPS */ + +int rt_hw_i2c_init(void) +{ +#ifdef RT_USING_I2C_BITOPS + { + static struct rt_i2c_bus_device i2c_device; + static const struct gd32_i2c_bit_data _i2c_bdata = + { + /* SCL */ + { I2C_SCL_CLK, I2C_SCL_PORT, I2C_SCL_PIN}, + /* SDA */ + { I2C_SDA_CLK, I2C_SDA_PORT, I2C_SDA_PIN}, + }; + + static const struct rt_i2c_bit_ops _i2c_bit_ops = + { + (void*)&_i2c_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + gpio_udelay, + 1, + 100 + }; + + drv_i2c_gpio_init(&_i2c_bdata); + + i2c_device.priv = (void *)&_i2c_bit_ops; + rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME); + } + +#else /* register hardware I2C */ + +#ifdef RT_USING_I2C0 +#define I2C0_SPEED 100000 + + static struct gd32_i2c_bus gd32_i2c0; + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + + /* connect PB6 to I2C0_SCL, PB7 to I2C0_SDA */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7); + + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_I2C0); + /* configure I2C clock */ + i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2); + + i2c_enable(I2C0); + /* enable acknowledge */ + i2c_ack_config(I2C0,I2C_ACK_ENABLE); + + rt_memset((void *)&gd32_i2c0, 0, sizeof(struct gd32_i2c_bus)); + gd32_i2c0.parent.ops = &i2c_ops; + gd32_i2c0.i2c_periph = I2C0; + rt_i2c_bus_device_register(&gd32_i2c0.parent, "i2c0"); +#endif + +#ifdef RT_USING_I2C1 +#define I2C1_SPEED 100000 + + static struct gd32_i2c_bus gd32_i2c1; + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + + /* connect PB10 to I2C1_SCL, PB11 to I2C1_SDA */ + gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11); + + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_I2C1); + /* configure I2C clock */ + i2c_clock_config(I2C1,I2C1_SPEED,I2C_DTCY_2); + + i2c_enable(I2C1); + /* enable acknowledge */ + i2c_ack_config(I2C1,I2C_ACK_ENABLE); + + rt_memset((void *)&gd32_i2c1, 0, sizeof(struct gd32_i2c_bus)); + gd32_i2c1.parent.ops = &i2c_ops; + gd32_i2c1.i2c_periph = I2C1; + rt_i2c_bus_device_register(&gd32_i2c1.parent, "i2c1"); +#endif + +#endif /* RT_USING_I2C_BITOPS */ + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif +/* end of i2c driver */ diff --git a/bsp/gd32e230k-start/drivers/drv_i2c.h b/bsp/gd32e230k-start/drivers/drv_i2c.h new file mode 100644 index 0000000000..2cc86ace3c --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_i2c.h @@ -0,0 +1,29 @@ +/* + * File : drv_i2c.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 + * 2017-06-05 tanek first implementation. + */ + +#ifndef __DRV_I2C__ +#define __DRV_I2C__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_spi.c b/bsp/gd32e230k-start/drivers/drv_spi.c new file mode 100644 index 0000000000..7c749d75e0 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_spi.c @@ -0,0 +1,290 @@ +/* + * File : drv_spi.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017 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 + * 2017-06-05 tanek first implementation. + * 2018-04-19 misonyo Porting for gd32f30x + */ + +#include "drv_spi.h" +#include "gd32e230.h" +#include + +#if defined(RT_USING_SPI) && defined(RT_USING_PIN) +#include + +#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) && \ + !defined(RT_USING_SPI2) +#error "Please define at least one SPIx" +#endif + +/* #define DEBUG */ +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +/* private rt-thread spi ops function */ +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration); +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message); + +static struct rt_spi_ops gd32_spi_ops = +{ + configure, + xfer +}; + +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration) +{ + spi_parameter_struct spi_init_struct; + + rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + if(configuration->data_width <= 8) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; + } + else if(configuration->data_width <= 16) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; + } + else + { + return RT_EIO; + } + + { + rcu_clock_freq_enum spi_src; + rt_uint32_t spi_apb_clock; + rt_uint32_t max_hz; + + max_hz = configuration->max_hz; + + DEBUG_PRINTF("sys freq: %d\n", rcu_clock_freq_get(CK_SYS)); + DEBUG_PRINTF("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2)); + DEBUG_PRINTF("max freq: %d\n", max_hz); + + if (spi_periph == SPI1) + { + spi_src = CK_APB1; + } + else + { + spi_src = CK_APB2; + } + spi_apb_clock = rcu_clock_freq_get(spi_src); + + if(max_hz >= spi_apb_clock/2) + { + spi_init_struct.prescale = SPI_PSC_2; + } + else if (max_hz >= spi_apb_clock/4) + { + spi_init_struct.prescale = SPI_PSC_4; + } + else if (max_hz >= spi_apb_clock/8) + { + spi_init_struct.prescale = SPI_PSC_8; + } + else if (max_hz >= spi_apb_clock/16) + { + spi_init_struct.prescale = SPI_PSC_16; + } + else if (max_hz >= spi_apb_clock/32) + { + spi_init_struct.prescale = SPI_PSC_32; + } + else if (max_hz >= spi_apb_clock/64) + { + spi_init_struct.prescale = SPI_PSC_64; + } + else if (max_hz >= spi_apb_clock/128) + { + spi_init_struct.prescale = SPI_PSC_128; + } + else + { + /* min prescaler 256 */ + spi_init_struct.prescale = SPI_PSC_256; + } + } /* baudrate */ + + switch(configuration->mode & RT_SPI_MODE_3) + { + case RT_SPI_MODE_0: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + break; + case RT_SPI_MODE_1: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; + break; + case RT_SPI_MODE_2: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; + break; + case RT_SPI_MODE_3: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + break; + } + + /* MSB or LSB */ + if(configuration->mode & RT_SPI_MSB) + { + spi_init_struct.endian = SPI_ENDIAN_MSB; + } + else + { + spi_init_struct.endian = SPI_ENDIAN_LSB; + } + + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER; + spi_init_struct.nss = SPI_NSS_SOFT; + + spi_init(spi_periph, &spi_init_struct); + + spi_crc_off(spi_periph); + + spi_enable(spi_periph); + + return RT_EOK; +}; + +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) +{ + rt_base_t gd32_cs_pin = (rt_base_t)device->parent.user_data; + rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data; + struct rt_spi_configuration * config = &device->config; + + RT_ASSERT(device != NULL); + RT_ASSERT(message != NULL); + + /* take CS */ + if(message->cs_take) + { + rt_pin_write(gd32_cs_pin, PIN_LOW); + DEBUG_PRINTF("spi take cs\n"); + } + + { + if(config->data_width <= 8) + { + const rt_uint8_t * send_ptr = message->send_buf; + rt_uint8_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + DEBUG_PRINTF("spi poll transfer start: %d\n", size); + + while(size--) + { + rt_uint8_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + // Todo: replace register read/write by gd32f3 lib + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + DEBUG_PRINTF("spi poll transfer finsh\n"); + } + else if(config->data_width <= 16) + { + const rt_uint16_t * send_ptr = message->send_buf; + rt_uint16_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + while(size--) + { + rt_uint16_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + } + + /* release CS */ + if(message->cs_release) + { + rt_pin_write(gd32_cs_pin, PIN_HIGH); + DEBUG_PRINTF("spi release cs\n"); + } + + return message->length; +}; + +int gd32_hw_spi_init(void) +{ + int result = 0; +#ifdef RT_USING_SPI0 + static struct rt_spi_bus spi_bus0; + spi_bus0.parent.user_data = (void *)SPI0; + + result = rt_spi_bus_register(&spi_bus0, "spi0", &gd32_spi_ops); + + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_SPI0); + /* SPI0_SCK(PA5), SPI0_MISO(PA6) and SPI0_MOSI(PA7) GPIO pin configuration */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7); + gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_7); +#endif +#ifdef RT_USING_SPI1 + static struct rt_spi_bus spi_bus1; + spi_bus1.parent.user_data = (void *)SPI1; + + result = rt_spi_bus_register(&spi_bus1, "spi1", &gd32_spi_ops); + + rcu_periph_clock_enable(RCU_SPI1); + rcu_periph_clock_enable(RCU_GPIOB); + + /* SPI1_SCK(PB13), SPI1_MISO(PB14) and SPI1_MOSI(PB15) GPIO pin configuration */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15); + gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_14); +#endif + return result; +} +INIT_BOARD_EXPORT(gd32_hw_spi_init); +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_spi.h b/bsp/gd32e230k-start/drivers/drv_spi.h new file mode 100644 index 0000000000..69b07b70af --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_spi.h @@ -0,0 +1,19 @@ +/* + * File : gd32f30x_spi.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-01 aozima first implementation. + */ + +#ifndef gd32F30X_SPI_H_INCLUDED +#define gd32F30X_SPI_H_INCLUDED + + +#endif // gd32F30X_SPI_H_INCLUDED diff --git a/bsp/gd32e230k-start/drivers/drv_usart.c b/bsp/gd32e230k-start/drivers/drv_usart.c new file mode 100644 index 0000000000..c34ca232cb --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_usart.c @@ -0,0 +1,381 @@ +/* + * File : drv_usart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + * 2018-04-19 misonyo Porting for gd32f30x + */ + +#include +#include +#include +#include "gd32e230.h" + +#ifdef RT_USING_SERIAL + +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \ + !defined(RT_USING_USART2) && !defined(RT_USING_UART3) && \ + !defined(RT_USING_UART4) +#error "Please define at least one UARTx" + +#endif + +#include + +/* GD32 uart driver */ +// Todo: compress uart info +struct gd32_uart +{ + uint32_t uart_periph; + IRQn_Type irqn; + rcu_periph_enum per_clk; + rcu_periph_enum tx_gpio_clk; + rcu_periph_enum rx_gpio_clk; + uint32_t tx_port; + uint16_t tx_pin; + uint32_t rx_port; + uint16_t rx_pin; + + struct rt_serial_device * serial; + char *device_name; +}; + +static void uart_isr(struct rt_serial_device *serial); + +#if defined(RT_USING_USART0) +struct rt_serial_device serial0; + +void USART0_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial0); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_USART0 */ + +#if defined(RT_USING_USART1) +struct rt_serial_device serial1; + +void USART1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial1); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART1 */ + +#if defined(RT_USING_USART2) +struct rt_serial_device serial2; + +void USART2_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial2); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART2 */ + +#if defined(RT_USING_UART3) +struct rt_serial_device serial3; + +void UART3_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial3); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART3 */ + +#if defined(RT_USING_UART4) +struct rt_serial_device serial4; + +void UART4_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial4); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* RT_USING_UART4 */ + +static const struct gd32_uart uarts[] = { + #ifdef RT_USING_USART0 + { + USART0, // uart peripheral index + USART0_IRQn, // uart iqrn + RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_PIN_9, // tx port, tx pin + GPIOA, GPIO_PIN_10, // rx port, rx pin + &serial0, + "uart0", + }, + #endif + + #ifdef RT_USING_USART1 + { + USART1, // uart peripheral index + USART1_IRQn, // uart iqrn + RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_PIN_2, // tx port, tx pin + GPIOA, GPIO_PIN_3, // rx port, rx pin + &serial1, + "uart1", + }, + #endif + + #ifdef RT_USING_USART2 + { + USART2, // uart peripheral index + USART2_IRQn, // uart iqrn + RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock + GPIOB, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOB, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial2, + "uart2", + }, + #endif + + #ifdef RT_USING_UART3 + { + UART3, // uart peripheral index + UART3_IRQn, // uart iqrn + RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOC, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial3, + "uart3", + }, + #endif + + #ifdef RT_USING_UART4 + { + UART4, // uart peripheral index + UART4_IRQn, // uart iqrn + RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_PIN_12, // tx port, tx alternate, tx pin + GPIOD, GPIO_PIN_2, // rx port, rx alternate, rx pin + &serial4, + "uart4", + }, + #endif +}; + + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example: +* - Peripheral's clock enable +* - Peripheral's GPIO Configuration +* - NVIC configuration for UART interrupt request enable +* @param uart: UART handle pointer +* @retval None +*/ +void gd32_uart_gpio_init(struct gd32_uart *uart) +{ + /* enable USART clock */ + rcu_periph_clock_enable(uart->tx_gpio_clk); + rcu_periph_clock_enable(uart->rx_gpio_clk); + rcu_periph_clock_enable(uart->per_clk); + + /* connect port to USARTx_Tx */ + gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, uart->tx_pin); + gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin); + + /* connect port to USARTx_Rx */ + gpio_mode_set(uart->rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, uart->rx_pin); + + NVIC_SetPriority(uart->irqn, 0); + NVIC_EnableIRQ(uart->irqn); +} + +static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct gd32_uart *)serial->parent.user_data; + + gd32_uart_gpio_init(uart); + + usart_baudrate_set(uart->uart_periph, cfg->baud_rate); + + switch (cfg->data_bits) + { + case DATA_BITS_9: + usart_word_length_set(uart->uart_periph, USART_WL_9BIT); + break; + + default: + usart_word_length_set(uart->uart_periph, USART_WL_8BIT); + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + usart_parity_config(uart->uart_periph, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(uart->uart_periph, USART_PM_EVEN); + break; + default: + usart_parity_config(uart->uart_periph, USART_PM_NONE); + break; + } + + usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); + usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); + usart_enable(uart->uart_periph); + + return RT_EOK; +} + +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irqn); + /* disable interrupt */ + usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE); + + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irqn); + /* enable interrupt */ + usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE); + break; + } + + return RT_EOK; +} + +static int gd32_putc(struct rt_serial_device *serial, char ch) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + usart_data_transmit(uart->uart_periph, ch); + while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); + + return 1; +} + +static int gd32_getc(struct rt_serial_device *serial) +{ + int ch; + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + ch = -1; + if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) + ch = usart_data_receive(uart->uart_periph); + return ch; +} + +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* UART in mode Receiver */ + if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) && + (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear RXNE interrupt flag */ + usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); + } +} + +static const struct rt_uart_ops gd32_uart_ops = +{ + gd32_configure, + gd32_control, + gd32_putc, + gd32_getc +}; + +int gd32_hw_usart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + int i; + + for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) + { + uarts[i].serial->ops = &gd32_uart_ops; + uarts[i].serial->config = config; + + /* register UART device */ + rt_hw_serial_register(uarts[i].serial, + uarts[i].device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)&uarts[i]); + } + + return 0; +} +INIT_BOARD_EXPORT(gd32_hw_usart_init); +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_usart.h b/bsp/gd32e230k-start/drivers/drv_usart.h new file mode 100644 index 0000000000..2158016272 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_usart.h @@ -0,0 +1,19 @@ +/* + * File : drv_usart.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + */ + +#ifndef __USART_H__ +#define __USART_H__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/gd32e230_libopt.h b/bsp/gd32e230k-start/drivers/gd32e230_libopt.h new file mode 100644 index 0000000000..61010d794f --- /dev/null +++ b/bsp/gd32e230k-start/drivers/gd32e230_libopt.h @@ -0,0 +1,60 @@ +/*! + \file gd32e230_libopt.h + \brief library optional for gd32e230 + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32E230_LIBOPT_H +#define GD32E230_LIBOPT_H + +#include "gd32e230_adc.h" +#include "gd32e230_crc.h" +#include "gd32e230_dbg.h" +#include "gd32e230_dma.h" +#include "gd32e230_exti.h" +#include "gd32e230_fmc.h" +#include "gd32e230_gpio.h" +#include "gd32e230_syscfg.h" +#include "gd32e230_i2c.h" +#include "gd32e230_fwdgt.h" +#include "gd32e230_pmu.h" +#include "gd32e230_rcu.h" +#include "gd32e230_rtc.h" +#include "gd32e230_spi.h" +#include "gd32e230_timer.h" +#include "gd32e230_usart.h" +#include "gd32e230_wwdgt.h" +#include "gd32e230_misc.h" +#include "gd32e230_cmp.h" + +#endif /* GD32E230_LIBOPT_H */ diff --git a/bsp/gd32e230k-start/gd32_rom.icf b/bsp/gd32e230k-start/gd32_rom.icf new file mode 100644 index 0000000000..d6665c3649 --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0807ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + +export symbol __ICFEDIT_region_RAM_end__; + +define symbol __region_RAM1_start__ = 0x10000000; +define symbol __region_RAM1_end__ = 0x1000FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in RAM1_region { section .sram }; \ No newline at end of file diff --git a/bsp/gd32e230k-start/gd32_rom.ld b/bsp/gd32e230k-start/gd32_rom.ld new file mode 100644 index 0000000000..a017d88f4d --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.ld @@ -0,0 +1,142 @@ +/* + * linker script for GD32F30x with GNU ld + * bernard.xiong 2009-10-14 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */ + DATA (rw) : ORIGIN = 0x20000000, LENGTH = 64k /* 64KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > DATA + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/gd32e230k-start/gd32_rom.sct b/bsp/gd32e230k-start/gd32_rom.sct new file mode 100644 index 0000000000..abc5462a3f --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x000080000 { ; load region size_region + ER_IROM1 0x08000000 0x000080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00010000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/gd32e230k-start/project.uvoptx b/bsp/gd32e230k-start/project.uvoptx new file mode 100644 index 0000000000..c97d8a37d1 --- /dev/null +++ b/bsp/gd32e230k-start/project.uvoptx @@ -0,0 +1,1301 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32f30x + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\UL2V8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + + + 0 + JL2CM3 + -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Applications + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + Drivers + 1 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + drivers\board.c + board.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + drivers\drv_usart.c + drv_usart.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + drivers\drv_spi.c + drv_spi.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + drivers\drv_i2c.c + drv_i2c.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + + + GD32_Lib + 1 + 0 + 0 + 0 + + 3 + 7 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + gd32e230_adc.c + 0 + 0 + + + 3 + 8 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + gd32e230_cmp.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + gd32e230_crc.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + gd32e230_dbg.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + gd32e230_dma.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + gd32e230_exti.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + gd32e230_fmc.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + gd32e230_fwdgt.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + gd32e230_gpio.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + gd32e230_i2c.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + gd32e230_misc.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + gd32e230_pmu.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + gd32e230_rcu.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + gd32e230_rtc.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + gd32e230_spi.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + gd32e230_syscfg.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + gd32e230_timer.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + gd32e230_usart.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + gd32e230_wwdgt.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + .\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + system_gd32e230.c + 0 + 0 + + + 3 + 27 + 2 + 0 + 0 + 0 + .\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s + startup_gd32e230.s + 0 + 0 + + + + + Kernel + 1 + 0 + 0 + 0 + + 4 + 28 + 1 + 0 + 0 + 0 + ..\..\src\clock.c + clock.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + ..\..\src\components.c + components.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + ..\..\src\device.c + device.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + ..\..\src\idle.c + idle.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\src\ipc.c + ipc.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\src\irq.c + irq.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + ..\..\src\kservice.c + kservice.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + ..\..\src\mem.c + mem.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + ..\..\src\mempool.c + mempool.c + 0 + 0 + + + 4 + 37 + 1 + 0 + 0 + 0 + ..\..\src\object.c + object.c + 0 + 0 + + + 4 + 38 + 1 + 0 + 0 + 0 + ..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 4 + 39 + 1 + 0 + 0 + 0 + ..\..\src\signal.c + signal.c + 0 + 0 + + + 4 + 40 + 1 + 0 + 0 + 0 + ..\..\src\thread.c + thread.c + 0 + 0 + + + 4 + 41 + 1 + 0 + 0 + 0 + ..\..\src\timer.c + timer.c + 0 + 0 + + + + + CORTEX-M23 + 1 + 0 + 0 + 0 + + 5 + 42 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 5 + 43 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 5 + 44 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 5 + 45 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m23\cpuport.c + cpuport.c + 0 + 0 + + + 5 + 46 + 2 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m23\context_rvds.S + context_rvds.S + 0 + 0 + + + + + Filesystem + 1 + 0 + 0 + 0 + + 6 + 47 + 1 + 0 + 0 + 0 + ..\..\components\dfs\src\dfs.c + dfs.c + 0 + 0 + + + 6 + 48 + 1 + 0 + 0 + 0 + ..\..\components\dfs\src\dfs_file.c + dfs_file.c + 0 + 0 + + + 6 + 49 + 1 + 0 + 0 + 0 + ..\..\components\dfs\src\dfs_fs.c + dfs_fs.c + 0 + 0 + + + 6 + 50 + 1 + 0 + 0 + 0 + ..\..\components\dfs\src\dfs_posix.c + dfs_posix.c + 0 + 0 + + + 6 + 51 + 1 + 0 + 0 + 0 + ..\..\components\dfs\filesystems\devfs\devfs.c + devfs.c + 0 + 0 + + + 6 + 52 + 1 + 0 + 0 + 0 + ..\..\components\dfs\filesystems\elmfat\dfs_elm.c + dfs_elm.c + 0 + 0 + + + 6 + 53 + 1 + 0 + 0 + 0 + ..\..\components\dfs\filesystems\elmfat\ff.c + ff.c + 0 + 0 + + + + + DeviceDrivers + 1 + 0 + 0 + 0 + + 7 + 54 + 1 + 0 + 0 + 0 + ..\..\components\drivers\i2c\i2c_core.c + i2c_core.c + 0 + 0 + + + 7 + 55 + 1 + 0 + 0 + 0 + ..\..\components\drivers\i2c\i2c_dev.c + i2c_dev.c + 0 + 0 + + + 7 + 56 + 1 + 0 + 0 + 0 + ..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 7 + 57 + 1 + 0 + 0 + 0 + ..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 7 + 58 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\spi_core.c + spi_core.c + 0 + 0 + + + 7 + 59 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\spi_dev.c + spi_dev.c + 0 + 0 + + + 7 + 60 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 7 + 61 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 7 + 62 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 7 + 63 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 7 + 64 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 7 + 65 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 8 + 66 + 1 + 0 + 0 + 0 + ..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 8 + 67 + 1 + 0 + 0 + 0 + ..\..\components\finsh\symbol.c + symbol.c + 0 + 0 + + + 8 + 68 + 1 + 0 + 0 + 0 + ..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 8 + 69 + 1 + 0 + 0 + 0 + ..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + 8 + 70 + 1 + 0 + 0 + 0 + ..\..\components\finsh\msh_cmd.c + msh_cmd.c + 0 + 0 + + + 8 + 71 + 1 + 0 + 0 + 0 + ..\..\components\finsh\msh_file.c + msh_file.c + 0 + 0 + + + 8 + 72 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_compiler.c + finsh_compiler.c + 0 + 0 + + + 8 + 73 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_error.c + finsh_error.c + 0 + 0 + + + 8 + 74 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_heap.c + finsh_heap.c + 0 + 0 + + + 8 + 75 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_init.c + finsh_init.c + 0 + 0 + + + 8 + 76 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_node.c + finsh_node.c + 0 + 0 + + + 8 + 77 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_ops.c + finsh_ops.c + 0 + 0 + + + 8 + 78 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_parser.c + finsh_parser.c + 0 + 0 + + + 8 + 79 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_var.c + finsh_var.c + 0 + 0 + + + 8 + 80 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_vm.c + finsh_vm.c + 0 + 0 + + + 8 + 81 + 1 + 0 + 0 + 0 + ..\..\components\finsh\finsh_token.c + finsh_token.c + 0 + 0 + + + + + libc + 0 + 0 + 0 + 0 + + 9 + 82 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\libc.c + libc.c + 0 + 0 + + + 9 + 83 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\libc_syms.c + libc_syms.c + 0 + 0 + + + 9 + 84 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\mem_std.c + mem_std.c + 0 + 0 + + + 9 + 85 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\stdio.c + stdio.c + 0 + 0 + + + 9 + 86 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\stubs.c + stubs.c + 0 + 0 + + + 9 + 87 + 1 + 0 + 0 + 0 + ..\..\components\libc\compilers\armlibc\time.c + time.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/bsp/gd32e230k-start/project.uvprojx b/bsp/gd32e230k-start/project.uvprojx new file mode 100644 index 0000000000..66d282d567 --- /dev/null +++ b/bsp/gd32e230k-start/project.uvprojx @@ -0,0 +1,952 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f30x + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 6120000::V6.12::.\ARMCLANG + 1 + + + GD32E230K8 + GigaDevice + GigaDevice.GD32E230_DFP.1.0.0 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian + IRAM(0x20000000,0x0002000) IROM(0x08000000,0x0010000) CPUTYPE("Cortex-M23") CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + 0 + $$Device:GD32E230K8$Device\Include\gd32e230.h + + + + + + + + + + $$Device:GD32E230K8$SVD\GD32E230.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f30x + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM23 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M23" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 3 + 3 + 1 + 1 + 0 + 0 + 0 + + + GD32E230, RT_USING_ARM_LIBC + + applications;.;drivers;Libraries\CMSIS;..\..\include;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\spi;..\..\components\drivers\include;..\..\components\drivers\spi\sfud\inc;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\armlibc;.\Libraries\GD32E230_standard_peripheral\Include;.\Libraries\CMSIS\GD\GD32E230\Include;..\..\libcpu\arm\cortex-m23 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + Drivers + + + board.c + 1 + drivers\board.c + + + drv_usart.c + 1 + drivers\drv_usart.c + + + drv_spi.c + 1 + drivers\drv_spi.c + + + drv_i2c.c + 1 + drivers\drv_i2c.c + + + drv_gpio.c + 1 + drivers\drv_gpio.c + + + + + GD32_Lib + + + gd32e230_adc.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + + + gd32e230_cmp.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + + + gd32e230_crc.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + + + gd32e230_dbg.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + + + gd32e230_dma.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + + + gd32e230_exti.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + + + gd32e230_fmc.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + + + gd32e230_fwdgt.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + + + gd32e230_gpio.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + + + gd32e230_i2c.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + + + gd32e230_misc.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + + + gd32e230_pmu.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + + + gd32e230_rcu.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + + + gd32e230_rtc.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + + + gd32e230_spi.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + + + gd32e230_syscfg.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + + + gd32e230_timer.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + + + gd32e230_usart.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + + + gd32e230_wwdgt.c + 1 + .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + + + system_gd32e230.c + 1 + .\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + + + startup_gd32e230.s + 2 + .\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s + + + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c + + + components.c + 1 + ..\..\src\components.c + + + device.c + 1 + ..\..\src\device.c + + + idle.c + 1 + ..\..\src\idle.c + + + ipc.c + 1 + ..\..\src\ipc.c + + + irq.c + 1 + ..\..\src\irq.c + + + kservice.c + 1 + ..\..\src\kservice.c + + + mem.c + 1 + ..\..\src\mem.c + + + mempool.c + 1 + ..\..\src\mempool.c + + + object.c + 1 + ..\..\src\object.c + + + scheduler.c + 1 + ..\..\src\scheduler.c + + + signal.c + 1 + ..\..\src\signal.c + + + thread.c + 1 + ..\..\src\thread.c + + + timer.c + 1 + ..\..\src\timer.c + + + + + CORTEX-M23 + + + backtrace.c + 1 + ..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\libcpu\arm\common\showmem.c + + + cpuport.c + 1 + ..\..\libcpu\arm\cortex-m23\cpuport.c + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m23\context_rvds.S + + + + + Filesystem + + + dfs.c + 1 + ..\..\components\dfs\src\dfs.c + + + dfs_file.c + 1 + ..\..\components\dfs\src\dfs_file.c + + + dfs_fs.c + 1 + ..\..\components\dfs\src\dfs_fs.c + + + dfs_posix.c + 1 + ..\..\components\dfs\src\dfs_posix.c + + + devfs.c + 1 + ..\..\components\dfs\filesystems\devfs\devfs.c + + + dfs_elm.c + 1 + ..\..\components\dfs\filesystems\elmfat\dfs_elm.c + + + ff.c + 1 + ..\..\components\dfs\filesystems\elmfat\ff.c + + + + + DeviceDrivers + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + i2c_core.c + 1 + ..\..\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\components\drivers\i2c\i2c_dev.c + + + pin.c + 1 + ..\..\components\drivers\misc\pin.c + + + serial.c + 1 + ..\..\components\drivers\serial\serial.c + + + spi_core.c + 1 + ..\..\components\drivers\spi\spi_core.c + + + spi_dev.c + 1 + ..\..\components\drivers\spi\spi_dev.c + + + completion.c + 1 + ..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\components\drivers\src\pipe.c + + + ringbuffer.c + 1 + ..\..\components\drivers\src\ringbuffer.c + + + waitqueue.c + 1 + ..\..\components\drivers\src\waitqueue.c + + + workqueue.c + 1 + ..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\components\finsh\shell.c + + + symbol.c + 1 + ..\..\components\finsh\symbol.c + + + cmd.c + 1 + ..\..\components\finsh\cmd.c + + + msh.c + 1 + ..\..\components\finsh\msh.c + + + msh_cmd.c + 1 + ..\..\components\finsh\msh_cmd.c + + + msh_file.c + 1 + ..\..\components\finsh\msh_file.c + + + finsh_compiler.c + 1 + ..\..\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\components\finsh\finsh_token.c + + + + + libc + + + libc.c + 1 + ..\..\components\libc\compilers\armlibc\libc.c + + + libc_syms.c + 1 + ..\..\components\libc\compilers\armlibc\libc_syms.c + + + mem_std.c + 1 + ..\..\components\libc\compilers\armlibc\mem_std.c + + + stdio.c + 1 + ..\..\components\libc\compilers\armlibc\stdio.c + + + stubs.c + 1 + ..\..\components\libc\compilers\armlibc\stubs.c + + + time.c + 1 + ..\..\components\libc\compilers\armlibc\time.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/bsp/gd32e230k-start/rtconfig.h b/bsp/gd32e230k-start/rtconfig.h new file mode 100644 index 0000000000..77e9056395 --- /dev/null +++ b/bsp/gd32e230k-start/rtconfig.h @@ -0,0 +1,158 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_DEBUG +#define RT_DEBUG_COLOR +#define RT_USING_OVERFLOW_CHECK +#define RT_DEBUG_INIT 0 +#define RT_DEBUG_THREAD 0 +#define RT_USING_HOOK +#define IDLE_THREAD_STACK_SIZE 256 + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart0" + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 + +/* C++ features */ + + +/* 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_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT + +/* Device virtual file system */ + +#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 + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_0 +#define RT_DFS_ELM_USE_LFN 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +#define RT_DFS_ELM_REENTRANT +#define RT_USING_DFS_DEVFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_USING_I2C +#define RT_USING_PIN +#define RT_USING_SPI + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC + +/* Network stack */ + +/* light weight TCP/IP stack */ + + +/* Modbus master and slave stack */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* system packages */ + +/* RT-Thread GUI Engine */ + + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* miscellaneous packages */ + + +/* example package: hello */ + +#define RT_USING_USART0 +#define RT_USING_USART1 +#define RT_USING_SPI0 +#define RT_USING_SPI1 +#define RT_USING_I2C0 + +#endif diff --git a/bsp/gd32e230k-start/rtconfig.py b/bsp/gd32e230k-start/rtconfig.py new file mode 100644 index 0000000000..c631bc3e44 --- /dev/null +++ b/bsp/gd32e230k-start/rtconfig.py @@ -0,0 +1,126 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='keil' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'D:/toolchain/gnu_tools_arm_embedded/5.4_2016q3/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # tool-chains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -Dgcc' # -D' + PART_TYPE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-gd32.map,-cref,-u,Reset_Handler -T gd32_rom.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-gd32.map --scatter gd32_rom.sct' + + LFLAGS += ' --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab)' + + EXEC_PATH += '/ARM/ARMCC/bin' + print(EXEC_PATH) + + CFLAGS += ' --c99' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = ' -D USE_STDPERIPH_DRIVER' + ' -D GD32F30X_HD' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --debug' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M4' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' -Ol' + CFLAGS += ' --use_c++_inline' + + AFLAGS = '' + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M4' + AFLAGS += ' --fpu None' + + LFLAGS = ' --config gd32_rom.icf' + LFLAGS += ' --redirect _Printf=_PrintfTiny' + LFLAGS += ' --redirect _Scanf=_ScanfSmall' + LFLAGS += ' --entry __iar_program_start' + + EXEC_PATH += '/arm/bin/' + POST_ACTION = '' + diff --git a/bsp/gd32e230k-start/template.uvoptx b/bsp/gd32e230k-start/template.uvoptx new file mode 100644 index 0000000000..8fc841b0e1 --- /dev/null +++ b/bsp/gd32e230k-start/template.uvoptx @@ -0,0 +1,185 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32f30x + 0x4 + ARM-ADS + + 16000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 4 + + + + + + + + + + + Segger\JL2CM3.dll + + + + 0 + JL2CM3 + -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL010000 -FP0($$Device:GD32F303ZE$Flash\GD32F30x_HD.FLM)) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/bsp/gd32e230k-start/template.uvprojx b/bsp/gd32e230k-start/template.uvprojx new file mode 100644 index 0000000000..9b0a830d22 --- /dev/null +++ b/bsp/gd32e230k-start/template.uvprojx @@ -0,0 +1,400 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f30x + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + GD32F303ZE + GigaDevice + GigaDevice.GD32F30x_DFP.1.0.1 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian + IRAM(0x20000000-0x2000FFFF)IROM(0x08000000-0x0807FFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") + + "Startup\GD\GD32F30x\startup_gd32f30x_hd.s" ("GD32F30x Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000) + 0 + gd32f30x.h + + + + + + + + + + SFD\GD\GD32F30x\GD32F30x_HD.SFR + 0 + 0 + + + + GD\GD32F30x\ + GD\GD32F30x\ + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f30x + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + applications;.;drivers;Libraries\CMSIS\GD\GD32F30x\Include;Libraries\CMSIS;Libraries\GD32F30x_standard_peripheral\Include;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --keep *.o(RTMSymTab) --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/libcpu/arm/cortex-m23/SConscript b/libcpu/arm/cortex-m23/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/cortex-m23/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S new file mode 100644 index 0000000000..d17a8aa12c --- /dev/null +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-10-11 Bernard First version + * 2010-12-29 onelife Modify for EFM32 + * 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S + * 2011-07-12 onelife Add interrupt context check function + * 2013-06-18 aozima add restore MSP feature. + * 2013-07-09 aozima enhancement hard fault exception handler. + */ + + .cpu cortex-m3 + .fpu softvfp + .syntax unified + .thumb + .text + + .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ + .equ ICSR, 0xE000ED04 /* interrupt control state register */ + .equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */ + + .equ SHPR3, 0xE000ED20 /* system priority register (3) */ + .equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */ + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ + .global rt_hw_interrupt_disable + .type rt_hw_interrupt_disable, %function +rt_hw_interrupt_disable: + MRS R0, PRIMASK + CPSID I + BX LR + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ + .global rt_hw_interrupt_enable + .type rt_hw_interrupt_enable, %function +rt_hw_interrupt_enable: + MSR PRIMASK, R0 + BX LR + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * R0 --> from + * R1 --> to + */ + .global rt_hw_context_switch_interrupt + .type rt_hw_context_switch_interrupt, %function + .global rt_hw_context_switch + .type rt_hw_context_switch, %function +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + /* set rt_thread_switch_interrupt_flag to 1 */ + LDR R2, =rt_thread_switch_interrupt_flag + LDR R3, [R2] + CMP R3, #1 + BEQ _reswitch + MOV R3, #1 + STR R3, [R2] + + LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ + STR R0, [R2] + +_reswitch: + LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ + STR R1, [R2] + + LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ + LDR R1, =PENDSVSET_BIT + STR R1, [R0] + BX LR + +/* R0 --> switch from thread stack + * R1 --> switch to thread stack + * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack + */ + .global PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + /* disable interrupt to protect context switch */ + MRS R2, PRIMASK + CPSID I + + /* get rt_thread_switch_interrupt_flag */ + LDR R0, =rt_thread_switch_interrupt_flag + LDR R1, [R0] + CBZ R1, pendsv_exit /* pendsv aLReady handled */ + + /* clear rt_thread_switch_interrupt_flag to 0 */ + MOV R1, #0 + STR R1, [R0] + + LDR R0, =rt_interrupt_from_thread + LDR R1, [R0] + CBZ R1, switch_to_thread /* skip register save at the first time */ + + MRS R1, PSP /* get from thread stack pointer */ + STMFD R1!, {R4 - R11} /* push R4 - R11 register */ + LDR R0, [R0] + STR R1, [R0] /* update from thread stack pointer */ + +switch_to_thread: + LDR R1, =rt_interrupt_to_thread + LDR R1, [R1] + LDR R1, [R1] /* load thread stack pointer */ + + LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */ + MSR PSP, R1 /* update stack pointer */ + +pendsv_exit: + /* restore interrupt */ + MSR PRIMASK, R2 + + ORR LR, LR, #0x04 + BX LR + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * R0 --> to + */ + .global rt_hw_context_switch_to + .type rt_hw_context_switch_to, %function +rt_hw_context_switch_to: + LDR R1, =rt_interrupt_to_thread + STR R0, [R1] + + /* set from thread to 0 */ + LDR R1, =rt_interrupt_from_thread + MOV R0, #0 + STR R0, [R1] + + /* set interrupt flag to 1 */ + LDR R1, =rt_thread_switch_interrupt_flag + MOV R0, #1 + STR R0, [R1] + + /* set the PendSV exception priority */ + LDR R0, =SHPR3 + LDR R1, =PENDSV_PRI_LOWEST + LDR.W R2, [R0,#0] /* read */ + ORR R1, R1, R2 /* modify */ + STR R1, [R0] /* write-back */ + + LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ + LDR R1, =PENDSVSET_BIT + STR R1, [R0] + + /* restore MSP */ + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + NOP + MSR msp, r0 + + /* enable interrupts at processor level */ + CPSIE F + CPSIE I + + /* never reach here! */ + +/* compatible with old version */ + .global rt_hw_interrupt_thread_switch + .type rt_hw_interrupt_thread_switch, %function +rt_hw_interrupt_thread_switch: + BX LR + NOP + + .global HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + /* get current context */ + MRS r0, msp /* get fault context from handler. */ + TST lr, #0x04 /* if(!EXC_RETURN[2]) */ + BEQ _get_sp_done + MRS r0, psp /* get fault context from thread. */ +_get_sp_done: + + STMFD r0!, {r4 - r11} /* push r4 - r11 register */ + STMFD r0!, {lr} /* push exec_return register */ + + TST lr, #0x04 /* if(!EXC_RETURN[2]) */ + BEQ _update_msp + MSR psp, r0 /* update stack pointer to PSP. */ + B _update_done +_update_msp: + MSR msp, r0 /* update stack pointer to MSP. */ +_update_done: + + PUSH {LR} + BL rt_hw_hard_fault_exception + POP {LR} + + ORR LR, LR, #0x04 + BX LR + +/* + * rt_uint32_t rt_hw_interrupt_check(void); + * R0 --> state + */ + .global rt_hw_interrupt_check + .type rt_hw_interrupt_check, %function +rt_hw_interrupt_check: + MRS R0, IPSR + BX LR diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S new file mode 100644 index 0000000000..91645c48b3 --- /dev/null +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -0,0 +1,202 @@ +;/* +; * Copyright (c) 2006-2018, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2009-01-17 Bernard first version +; * 2009-09-27 Bernard add protect when contex switch occurs +; * 2013-06-18 aozima add restore MSP feature. +; * 2013-07-09 aozima enhancement hard fault exception handler. +; */ + +;/** +; * @addtogroup cortex-m3 +; */ +;/*@{*/ + +SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register +NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register +NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) +NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception + + SECTION .text:CODE(2) + THUMB + REQUIRE8 + PRESERVE8 + + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ + EXPORT rt_hw_interrupt_disable +rt_hw_interrupt_disable: + MRS r0, PRIMASK + CPSID I + BX LR + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ + EXPORT rt_hw_interrupt_enable +rt_hw_interrupt_enable: + MSR PRIMASK, r0 + BX LR + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ + EXPORT rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + ; set rt_thread_switch_interrupt_flag to 1 + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 + STR r3, [r2] + + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] + +_reswitch + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + BX LR + +; r0 --> switch from thread stack +; r1 --> switch to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack + EXPORT PendSV_Handler +PendSV_Handler: + + ; disable interrupt to protect context switch + MRS r2, PRIMASK + CPSID I + + ; get rt_thread_switch_interrupt_flag + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CBZ r1, pendsv_exit ; pendsv already handled + + ; clear rt_thread_switch_interrupt_flag to 0 + MOV r1, #0x00 + STR r1, [r0] + + LDR r0, =rt_interrupt_from_thread + LDR r1, [r0] + CBZ r1, switch_to_thread ; skip register save at the first time + + MRS r1, psp ; get from thread stack pointer + STMFD r1!, {r4 - r11} ; push r4 - r11 register + LDR r0, [r0] + STR r1, [r0] ; update from thread stack pointer + +switch_to_thread + LDR r1, =rt_interrupt_to_thread + LDR r1, [r1] + LDR r1, [r1] ; load thread stack pointer + + LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + MSR psp, r1 ; update stack pointer + +pendsv_exit + ; restore interrupt + MSR PRIMASK, r2 + + ORR lr, lr, #0x04 + BX lr + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; */ + EXPORT rt_hw_context_switch_to +rt_hw_context_switch_to: + LDR r1, =rt_interrupt_to_thread + STR r0, [r1] + + ; set from thread to 0 + LDR r1, =rt_interrupt_from_thread + MOV r0, #0x0 + STR r0, [r1] + + ; set interrupt flag to 1 + LDR r1, =rt_thread_switch_interrupt_flag + MOV r0, #1 + STR r0, [r1] + + ; set the PendSV exception priority + LDR r0, =NVIC_SYSPRI2 + LDR r1, =NVIC_PENDSV_PRI + LDR.W r2, [r0,#0x00] ; read + ORR r1,r1,r2 ; modify + STR r1, [r0] ; write-back + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + + ; restore MSP + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + NOP + MSR msp, r0 + + ; enable interrupts at processor level + CPSIE F + CPSIE I + + ; never reach here! + +; compatible with old version + EXPORT rt_hw_interrupt_thread_switch +rt_hw_interrupt_thread_switch: + BX lr + + IMPORT rt_hw_hard_fault_exception + EXPORT HardFault_Handler +HardFault_Handler: + + ; get current context + MRS r0, msp ; get fault context from handler. + TST lr, #0x04 ; if(!EXC_RETURN[2]) + BEQ _get_sp_done + MRS r0, psp ; get fault context from thread. +_get_sp_done + + STMFD r0!, {r4 - r11} ; push r4 - r11 register + ;STMFD r0!, {lr} ; push exec_return register + SUB r0, r0, #0x04 + STR lr, [r0] + + TST lr, #0x04 ; if(!EXC_RETURN[2]) + BEQ _update_msp + MSR psp, r0 ; update stack pointer to PSP. + B _update_done +_update_msp + MSR msp, r0 ; update stack pointer to MSP. +_update_done + + PUSH {lr} + BL rt_hw_hard_fault_exception + POP {lr} + + ORR lr, lr, #0x04 + BX lr + + END diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S new file mode 100644 index 0000000000..c0a2130703 --- /dev/null +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -0,0 +1,207 @@ +;/* +; * Copyright (c) 2006-2018, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2009-01-17 Bernard first version +; * 2013-06-18 aozima add restore MSP feature. +; * 2013-07-09 aozima enhancement hard fault exception handler. +; */ + +;/** +; * @addtogroup CORTEX-M23 +; */ +;/*@{*/ + +SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register +NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register +NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) +NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception + + AREA |.text|, CODE, READONLY, ALIGN=2 + THUMB + REQUIRE8 + PRESERVE8 + + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ +rt_hw_interrupt_disable PROC + EXPORT rt_hw_interrupt_disable + MRS r0, PRIMASK + CPSID I + BX LR + ENDP + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ +rt_hw_interrupt_enable PROC + EXPORT rt_hw_interrupt_enable + MSR PRIMASK, r0 + BX LR + ENDP + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ +rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch_interrupt +rt_hw_context_switch PROC + EXPORT rt_hw_context_switch + + ; set rt_thread_switch_interrupt_flag to 1 + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 + STR r3, [r2] + + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] + +_reswitch + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + BX LR + ENDP + +; r0 --> switch from thread stack +; r1 --> switch to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack +PendSV_Handler PROC + EXPORT PendSV_Handler + + ; disable interrupt to protect context switch + MRS r2, PRIMASK + CPSID I + + ; get rt_thread_switch_interrupt_flag + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CBZ r1, pendsv_exit ; pendsv already handled + + ; clear rt_thread_switch_interrupt_flag to 0 + MOV r1, #0x00 + STR r1, [r0] + + LDR r0, =rt_interrupt_from_thread + LDR r1, [r0] + CBZ r1, switch_to_thread ; skip register save at the first time + + MRS r1, psp ; get from thread stack pointer + STMFD r1!, {r4 - r11} ; push r4 - r11 register + LDR r0, [r0] + STR r1, [r0] ; update from thread stack pointer + +switch_to_thread + LDR r1, =rt_interrupt_to_thread + LDR r1, [r1] + LDR r1, [r1] ; load thread stack pointer + + LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + MSR psp, r1 ; update stack pointer + +pendsv_exit + ; restore interrupt + MSR PRIMASK, r2 + + ORR lr, lr, #0x04 + BX lr + ENDP + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; * this fucntion is used to perform the first thread switch +; */ +rt_hw_context_switch_to PROC + EXPORT rt_hw_context_switch_to + ; set to thread + LDR r1, =rt_interrupt_to_thread + STR r0, [r1] + + ; set from thread to 0 + LDR r1, =rt_interrupt_from_thread + MOV r0, #0x0 + STR r0, [r1] + + ; set interrupt flag to 1 + LDR r1, =rt_thread_switch_interrupt_flag + MOV r0, #1 + STR r0, [r1] + + ; set the PendSV exception priority + LDR r0, =NVIC_SYSPRI2 + LDR r1, =NVIC_PENDSV_PRI + LDR.W r2, [r0,#0x00] ; read + ORR r1,r1,r2 ; modify + STR r1, [r0] ; write-back + + ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + + ; restore MSP + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + MSR msp, r0 + + ; enable interrupts at processor level + CPSIE F + CPSIE I + + ; never reach here! + ENDP + +; compatible with old version +rt_hw_interrupt_thread_switch PROC + EXPORT rt_hw_interrupt_thread_switch + BX lr + ENDP + + IMPORT rt_hw_hard_fault_exception + EXPORT HardFault_Handler +HardFault_Handler PROC + + ; get current context + TST lr, #0x04 ; if(!EXC_RETURN[2]) + ITE EQ + MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler. + MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread. + + STMFD r0!, {r4 - r11} ; push r4 - r11 register + STMFD r0!, {lr} ; push exec_return register + + TST lr, #0x04 ; if(!EXC_RETURN[2]) + ITE EQ + MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP. + MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP. + + PUSH {lr} + BL rt_hw_hard_fault_exception + POP {lr} + + ORR lr, lr, #0x04 + BX lr + ENDP + + ALIGN 4 + + END diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c new file mode 100644 index 0000000000..a386747750 --- /dev/null +++ b/libcpu/arm/cortex-m23/cpuport.c @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first version + * 2011-02-14 onelife Modify for EFM32 + * 2011-06-17 onelife Merge all of the C source code into cpuport.c + * 2012-12-23 aozima stack addr align to 8byte. + * 2012-12-29 Bernard Add exception hook. + * 2013-07-09 aozima enhancement hard fault exception handler. + */ + +#include + +struct exception_stack_frame +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r12; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t psr; +}; + +struct stack_frame +{ + /* r4 ~ r11 register */ + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t r11; + + struct exception_stack_frame exception_stack_frame; +}; + +/* flag in interrupt handling */ +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; +/* exception hook */ +static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, + rt_uint8_t *stack_addr, + void *texit) +{ + struct stack_frame *stack_frame; + rt_uint8_t *stk; + unsigned long i; + + stk = stack_addr + sizeof(rt_uint32_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); + stk -= sizeof(struct stack_frame); + + stack_frame = (struct stack_frame *)stk; + + /* init all register */ + for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) + { + ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; + } + + stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ + stack_frame->exception_stack_frame.r1 = 0; /* r1 */ + stack_frame->exception_stack_frame.r2 = 0; /* r2 */ + stack_frame->exception_stack_frame.r3 = 0; /* r3 */ + stack_frame->exception_stack_frame.r12 = 0; /* r12 */ + stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */ + stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */ + stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */ + + /* return task's current stack address */ + return stk; +} + +/** + * This function set the hook, which is invoked on fault exception handling. + * + * @param exception_handle the exception handling hook function. + */ +void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context)) +{ + rt_exception_hook = exception_handle; +} + +#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */ +#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ +#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ +#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */ +#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ + +#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ +#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */ +#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */ + +#ifdef RT_USING_FINSH +static void usage_fault_track(void) +{ + rt_kprintf("usage fault:\n"); + rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR); + + if(SCB_CFSR_UFSR & (1<<0)) + { + /* [0]:UNDEFINSTR */ + rt_kprintf("UNDEFINSTR "); + } + + if(SCB_CFSR_UFSR & (1<<1)) + { + /* [1]:INVSTATE */ + rt_kprintf("INVSTATE "); + } + + if(SCB_CFSR_UFSR & (1<<2)) + { + /* [2]:INVPC */ + rt_kprintf("INVPC "); + } + + if(SCB_CFSR_UFSR & (1<<3)) + { + /* [3]:NOCP */ + rt_kprintf("NOCP "); + } + + if(SCB_CFSR_UFSR & (1<<8)) + { + /* [8]:UNALIGNED */ + rt_kprintf("UNALIGNED "); + } + + if(SCB_CFSR_UFSR & (1<<9)) + { + /* [9]:DIVBYZERO */ + rt_kprintf("DIVBYZERO "); + } + + rt_kprintf("\n"); +} + +static void bus_fault_track(void) +{ + rt_kprintf("bus fault:\n"); + rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR); + + if(SCB_CFSR_BFSR & (1<<0)) + { + /* [0]:IBUSERR */ + rt_kprintf("IBUSERR "); + } + + if(SCB_CFSR_BFSR & (1<<1)) + { + /* [1]:PRECISERR */ + rt_kprintf("PRECISERR "); + } + + if(SCB_CFSR_BFSR & (1<<2)) + { + /* [2]:IMPRECISERR */ + rt_kprintf("IMPRECISERR "); + } + + if(SCB_CFSR_BFSR & (1<<3)) + { + /* [3]:UNSTKERR */ + rt_kprintf("UNSTKERR "); + } + + if(SCB_CFSR_BFSR & (1<<4)) + { + /* [4]:STKERR */ + rt_kprintf("STKERR "); + } + + if(SCB_CFSR_BFSR & (1<<7)) + { + rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR); + } + else + { + rt_kprintf("\n"); + } +} + +static void mem_manage_fault_track(void) +{ + rt_kprintf("mem manage fault:\n"); + rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR); + + if(SCB_CFSR_MFSR & (1<<0)) + { + /* [0]:IACCVIOL */ + rt_kprintf("IACCVIOL "); + } + + if(SCB_CFSR_MFSR & (1<<1)) + { + /* [1]:DACCVIOL */ + rt_kprintf("DACCVIOL "); + } + + if(SCB_CFSR_MFSR & (1<<3)) + { + /* [3]:MUNSTKERR */ + rt_kprintf("MUNSTKERR "); + } + + if(SCB_CFSR_MFSR & (1<<4)) + { + /* [4]:MSTKERR */ + rt_kprintf("MSTKERR "); + } + + if(SCB_CFSR_MFSR & (1<<7)) + { + /* [7]:MMARVALID */ + rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR); + } + else + { + rt_kprintf("\n"); + } +} + +static void hard_fault_track(void) +{ + if(SCB_HFSR & (1UL<<1)) + { + /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */ + rt_kprintf("failed vector fetch\n"); + } + + if(SCB_HFSR & (1UL<<30)) + { + /* [30]:FORCED, Indicates hard fault is taken because of bus fault, + memory management fault, or usage fault. */ + if(SCB_CFSR_BFSR) + { + bus_fault_track(); + } + + if(SCB_CFSR_MFSR) + { + mem_manage_fault_track(); + } + + if(SCB_CFSR_UFSR) + { + usage_fault_track(); + } + } + + if(SCB_HFSR & (1UL<<31)) + { + /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */ + rt_kprintf("debug event\n"); + } +} +#endif /* RT_USING_FINSH */ + +struct exception_info +{ + rt_uint32_t exc_return; + struct stack_frame stack_frame; +}; + +/* + * fault exception handler + */ +void rt_hw_hard_fault_exception(struct exception_info * exception_info) +{ + extern long list_thread(void); + struct stack_frame* context = &exception_info->stack_frame; + + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(exception_info); + if (result == RT_EOK) + return; + } + + rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr); + + rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0); + rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1); + rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2); + rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3); + rt_kprintf("r04: 0x%08x\n", context->r4); + rt_kprintf("r05: 0x%08x\n", context->r5); + rt_kprintf("r06: 0x%08x\n", context->r6); + rt_kprintf("r07: 0x%08x\n", context->r7); + rt_kprintf("r08: 0x%08x\n", context->r8); + rt_kprintf("r09: 0x%08x\n", context->r9); + rt_kprintf("r10: 0x%08x\n", context->r10); + rt_kprintf("r11: 0x%08x\n", context->r11); + rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12); + rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr); + rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc); + + if(exception_info->exc_return & (1 << 2) ) + { + rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif /* RT_USING_FINSH */ + } + else + { + rt_kprintf("hard fault on handler\r\n\r\n"); + } + +#ifdef RT_USING_FINSH + hard_fault_track(); +#endif /* RT_USING_FINSH */ + + while (1); +} + +/** + * shutdown CPU + */ +void rt_hw_cpu_shutdown(void) +{ + rt_kprintf("shutdown...\n"); + + RT_ASSERT(0); +} + +/** + * reset CPU + */ +RT_WEAK void rt_hw_cpu_reset(void) +{ + SCB_AIRCR = SCB_RESET_VALUE; +} + +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +#if defined(__CC_ARM) +__asm int __rt_ffs(int value) +{ + CMP r0, #0x00 + BEQ exit + + RBIT r0, r0 + CLZ r0, r0 + ADDS r0, r0, #0x01 + +exit + BX lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +int __rt_ffs(int value) +{ + if (value == 0) return value; + + asm("RBIT %0, %1" : "=r"(value) : "r"(value)); + asm("CLZ %0, %1" : "=r"(value) : "r"(value)); + asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); + + return value; +} +#elif defined(__GNUC__) +int __rt_ffs(int value) +{ + return __builtin_ffs(value); +} +#endif + +#endif -- cgit v1.3.1 From 5a460aadcd1df4fcfb14aafeb248230a47e9cbeb Mon Sep 17 00:00:00 2001 From: xuzhuoyi Date: Sun, 31 Mar 2019 21:17:55 +0800 Subject: [bsp][gd32e230k-start] Update Sconscript --- bsp/gd32e230k-start/Libraries/SConscript | 22 +- bsp/gd32e230k-start/SConstruct | 2 +- bsp/gd32e230k-start/drivers/SConscript | 4 - bsp/gd32e230k-start/drivers/board.h | 2 +- bsp/gd32e230k-start/project.uvoptx | 564 ++++++++++++------------------- bsp/gd32e230k-start/project.uvprojx | 318 +++++++---------- bsp/gd32e230k-start/rtconfig.h | 61 ++-- bsp/gd32e230k-start/rtconfig.py | 4 +- bsp/gd32e230k-start/template.uvoptx | 18 +- bsp/gd32e230k-start/template.uvprojx | 62 ++-- libcpu/arm/cortex-m23/context_gcc.S | 122 +++---- libcpu/arm/cortex-m23/context_iar.S | 90 ++--- libcpu/arm/cortex-m23/context_rvds.S | 84 ++--- libcpu/arm/cortex-m23/cpuport.c | 328 ++---------------- 14 files changed, 618 insertions(+), 1063 deletions(-) (limited to 'libcpu') diff --git a/bsp/gd32e230k-start/Libraries/SConscript b/bsp/gd32e230k-start/Libraries/SConscript index eb4cfb77c7..e79dc34216 100644 --- a/bsp/gd32e230k-start/Libraries/SConscript +++ b/bsp/gd32e230k-start/Libraries/SConscript @@ -6,27 +6,21 @@ cwd = GetCurrentDir() # The set of source files associated with this SConscript file. -src = Glob('GD32F30x_standard_peripheral/Source/*.c') -src += [cwd + '/CMSIS/GD/GD32F30x/Source/system_gd32f30x.c'] +src = Glob('GD32E230_standard_peripheral/Source/*.c') +src += [cwd + '/CMSIS/GD/GD32E230/Source/system_gd32e230.c'] #add for startup script -if rtconfig.CROSS_TOOL == 'gcc': - src += [cwd + '/CMSIS/GD/GD32F30x/Source/GCC/startup_gd32f30x_hd.s'] -elif rtconfig.CROSS_TOOL == 'keil': - src += [cwd + '/CMSIS/GD/GD32F30x/Source/ARM/startup_gd32f30x_hd.s'] +if rtconfig.CROSS_TOOL == 'keil': + src += [cwd + '/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s'] elif rtconfig.CROSS_TOOL == 'iar': - src += [cwd + '/CMSIS/GD/GD32F30x/Source/IAR/startup_gd32f30x_hd.s'] + src += [cwd + '/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s'] path = [ - cwd + '/CMSIS/GD/GD32F30x/Include', + cwd + '/CMSIS/GD/GD32E230/Include', cwd + '/CMSIS', - cwd + '/GD32F30x_standard_peripheral/Include',] - -if GetDepend(['RT_USING_BSP_USB']): - path += [cwd + '/GD32F30x_usb_driver/Include'] - src += [cwd + '/GD32F30x_usb_driver/Source'] + cwd + '/GD32E230_standard_peripheral/Include',] -CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F30X_HD'] +CPPDEFINES = ['GD32E230'] group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) diff --git a/bsp/gd32e230k-start/SConstruct b/bsp/gd32e230k-start/SConstruct index 1cdbaab4a8..57a8ac59fc 100644 --- a/bsp/gd32e230k-start/SConstruct +++ b/bsp/gd32e230k-start/SConstruct @@ -15,7 +15,7 @@ except: print(RTT_ROOT) exit(-1) -TARGET = 'rtthread-gd32f30x.' + rtconfig.TARGET_EXT +TARGET = 'rtthread-gd32f230.' + rtconfig.TARGET_EXT env = Environment(tools = ['mingw'], AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, diff --git a/bsp/gd32e230k-start/drivers/SConscript b/bsp/gd32e230k-start/drivers/SConscript index ef03e2dcf0..45fd672f5f 100644 --- a/bsp/gd32e230k-start/drivers/SConscript +++ b/bsp/gd32e230k-start/drivers/SConscript @@ -24,10 +24,6 @@ if GetDepend('RT_USING_I2C'): if GetDepend('RT_USING_PIN'): src += ['drv_gpio.c'] -# add spi flash drivers. -if GetDepend('RT_USING_SFUD'): - src += ['drv_spi_flash.c'] - group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/bsp/gd32e230k-start/drivers/board.h b/bsp/gd32e230k-start/drivers/board.h index de344e8768..bff43464b4 100644 --- a/bsp/gd32e230k-start/drivers/board.h +++ b/bsp/gd32e230k-start/drivers/board.h @@ -29,7 +29,7 @@ extern char __ICFEDIT_region_RAM_end__; #define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) #endif -#ifdef __CC_ARM +#ifdef __ARMCC_VERSION extern int Image$$RW_IRAM1$$ZI$$Limit; #define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) #elif __ICCARM__ diff --git a/bsp/gd32e230k-start/project.uvoptx b/bsp/gd32e230k-start/project.uvoptx index c97d8a37d1..aa084f2049 100644 --- a/bsp/gd32e230k-start/project.uvoptx +++ b/bsp/gd32e230k-start/project.uvoptx @@ -22,7 +22,7 @@ - rt-thread_gd32f30x + rt-thread_gd32e230 0x4 ARM-ADS @@ -103,7 +103,7 @@ 1 0 0 - 19 + 14 @@ -175,8 +175,8 @@ - Applications - 1 + Kernel + 0 0 0 0 @@ -187,207 +187,207 @@ 0 0 0 - applications\main.c - main.c + ..\..\src\clock.c + clock.c 0 0 - - - - Drivers - 1 - 0 - 0 - 0 - 2 + 1 2 1 0 0 0 - drivers\board.c - board.c + ..\..\src\components.c + components.c 0 0 - 2 + 1 3 1 0 0 0 - drivers\drv_usart.c - drv_usart.c + ..\..\src\cpu.c + cpu.c 0 0 - 2 + 1 4 1 0 0 0 - drivers\drv_spi.c - drv_spi.c + ..\..\src\device.c + device.c 0 0 - 2 + 1 5 1 0 0 0 - drivers\drv_i2c.c - drv_i2c.c + ..\..\src\idle.c + idle.c 0 0 - 2 + 1 6 1 0 0 0 - drivers\drv_gpio.c - drv_gpio.c + ..\..\src\ipc.c + ipc.c 0 0 - - - - GD32_Lib - 1 - 0 - 0 - 0 - 3 + 1 7 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c - gd32e230_adc.c + ..\..\src\irq.c + irq.c 0 0 - 3 + 1 8 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c - gd32e230_cmp.c + ..\..\src\kservice.c + kservice.c 0 0 - 3 + 1 9 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c - gd32e230_crc.c + ..\..\src\mem.c + mem.c 0 0 - 3 + 1 10 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c - gd32e230_dbg.c + ..\..\src\mempool.c + mempool.c 0 0 - 3 + 1 11 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c - gd32e230_dma.c + ..\..\src\object.c + object.c 0 0 - 3 + 1 12 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c - gd32e230_exti.c + ..\..\src\scheduler.c + scheduler.c 0 0 - 3 + 1 13 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c - gd32e230_fmc.c + ..\..\src\signal.c + signal.c 0 0 - 3 + 1 14 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c - gd32e230_fwdgt.c + ..\..\src\thread.c + thread.c 0 0 - 3 + 1 15 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c - gd32e230_gpio.c + ..\..\src\timer.c + timer.c 0 0 + + + + Applications + 0 + 0 + 0 + 0 - 3 + 2 16 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c - gd32e230_i2c.c + applications\main.c + main.c 0 0 + + + + Drivers + 0 + 0 + 0 + 0 3 17 @@ -395,8 +395,8 @@ 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c - gd32e230_misc.c + drivers\board.c + board.c 0 0 @@ -407,8 +407,8 @@ 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c - gd32e230_pmu.c + drivers\drv_usart.c + drv_usart.c 0 0 @@ -419,8 +419,8 @@ 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c - gd32e230_rcu.c + drivers\drv_spi.c + drv_spi.c 0 0 @@ -431,8 +431,8 @@ 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c - gd32e230_rtc.c + drivers\drv_i2c.c + drv_i2c.c 0 0 @@ -443,91 +443,91 @@ 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c - gd32e230_spi.c + drivers\drv_gpio.c + drv_gpio.c 0 0 + + + + GD32_Lib + 0 + 0 + 0 + 0 - 3 + 4 22 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c - gd32e230_syscfg.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + gd32e230_adc.c 0 0 - 3 + 4 23 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c - gd32e230_timer.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + gd32e230_cmp.c 0 0 - 3 + 4 24 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c - gd32e230_usart.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + gd32e230_crc.c 0 0 - 3 + 4 25 1 0 0 0 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c - gd32e230_wwdgt.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + gd32e230_dbg.c 0 0 - 3 + 4 26 1 0 0 0 - .\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c - system_gd32e230.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + gd32e230_dma.c 0 0 - 3 + 4 27 - 2 + 1 0 0 0 - .\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s - startup_gd32e230.s + Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + gd32e230_exti.c 0 0 - - - - Kernel - 1 - 0 - 0 - 0 4 28 @@ -535,8 +535,8 @@ 0 0 0 - ..\..\src\clock.c - clock.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + gd32e230_fmc.c 0 0 @@ -547,8 +547,8 @@ 0 0 0 - ..\..\src\components.c - components.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + gd32e230_fwdgt.c 0 0 @@ -559,8 +559,8 @@ 0 0 0 - ..\..\src\device.c - device.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + gd32e230_gpio.c 0 0 @@ -571,8 +571,8 @@ 0 0 0 - ..\..\src\idle.c - idle.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + gd32e230_i2c.c 0 0 @@ -583,8 +583,8 @@ 0 0 0 - ..\..\src\ipc.c - ipc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + gd32e230_misc.c 0 0 @@ -595,8 +595,8 @@ 0 0 0 - ..\..\src\irq.c - irq.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + gd32e230_pmu.c 0 0 @@ -607,8 +607,8 @@ 0 0 0 - ..\..\src\kservice.c - kservice.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + gd32e230_rcu.c 0 0 @@ -619,8 +619,8 @@ 0 0 0 - ..\..\src\mem.c - mem.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + gd32e230_rtc.c 0 0 @@ -631,8 +631,8 @@ 0 0 0 - ..\..\src\mempool.c - mempool.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + gd32e230_spi.c 0 0 @@ -643,8 +643,8 @@ 0 0 0 - ..\..\src\object.c - object.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + gd32e230_syscfg.c 0 0 @@ -655,8 +655,8 @@ 0 0 0 - ..\..\src\scheduler.c - scheduler.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + gd32e230_timer.c 0 0 @@ -667,8 +667,8 @@ 0 0 0 - ..\..\src\signal.c - signal.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + gd32e230_usart.c 0 0 @@ -679,8 +679,8 @@ 0 0 0 - ..\..\src\thread.c - thread.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + gd32e230_wwdgt.c 0 0 @@ -691,22 +691,34 @@ 0 0 0 - ..\..\src\timer.c - timer.c + Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + system_gd32e230.c + 0 + 0 + + + 4 + 42 + 2 + 0 + 0 + 0 + Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s + startup_gd32e230.s 0 0 - CORTEX-M23 - 1 + cpu + 0 0 0 0 5 - 42 + 43 1 0 0 @@ -718,7 +730,7 @@ 5 - 43 + 44 1 0 0 @@ -730,7 +742,7 @@ 5 - 44 + 45 1 0 0 @@ -742,7 +754,7 @@ 5 - 45 + 46 1 0 0 @@ -754,7 +766,7 @@ 5 - 46 + 47 2 0 0 @@ -767,23 +779,11 @@ - Filesystem - 1 + DeviceDrivers + 0 0 0 0 - - 6 - 47 - 1 - 0 - 0 - 0 - ..\..\components\dfs\src\dfs.c - dfs.c - 0 - 0 - 6 48 @@ -791,8 +791,8 @@ 0 0 0 - ..\..\components\dfs\src\dfs_file.c - dfs_file.c + ..\..\components\drivers\i2c\i2c_core.c + i2c_core.c 0 0 @@ -803,8 +803,8 @@ 0 0 0 - ..\..\components\dfs\src\dfs_fs.c - dfs_fs.c + ..\..\components\drivers\i2c\i2c_dev.c + i2c_dev.c 0 0 @@ -815,8 +815,8 @@ 0 0 0 - ..\..\components\dfs\src\dfs_posix.c - dfs_posix.c + ..\..\components\drivers\misc\pin.c + pin.c 0 0 @@ -827,8 +827,8 @@ 0 0 0 - ..\..\components\dfs\filesystems\devfs\devfs.c - devfs.c + ..\..\components\drivers\serial\serial.c + serial.c 0 0 @@ -839,8 +839,8 @@ 0 0 0 - ..\..\components\dfs\filesystems\elmfat\dfs_elm.c - dfs_elm.c + ..\..\components\drivers\spi\spi_core.c + spi_core.c 0 0 @@ -851,142 +851,98 @@ 0 0 0 - ..\..\components\dfs\filesystems\elmfat\ff.c - ff.c + ..\..\components\drivers\spi\spi_dev.c + spi_dev.c 0 0 - - - - DeviceDrivers - 1 - 0 - 0 - 0 - 7 + 6 54 1 0 0 0 - ..\..\components\drivers\i2c\i2c_core.c - i2c_core.c + ..\..\components\drivers\spi\spi_flash_sfud.c + spi_flash_sfud.c 0 0 - 7 + 6 55 1 0 0 0 - ..\..\components\drivers\i2c\i2c_dev.c - i2c_dev.c + ..\..\components\drivers\spi\sfud\src\sfud.c + sfud.c 0 0 - 7 + 6 56 1 0 0 0 - ..\..\components\drivers\misc\pin.c - pin.c + ..\..\components\drivers\src\completion.c + completion.c 0 0 - 7 + 6 57 1 0 0 0 - ..\..\components\drivers\serial\serial.c - serial.c + ..\..\components\drivers\src\dataqueue.c + dataqueue.c 0 0 - 7 + 6 58 1 0 0 0 - ..\..\components\drivers\spi\spi_core.c - spi_core.c + ..\..\components\drivers\src\pipe.c + pipe.c 0 0 - 7 + 6 59 1 0 0 0 - ..\..\components\drivers\spi\spi_dev.c - spi_dev.c + ..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c 0 0 - 7 + 6 60 1 0 0 0 - ..\..\components\drivers\src\completion.c - completion.c - 0 - 0 - - - 7 - 61 - 1 - 0 - 0 - 0 - ..\..\components\drivers\src\dataqueue.c - dataqueue.c - 0 - 0 - - - 7 - 62 - 1 - 0 - 0 - 0 - ..\..\components\drivers\src\pipe.c - pipe.c - 0 - 0 - - - 7 - 63 - 1 - 0 - 0 - 0 ..\..\components\drivers\src\ringbuffer.c ringbuffer.c 0 0 - 7 - 64 + 6 + 61 1 0 0 @@ -997,8 +953,8 @@ 0 - 7 - 65 + 6 + 62 1 0 0 @@ -1017,8 +973,8 @@ 0 0 - 8 - 66 + 7 + 63 1 0 0 @@ -1029,8 +985,8 @@ 0 - 8 - 67 + 7 + 64 1 0 0 @@ -1041,8 +997,8 @@ 0 - 8 - 68 + 7 + 65 1 0 0 @@ -1053,8 +1009,8 @@ 0 - 8 - 69 + 7 + 66 1 0 0 @@ -1065,8 +1021,8 @@ 0 - 8 - 70 + 7 + 67 1 0 0 @@ -1077,8 +1033,8 @@ 0 - 8 - 71 + 7 + 68 1 0 0 @@ -1089,8 +1045,8 @@ 0 - 8 - 72 + 7 + 69 1 0 0 @@ -1101,8 +1057,8 @@ 0 - 8 - 73 + 7 + 70 1 0 0 @@ -1113,8 +1069,8 @@ 0 - 8 - 74 + 7 + 71 1 0 0 @@ -1125,8 +1081,8 @@ 0 - 8 - 75 + 7 + 72 1 0 0 @@ -1137,8 +1093,8 @@ 0 - 8 - 76 + 7 + 73 1 0 0 @@ -1149,8 +1105,8 @@ 0 - 8 - 77 + 7 + 74 1 0 0 @@ -1161,8 +1117,8 @@ 0 - 8 - 78 + 7 + 75 1 0 0 @@ -1173,8 +1129,8 @@ 0 - 8 - 79 + 7 + 76 1 0 0 @@ -1185,8 +1141,8 @@ 0 - 8 - 80 + 7 + 77 1 0 0 @@ -1197,8 +1153,8 @@ 0 - 8 - 81 + 7 + 78 1 0 0 @@ -1210,86 +1166,6 @@ - - libc - 0 - 0 - 0 - 0 - - 9 - 82 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\libc.c - libc.c - 0 - 0 - - - 9 - 83 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\libc_syms.c - libc_syms.c - 0 - 0 - - - 9 - 84 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\mem_std.c - mem_std.c - 0 - 0 - - - 9 - 85 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\stdio.c - stdio.c - 0 - 0 - - - 9 - 86 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\stubs.c - stubs.c - 0 - 0 - - - 9 - 87 - 1 - 0 - 0 - 0 - ..\..\components\libc\compilers\armlibc\time.c - time.c - 0 - 0 - - - ::CMSIS 0 diff --git a/bsp/gd32e230k-start/project.uvprojx b/bsp/gd32e230k-start/project.uvprojx index 66d282d567..4466ae7d45 100644 --- a/bsp/gd32e230k-start/project.uvprojx +++ b/bsp/gd32e230k-start/project.uvprojx @@ -7,11 +7,10 @@ - rt-thread_gd32f30x + rt-thread_gd32e230 0x4 ARM-ADS - 6120000::V6.12::.\ARMCLANG - 6120000::V6.12::.\ARMCLANG + 5060750::V5.06 update 6 (build 750)::ARMCC 1 @@ -50,7 +49,7 @@ 1 .\build\ - rtthread-gd32f30x + rtthread-gd32e230 1 0 0 @@ -313,7 +312,7 @@ 1 - 7 + 1 0 0 0 @@ -322,14 +321,14 @@ 0 0 0 - 3 + 0 0 0 1 0 0 - 3 - 3 + 1 + 1 1 1 0 @@ -337,9 +336,9 @@ 0 - GD32E230, RT_USING_ARM_LIBC + GD32E230 - applications;.;drivers;Libraries\CMSIS;..\..\include;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\spi;..\..\components\drivers\include;..\..\components\drivers\spi\sfud\inc;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\armlibc;.\Libraries\GD32E230_standard_peripheral\Include;.\Libraries\CMSIS\GD\GD32E230\Include;..\..\libcpu\arm\cortex-m23 + .;..\..\include;applications;.;drivers;Libraries\CMSIS\GD\GD32E230\Include;Libraries\CMSIS;Libraries\GD32E230_standard_peripheral\Include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m23;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\spi;..\..\components\drivers\include;..\..\components\drivers\spi\sfud\inc;..\..\components\drivers\include;..\..\components\finsh @@ -373,13 +372,93 @@ - --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c + + + components.c + 1 + ..\..\src\components.c + + + cpu.c + 1 + ..\..\src\cpu.c + + + device.c + 1 + ..\..\src\device.c + + + idle.c + 1 + ..\..\src\idle.c + + + ipc.c + 1 + ..\..\src\ipc.c + + + irq.c + 1 + ..\..\src\irq.c + + + kservice.c + 1 + ..\..\src\kservice.c + + + mem.c + 1 + ..\..\src\mem.c + + + mempool.c + 1 + ..\..\src\mempool.c + + + object.c + 1 + ..\..\src\object.c + + + scheduler.c + 1 + ..\..\src\scheduler.c + + + signal.c + 1 + ..\..\src\signal.c + + + thread.c + 1 + ..\..\src\thread.c + + + timer.c + 1 + ..\..\src\timer.c + + + Applications @@ -426,187 +505,112 @@ gd32e230_adc.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c gd32e230_cmp.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c gd32e230_crc.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c gd32e230_dbg.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c gd32e230_dma.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c gd32e230_exti.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c gd32e230_fmc.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c gd32e230_fwdgt.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c gd32e230_gpio.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c gd32e230_i2c.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c gd32e230_misc.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c gd32e230_pmu.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c gd32e230_rcu.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c gd32e230_rtc.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c gd32e230_spi.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c gd32e230_syscfg.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c gd32e230_timer.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c gd32e230_usart.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c gd32e230_wwdgt.c 1 - .\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c system_gd32e230.c 1 - .\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c startup_gd32e230.s 2 - .\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s - - - - - Kernel - - - clock.c - 1 - ..\..\src\clock.c - - - components.c - 1 - ..\..\src\components.c - - - device.c - 1 - ..\..\src\device.c - - - idle.c - 1 - ..\..\src\idle.c - - - ipc.c - 1 - ..\..\src\ipc.c - - - irq.c - 1 - ..\..\src\irq.c - - - kservice.c - 1 - ..\..\src\kservice.c - - - mem.c - 1 - ..\..\src\mem.c - - - mempool.c - 1 - ..\..\src\mempool.c - - - object.c - 1 - ..\..\src\object.c - - - scheduler.c - 1 - ..\..\src\scheduler.c - - - signal.c - 1 - ..\..\src\signal.c - - - thread.c - 1 - ..\..\src\thread.c - - - timer.c - 1 - ..\..\src\timer.c + Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s - CORTEX-M23 + cpu backtrace.c @@ -635,46 +639,6 @@ - - Filesystem - - - dfs.c - 1 - ..\..\components\dfs\src\dfs.c - - - dfs_file.c - 1 - ..\..\components\dfs\src\dfs_file.c - - - dfs_fs.c - 1 - ..\..\components\dfs\src\dfs_fs.c - - - dfs_posix.c - 1 - ..\..\components\dfs\src\dfs_posix.c - - - devfs.c - 1 - ..\..\components\dfs\filesystems\devfs\devfs.c - - - dfs_elm.c - 1 - ..\..\components\dfs\filesystems\elmfat\dfs_elm.c - - - ff.c - 1 - ..\..\components\dfs\filesystems\elmfat\ff.c - - - DeviceDrivers @@ -720,9 +684,9 @@ 2 2 - - - + --c99 + + @@ -777,6 +741,16 @@ 1 ..\..\components\drivers\spi\spi_dev.c + + spi_flash_sfud.c + 1 + ..\..\components\drivers\spi\spi_flash_sfud.c + + + sfud.c + 1 + ..\..\components\drivers\spi\sfud\src\sfud.c + completion.c 1 @@ -792,6 +766,11 @@ 1 ..\..\components\drivers\src\pipe.c + + ringblk_buf.c + 1 + ..\..\components\drivers\src\ringblk_buf.c + ringbuffer.c 1 @@ -894,41 +873,6 @@ - - libc - - - libc.c - 1 - ..\..\components\libc\compilers\armlibc\libc.c - - - libc_syms.c - 1 - ..\..\components\libc\compilers\armlibc\libc_syms.c - - - mem_std.c - 1 - ..\..\components\libc\compilers\armlibc\mem_std.c - - - stdio.c - 1 - ..\..\components\libc\compilers\armlibc\stdio.c - - - stubs.c - 1 - ..\..\components\libc\compilers\armlibc\stubs.c - - - time.c - 1 - ..\..\components\libc\compilers\armlibc\time.c - - - ::CMSIS @@ -942,7 +886,7 @@ - + diff --git a/bsp/gd32e230k-start/rtconfig.h b/bsp/gd32e230k-start/rtconfig.h index 77e9056395..b490faaf8a 100644 --- a/bsp/gd32e230k-start/rtconfig.h +++ b/bsp/gd32e230k-start/rtconfig.h @@ -11,13 +11,13 @@ #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 100 -#define RT_DEBUG -#define RT_DEBUG_COLOR #define RT_USING_OVERFLOW_CHECK -#define RT_DEBUG_INIT 0 -#define RT_DEBUG_THREAD 0 #define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDEL_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 256 +#define RT_DEBUG +#define RT_DEBUG_COLOR /* Inter-Thread communication */ @@ -39,12 +39,14 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x40001 /* RT-Thread Components */ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN #define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 /* C++ features */ @@ -62,45 +64,37 @@ #define FINSH_CMD_SIZE 80 #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 /* Device virtual file system */ -#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 - -/* elm-chan's FatFs, Generic FAT Filesystem Module */ - -#define RT_DFS_ELM_CODE_PAGE 437 -#define RT_DFS_ELM_WORD_ACCESS -#define RT_DFS_ELM_USE_LFN_0 -#define RT_DFS_ELM_USE_LFN 0 -#define RT_DFS_ELM_MAX_LFN 255 -#define RT_DFS_ELM_DRIVES 2 -#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 -#define RT_DFS_ELM_REENTRANT -#define RT_USING_DFS_DEVFS /* Device Drivers */ #define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 #define RT_USING_SERIAL #define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_I2C #define RT_USING_PIN #define RT_USING_SPI +#define RT_USING_SFUD +#define RT_SFUD_USING_FLASH_INFO_TABLE + +/* Using WiFi */ + /* Using USB */ /* POSIX layer and C standard library */ -#define RT_USING_LIBC -/* Network stack */ +/* Network */ + +/* Socket abstraction layer */ + /* light weight TCP/IP stack */ @@ -108,6 +102,9 @@ /* Modbus master and slave stack */ +/* AT commands */ + + /* VBUS(Virtual Software BUS) */ @@ -116,11 +113,6 @@ /* RT-Thread online packages */ -/* system packages */ - -/* RT-Thread GUI Engine */ - - /* IoT - internet of things */ @@ -132,6 +124,9 @@ /* Wiced WiFi */ +/* IoT Cloud */ + + /* security packages */ @@ -144,10 +139,16 @@ /* tools packages */ +/* system packages */ + + +/* peripheral libraries and drivers */ + + /* miscellaneous packages */ -/* example package: hello */ +/* samples: kernel and components samples */ #define RT_USING_USART0 #define RT_USING_USART1 diff --git a/bsp/gd32e230k-start/rtconfig.py b/bsp/gd32e230k-start/rtconfig.py index c631bc3e44..f953a5e67b 100644 --- a/bsp/gd32e230k-start/rtconfig.py +++ b/bsp/gd32e230k-start/rtconfig.py @@ -2,7 +2,7 @@ import os # toolchains options ARCH='arm' -CPU='cortex-m4' +CPU='cortex-m23' CROSS_TOOL='keil' if os.getenv('RTT_CC'): @@ -71,8 +71,6 @@ elif PLATFORM == 'armcc': EXEC_PATH += '/ARM/ARMCC/bin' print(EXEC_PATH) - CFLAGS += ' --c99' - if BUILD == 'debug': CFLAGS += ' -g -O0' AFLAGS += ' -g' diff --git a/bsp/gd32e230k-start/template.uvoptx b/bsp/gd32e230k-start/template.uvoptx index 8fc841b0e1..93d9c266ef 100644 --- a/bsp/gd32e230k-start/template.uvoptx +++ b/bsp/gd32e230k-start/template.uvoptx @@ -22,11 +22,11 @@ - rt-thread_gd32f30x + rt-thread_gd32e230 0x4 ARM-ADS - 16000000 + 12000000 1 1 @@ -73,7 +73,7 @@ 0 - 0 + 1 0 1 @@ -103,7 +103,7 @@ 1 0 0 - 4 + 14 @@ -114,18 +114,18 @@ - Segger\JL2CM3.dll + BIN\UL2V8M.DLL 0 - JL2CM3 - -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL010000 -FP0($$Device:GD32F303ZE$Flash\GD32F30x_HD.FLM)) + JL2CM3 + -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 diff --git a/bsp/gd32e230k-start/template.uvprojx b/bsp/gd32e230k-start/template.uvprojx index 9b0a830d22..cf0ba886d1 100644 --- a/bsp/gd32e230k-start/template.uvprojx +++ b/bsp/gd32e230k-start/template.uvprojx @@ -7,23 +7,23 @@ - rt-thread_gd32f30x + rt-thread_gd32e230 0x4 ARM-ADS 5060750::V5.06 update 6 (build 750)::ARMCC - 0 + 1 - GD32F303ZE + GD32E230K8 GigaDevice - GigaDevice.GD32F30x_DFP.1.0.1 + GigaDevice.GD32E230_DFP.1.0.0 http://gd32mcu.21ic.com/data/documents/yingyongruanjian - IRAM(0x20000000-0x2000FFFF)IROM(0x08000000-0x0807FFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") + IRAM(0x20000000,0x0002000) IROM(0x08000000,0x0010000) CPUTYPE("Cortex-M23") CLOCK(12000000) ELITTLE - "Startup\GD\GD32F30x\startup_gd32f30x_hd.s" ("GD32F30x Startup Code") - UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000) + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) 0 - gd32f30x.h + $$Device:GD32E230K8$Device\Include\gd32e230.h @@ -33,14 +33,14 @@ - SFD\GD\GD32F30x\GD32F30x_HD.SFR + $$Device:GD32E230K8$SVD\GD32E230.svd 0 0 - GD\GD32F30x\ - GD\GD32F30x\ + + 0 0 @@ -49,7 +49,7 @@ 1 .\build\ - rtthread-gd32f30x + rtthread-gd32e230 1 0 0 @@ -109,14 +109,14 @@ 1 - SARMCM3.DLL - -REMAP - DCM.DLL - -pCM3 - SARMCM3.DLL - + + + + + SARMV8M.DLL + -MPU TCM.DLL - -pCM3 + -pCM23 @@ -137,8 +137,8 @@ 4096 1 - BIN\UL2CM3.DLL - "" () + BIN\UL2V8M.DLL + @@ -174,7 +174,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M23" 0 0 @@ -184,6 +184,7 @@ 0 0 0 + 0 0 0 8 @@ -192,7 +193,7 @@ 0 0 3 - 4 + 3 0 0 0 @@ -244,12 +245,12 @@ 0 0x20000000 - 0x10000 + 0x2000 1 0x8000000 - 0x80000 + 0x10000 0 @@ -274,7 +275,7 @@ 1 0x8000000 - 0x80000 + 0x10000 1 @@ -299,7 +300,7 @@ 0 0x20000000 - 0x10000 + 0x2000 0 @@ -324,6 +325,7 @@ 0 0 1 + 0 0 1 1 @@ -387,10 +389,10 @@ - - + + - + diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S index d17a8aa12c..d9993247e2 100644 --- a/libcpu/arm/cortex-m23/context_gcc.S +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -5,26 +5,25 @@ * * Change Logs: * Date Author Notes - * 2009-10-11 Bernard First version - * 2010-12-29 onelife Modify for EFM32 - * 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S - * 2011-07-12 onelife Add interrupt context check function - * 2013-06-18 aozima add restore MSP feature. - * 2013-07-09 aozima enhancement hard fault exception handler. + * 2010-01-25 Bernard first version + * 2012-06-01 aozima set pendsv priority to 0xFF. + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2013-02-20 aozima port to gcc. + * 2013-06-18 aozima add restore MSP feature. + * 2013-11-04 bright fixed hardfault bug for gcc. */ - .cpu cortex-m3 + .cpu cortex-m0 .fpu softvfp .syntax unified .thumb .text - .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ - .equ ICSR, 0xE000ED04 /* interrupt control state register */ - .equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */ - - .equ SHPR3, 0xE000ED20 /* system priority register (3) */ - .equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */ + .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ + .equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */ + .equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */ + .equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */ + .equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */ /* * rt_base_t rt_hw_interrupt_disable(); @@ -61,7 +60,7 @@ rt_hw_context_switch: LDR R3, [R2] CMP R3, #1 BEQ _reswitch - MOV R3, #1 + MOVS R3, #1 STR R3, [R2] LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ @@ -71,8 +70,8 @@ _reswitch: LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ STR R1, [R2] - LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ - LDR R1, =PENDSVSET_BIT + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR @@ -90,36 +89,56 @@ PendSV_Handler: /* get rt_thread_switch_interrupt_flag */ LDR R0, =rt_thread_switch_interrupt_flag LDR R1, [R0] - CBZ R1, pendsv_exit /* pendsv aLReady handled */ + CMP R1, #0x00 + BEQ pendsv_exit /* pendsv aLReady handled */ /* clear rt_thread_switch_interrupt_flag to 0 */ - MOV R1, #0 + MOVS R1, #0 STR R1, [R0] LDR R0, =rt_interrupt_from_thread LDR R1, [R0] - CBZ R1, switch_to_thread /* skip register save at the first time */ + CMP R1, #0x00 + BEQ switch_to_thread /* skip register save at the first time */ - MRS R1, PSP /* get from thread stack pointer */ - STMFD R1!, {R4 - R11} /* push R4 - R11 register */ + MRS R1, PSP /* get from thread stack pointer */ + + SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */ LDR R0, [R0] STR R1, [R0] /* update from thread stack pointer */ + STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */ + + MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */ + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */ switch_to_thread: LDR R1, =rt_interrupt_to_thread LDR R1, [R1] LDR R1, [R1] /* load thread stack pointer */ - LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */ + LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */ + PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */ + + LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */ + MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */ + MOV R9, R5 + MOV R10, R6 + MOV R11, R7 + + POP {R4 - R7} /* pop {R4 - R7} from MSP */ + MSR PSP, R1 /* update stack pointer */ pendsv_exit: /* restore interrupt */ MSR PRIMASK, R2 - ORR LR, LR, #0x04 - BX LR - + MOVS R0, #0x04 + RSBS R0, R0, #0x00 + BX R0 /* * void rt_hw_context_switch_to(rt_uint32 to); * R0 --> to @@ -132,34 +151,33 @@ rt_hw_context_switch_to: /* set from thread to 0 */ LDR R1, =rt_interrupt_from_thread - MOV R0, #0 + MOVS R0, #0 STR R0, [R1] /* set interrupt flag to 1 */ LDR R1, =rt_thread_switch_interrupt_flag - MOV R0, #1 + MOVS R0, #1 STR R0, [R1] /* set the PendSV exception priority */ - LDR R0, =SHPR3 - LDR R1, =PENDSV_PRI_LOWEST - LDR.W R2, [R0,#0] /* read */ - ORR R1, R1, R2 /* modify */ - STR R1, [R0] /* write-back */ - - LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ - LDR R1, =PENDSVSET_BIT + LDR R0, =NVIC_SHPR3 + LDR R1, =NVIC_PENDSV_PRI + LDR R2, [R0,#0x00] /* read */ + ORRS R1, R1, R2 /* modify */ + STR R1, [R0] /* write-back */ + + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET STR R1, [R0] - + NOP /* restore MSP */ - LDR r0, =SCB_VTOR - LDR r0, [r0] - LDR r0, [r0] + LDR R0, =SCB_VTOR + LDR R0, [R0] + LDR R0, [R0] NOP - MSR msp, r0 + MSR MSP, R0 /* enable interrupts at processor level */ - CPSIE F CPSIE I /* never reach here! */ @@ -175,29 +193,11 @@ rt_hw_interrupt_thread_switch: .type HardFault_Handler, %function HardFault_Handler: /* get current context */ - MRS r0, msp /* get fault context from handler. */ - TST lr, #0x04 /* if(!EXC_RETURN[2]) */ - BEQ _get_sp_done - MRS r0, psp /* get fault context from thread. */ -_get_sp_done: - - STMFD r0!, {r4 - r11} /* push r4 - r11 register */ - STMFD r0!, {lr} /* push exec_return register */ - - TST lr, #0x04 /* if(!EXC_RETURN[2]) */ - BEQ _update_msp - MSR psp, r0 /* update stack pointer to PSP. */ - B _update_done -_update_msp: - MSR msp, r0 /* update stack pointer to MSP. */ -_update_done: - + MRS R0, PSP /* get fault thread stack pointer */ PUSH {LR} BL rt_hw_hard_fault_exception - POP {LR} + POP {PC} - ORR LR, LR, #0x04 - BX LR /* * rt_uint32_t rt_hw_interrupt_check(void); diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S index 91645c48b3..50d3781359 100644 --- a/libcpu/arm/cortex-m23/context_iar.S +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -5,20 +5,20 @@ ; * ; * Change Logs: ; * Date Author Notes -; * 2009-01-17 Bernard first version -; * 2009-09-27 Bernard add protect when contex switch occurs +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. -; * 2013-07-09 aozima enhancement hard fault exception handler. ; */ ;/** -; * @addtogroup cortex-m3 +; * @addtogroup CORTEX-M0 ; */ ;/*@{*/ SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register -NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception @@ -62,7 +62,7 @@ rt_hw_context_switch: LDR r3, [r2] CMP r3, #1 BEQ _reswitch - MOV r3, #1 + MOVS r3, #0x1 STR r3, [r2] LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread @@ -90,65 +90,91 @@ PendSV_Handler: ; get rt_thread_switch_interrupt_flag LDR r0, =rt_thread_switch_interrupt_flag LDR r1, [r0] - CBZ r1, pendsv_exit ; pendsv already handled + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled ; clear rt_thread_switch_interrupt_flag to 0 - MOV r1, #0x00 + MOVS r1, #0x00 STR r1, [r0] LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, switch_to_thread ; skip register save at the first time + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer - STMFD r1!, {r4 - r11} ; push r4 - r11 register + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer - LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + MSR psp, r1 ; update stack pointer pendsv_exit ; restore interrupt MSR PRIMASK, r2 - ORR lr, lr, #0x04 - BX lr + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 ;/* ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to +; * this fucntion is used to perform the first thread switch ; */ EXPORT rt_hw_context_switch_to rt_hw_context_switch_to: + ; set to thread LDR r1, =rt_interrupt_to_thread STR r0, [r1] ; set from thread to 0 LDR r1, =rt_interrupt_from_thread - MOV r0, #0x0 + MOVS r0, #0x0 STR r0, [r1] ; set interrupt flag to 1 LDR r1, =rt_thread_switch_interrupt_flag - MOV r0, #1 + MOVS r0, #1 STR r0, [r1] ; set the PendSV exception priority - LDR r0, =NVIC_SYSPRI2 + LDR r0, =NVIC_SHPR3 LDR r1, =NVIC_PENDSV_PRI - LDR.W r2, [r0,#0x00] ; read - ORR r1,r1,r2 ; modify + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify STR r1, [r0] ; write-back - LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL LDR r1, =NVIC_PENDSVSET STR r1, [r0] + NOP ; restore MSP LDR r0, =SCB_VTOR @@ -158,7 +184,6 @@ rt_hw_context_switch_to: MSR msp, r0 ; enable interrupts at processor level - CPSIE F CPSIE I ; never reach here! @@ -173,30 +198,9 @@ rt_hw_interrupt_thread_switch: HardFault_Handler: ; get current context - MRS r0, msp ; get fault context from handler. - TST lr, #0x04 ; if(!EXC_RETURN[2]) - BEQ _get_sp_done - MRS r0, psp ; get fault context from thread. -_get_sp_done - - STMFD r0!, {r4 - r11} ; push r4 - r11 register - ;STMFD r0!, {lr} ; push exec_return register - SUB r0, r0, #0x04 - STR lr, [r0] - - TST lr, #0x04 ; if(!EXC_RETURN[2]) - BEQ _update_msp - MSR psp, r0 ; update stack pointer to PSP. - B _update_done -_update_msp - MSR msp, r0 ; update stack pointer to MSP. -_update_done - + MRS r0, psp ; get fault thread stack pointer PUSH {lr} BL rt_hw_hard_fault_exception - POP {lr} - - ORR lr, lr, #0x04 - BX lr + POP {pc} END diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S index c0a2130703..54145773d3 100644 --- a/libcpu/arm/cortex-m23/context_rvds.S +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -5,9 +5,10 @@ ; * ; * Change Logs: ; * Date Author Notes -; * 2009-01-17 Bernard first version +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. -; * 2013-07-09 aozima enhancement hard fault exception handler. ; */ ;/** @@ -17,7 +18,7 @@ SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register -NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception @@ -45,8 +46,8 @@ rt_hw_interrupt_disable PROC ; */ rt_hw_interrupt_enable PROC EXPORT rt_hw_interrupt_enable - MSR PRIMASK, r0 - BX LR + MSR PRIMASK, r0 + BX LR ENDP ;/* @@ -64,7 +65,7 @@ rt_hw_context_switch PROC LDR r3, [r2] CMP r3, #1 BEQ _reswitch - MOV r3, #1 + MOVS r3, #0x01 STR r3, [r2] LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread @@ -83,7 +84,7 @@ _reswitch ; r0 --> switch from thread stack ; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack -PendSV_Handler PROC +PendSV_Handler PROC EXPORT PendSV_Handler ; disable interrupt to protect context switch @@ -93,35 +94,57 @@ PendSV_Handler PROC ; get rt_thread_switch_interrupt_flag LDR r0, =rt_thread_switch_interrupt_flag LDR r1, [r0] - CBZ r1, pendsv_exit ; pendsv already handled + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled ; clear rt_thread_switch_interrupt_flag to 0 - MOV r1, #0x00 + MOVS r1, #0x00 STR r1, [r0] LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, switch_to_thread ; skip register save at the first time + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer - STMFD r1!, {r4 - r11} ; push r4 - r11 register + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer - LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + MSR psp, r1 ; update stack pointer pendsv_exit ; restore interrupt MSR PRIMASK, r2 - ORR lr, lr, #0x04 - BX lr + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 ENDP ;/* @@ -137,19 +160,19 @@ rt_hw_context_switch_to PROC ; set from thread to 0 LDR r1, =rt_interrupt_from_thread - MOV r0, #0x0 + MOVS r0, #0x0 STR r0, [r1] ; set interrupt flag to 1 LDR r1, =rt_thread_switch_interrupt_flag - MOV r0, #1 + MOVS r0, #1 STR r0, [r1] ; set the PendSV exception priority - LDR r0, =NVIC_SYSPRI2 + LDR r0, =NVIC_SHPR3 LDR r1, =NVIC_PENDSV_PRI - LDR.W r2, [r0,#0x00] ; read - ORR r1,r1,r2 ; modify + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify STR r1, [r0] ; write-back ; trigger the PendSV exception (causes context switch) @@ -164,7 +187,6 @@ rt_hw_context_switch_to PROC MSR msp, r0 ; enable interrupts at processor level - CPSIE F CPSIE I ; never reach here! @@ -177,29 +199,15 @@ rt_hw_interrupt_thread_switch PROC ENDP IMPORT rt_hw_hard_fault_exception - EXPORT HardFault_Handler + HardFault_Handler PROC + EXPORT HardFault_Handler ; get current context - TST lr, #0x04 ; if(!EXC_RETURN[2]) - ITE EQ - MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler. - MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread. - - STMFD r0!, {r4 - r11} ; push r4 - r11 register - STMFD r0!, {lr} ; push exec_return register - - TST lr, #0x04 ; if(!EXC_RETURN[2]) - ITE EQ - MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP. - MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP. - + MRS r0, psp ; get fault thread stack pointer PUSH {lr} BL rt_hw_hard_fault_exception - POP {lr} - - ORR lr, lr, #0x04 - BX lr + POP {pc} ENDP ALIGN 4 diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c index a386747750..5d36fa11fe 100644 --- a/libcpu/arm/cortex-m23/cpuport.c +++ b/libcpu/arm/cortex-m23/cpuport.c @@ -4,13 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2009-01-05 Bernard first version - * 2011-02-14 onelife Modify for EFM32 - * 2011-06-17 onelife Merge all of the C source code into cpuport.c - * 2012-12-23 aozima stack addr align to 8byte. - * 2012-12-29 Bernard Add exception hook. - * 2013-07-09 aozima enhancement hard fault exception handler. + * Date Author Notes + * 2010-01-25 Bernard first version + * 2012-05-31 aozima Merge all of the C source code into cpuport.c + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2012-12-23 aozima stack addr align to 8byte. */ #include @@ -29,11 +27,13 @@ struct exception_stack_frame struct stack_frame { - /* r4 ~ r11 register */ + /* r4 ~ r7 low register */ rt_uint32_t r4; rt_uint32_t r5; rt_uint32_t r6; rt_uint32_t r7; + + /* r8 ~ r11 high register */ rt_uint32_t r8; rt_uint32_t r9; rt_uint32_t r10; @@ -45,8 +45,6 @@ struct stack_frame /* flag in interrupt handling */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; -/* exception hook */ -static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; /** * This function will initialize thread stack @@ -92,312 +90,46 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, return stk; } +extern long list_thread(void); +extern rt_thread_t rt_current_thread; /** - * This function set the hook, which is invoked on fault exception handling. - * - * @param exception_handle the exception handling hook function. + * fault exception handling */ -void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context)) +void rt_hw_hard_fault_exception(struct exception_stack_frame *contex) { - rt_exception_hook = exception_handle; + rt_kprintf("psr: 0x%08x\n", contex->psr); + rt_kprintf(" pc: 0x%08x\n", contex->pc); + rt_kprintf(" lr: 0x%08x\n", contex->lr); + rt_kprintf("r12: 0x%08x\n", contex->r12); + rt_kprintf("r03: 0x%08x\n", contex->r3); + rt_kprintf("r02: 0x%08x\n", contex->r2); + rt_kprintf("r01: 0x%08x\n", contex->r1); + rt_kprintf("r00: 0x%08x\n", contex->r0); + + rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + + while (1); } #define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */ #define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ #define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ #define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ -#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */ #define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ #define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ #define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */ #define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */ -#ifdef RT_USING_FINSH -static void usage_fault_track(void) -{ - rt_kprintf("usage fault:\n"); - rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR); - - if(SCB_CFSR_UFSR & (1<<0)) - { - /* [0]:UNDEFINSTR */ - rt_kprintf("UNDEFINSTR "); - } - - if(SCB_CFSR_UFSR & (1<<1)) - { - /* [1]:INVSTATE */ - rt_kprintf("INVSTATE "); - } - - if(SCB_CFSR_UFSR & (1<<2)) - { - /* [2]:INVPC */ - rt_kprintf("INVPC "); - } - - if(SCB_CFSR_UFSR & (1<<3)) - { - /* [3]:NOCP */ - rt_kprintf("NOCP "); - } - - if(SCB_CFSR_UFSR & (1<<8)) - { - /* [8]:UNALIGNED */ - rt_kprintf("UNALIGNED "); - } - - if(SCB_CFSR_UFSR & (1<<9)) - { - /* [9]:DIVBYZERO */ - rt_kprintf("DIVBYZERO "); - } - - rt_kprintf("\n"); -} - -static void bus_fault_track(void) -{ - rt_kprintf("bus fault:\n"); - rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR); - - if(SCB_CFSR_BFSR & (1<<0)) - { - /* [0]:IBUSERR */ - rt_kprintf("IBUSERR "); - } - - if(SCB_CFSR_BFSR & (1<<1)) - { - /* [1]:PRECISERR */ - rt_kprintf("PRECISERR "); - } - - if(SCB_CFSR_BFSR & (1<<2)) - { - /* [2]:IMPRECISERR */ - rt_kprintf("IMPRECISERR "); - } - - if(SCB_CFSR_BFSR & (1<<3)) - { - /* [3]:UNSTKERR */ - rt_kprintf("UNSTKERR "); - } - - if(SCB_CFSR_BFSR & (1<<4)) - { - /* [4]:STKERR */ - rt_kprintf("STKERR "); - } - - if(SCB_CFSR_BFSR & (1<<7)) - { - rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR); - } - else - { - rt_kprintf("\n"); - } -} - -static void mem_manage_fault_track(void) -{ - rt_kprintf("mem manage fault:\n"); - rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR); - - if(SCB_CFSR_MFSR & (1<<0)) - { - /* [0]:IACCVIOL */ - rt_kprintf("IACCVIOL "); - } - - if(SCB_CFSR_MFSR & (1<<1)) - { - /* [1]:DACCVIOL */ - rt_kprintf("DACCVIOL "); - } - - if(SCB_CFSR_MFSR & (1<<3)) - { - /* [3]:MUNSTKERR */ - rt_kprintf("MUNSTKERR "); - } - - if(SCB_CFSR_MFSR & (1<<4)) - { - /* [4]:MSTKERR */ - rt_kprintf("MSTKERR "); - } - - if(SCB_CFSR_MFSR & (1<<7)) - { - /* [7]:MMARVALID */ - rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR); - } - else - { - rt_kprintf("\n"); - } -} - -static void hard_fault_track(void) -{ - if(SCB_HFSR & (1UL<<1)) - { - /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */ - rt_kprintf("failed vector fetch\n"); - } - - if(SCB_HFSR & (1UL<<30)) - { - /* [30]:FORCED, Indicates hard fault is taken because of bus fault, - memory management fault, or usage fault. */ - if(SCB_CFSR_BFSR) - { - bus_fault_track(); - } - - if(SCB_CFSR_MFSR) - { - mem_manage_fault_track(); - } - - if(SCB_CFSR_UFSR) - { - usage_fault_track(); - } - } - - if(SCB_HFSR & (1UL<<31)) - { - /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */ - rt_kprintf("debug event\n"); - } -} -#endif /* RT_USING_FINSH */ - -struct exception_info -{ - rt_uint32_t exc_return; - struct stack_frame stack_frame; -}; - -/* - * fault exception handler - */ -void rt_hw_hard_fault_exception(struct exception_info * exception_info) -{ - extern long list_thread(void); - struct stack_frame* context = &exception_info->stack_frame; - - if (rt_exception_hook != RT_NULL) - { - rt_err_t result; - - result = rt_exception_hook(exception_info); - if (result == RT_EOK) - return; - } - - rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr); - - rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0); - rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1); - rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2); - rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3); - rt_kprintf("r04: 0x%08x\n", context->r4); - rt_kprintf("r05: 0x%08x\n", context->r5); - rt_kprintf("r06: 0x%08x\n", context->r6); - rt_kprintf("r07: 0x%08x\n", context->r7); - rt_kprintf("r08: 0x%08x\n", context->r8); - rt_kprintf("r09: 0x%08x\n", context->r9); - rt_kprintf("r10: 0x%08x\n", context->r10); - rt_kprintf("r11: 0x%08x\n", context->r11); - rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12); - rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr); - rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc); - - if(exception_info->exc_return & (1 << 2) ) - { - rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name); - -#ifdef RT_USING_FINSH - list_thread(); -#endif /* RT_USING_FINSH */ - } - else - { - rt_kprintf("hard fault on handler\r\n\r\n"); - } - -#ifdef RT_USING_FINSH - hard_fault_track(); -#endif /* RT_USING_FINSH */ - - while (1); -} - -/** - * shutdown CPU - */ -void rt_hw_cpu_shutdown(void) -{ - rt_kprintf("shutdown...\n"); - - RT_ASSERT(0); -} - /** * reset CPU */ RT_WEAK void rt_hw_cpu_reset(void) { - SCB_AIRCR = SCB_RESET_VALUE; -} - -#ifdef RT_USING_CPU_FFS -/** - * This function finds the first bit set (beginning with the least significant bit) - * in value and return the index of that bit. - * - * Bits are numbered starting at 1 (the least significant bit). A return value of - * zero from any of these functions means that the argument was zero. - * - * @return return the index of the first bit set. If value is 0, then this function - * shall return 0. - */ -#if defined(__CC_ARM) -__asm int __rt_ffs(int value) -{ - CMP r0, #0x00 - BEQ exit - - RBIT r0, r0 - CLZ r0, r0 - ADDS r0, r0, #0x01 - -exit - BX lr + SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk); } -#elif defined(__IAR_SYSTEMS_ICC__) -int __rt_ffs(int value) -{ - if (value == 0) return value; - - asm("RBIT %0, %1" : "=r"(value) : "r"(value)); - asm("CLZ %0, %1" : "=r"(value) : "r"(value)); - asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); - - return value; -} -#elif defined(__GNUC__) -int __rt_ffs(int value) -{ - return __builtin_ffs(value); -} -#endif - -#endif -- cgit v1.3.1 From fd8eb60a67588f53125f3175594e51d634fd3f79 Mon Sep 17 00:00:00 2001 From: xuzhuoyi Date: Sun, 31 Mar 2019 23:26:35 +0800 Subject: [bsp][gd32e230k-start] Update Kconfig --- bsp/gd32e230k-start/.config | 163 +++++++++++++++++++++----------- bsp/gd32e230k-start/Kconfig | 5 - bsp/gd32e230k-start/drivers/drv_gpio.c | 134 +++++++------------------- bsp/gd32e230k-start/drivers/drv_i2c.c | 3 +- bsp/gd32e230k-start/drivers/drv_spi.c | 6 +- bsp/gd32e230k-start/drivers/drv_usart.c | 88 +---------------- bsp/gd32e230k-start/project.uvoptx | 4 +- bsp/gd32e230k-start/project.uvprojx | 12 +-- bsp/gd32e230k-start/rtconfig.h | 5 + bsp/gd32e230k-start/template.uvoptx | 2 +- bsp/gd32e230k-start/template.uvprojx | 4 +- libcpu/arm/cortex-m23/context_gcc.S | 7 +- libcpu/arm/cortex-m23/context_iar.S | 5 +- libcpu/arm/cortex-m23/context_rvds.S | 3 +- libcpu/arm/cortex-m23/cpuport.c | 3 +- 15 files changed, 176 insertions(+), 268 deletions(-) (limited to 'libcpu') diff --git a/bsp/gd32e230k-start/.config b/bsp/gd32e230k-start/.config index 40cac74cf7..8f18d4257e 100644 --- a/bsp/gd32e230k-start/.config +++ b/bsp/gd32e230k-start/.config @@ -7,20 +7,32 @@ # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 # 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=100 -CONFIG_RT_DEBUG=y -CONFIG_RT_DEBUG_COLOR=y CONFIG_RT_USING_OVERFLOW_CHECK=y -CONFIG_RT_DEBUG_INIT=0 -CONFIG_RT_DEBUG_THREAD=0 CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 CONFIG_IDLE_THREAD_STACK_SIZE=256 # CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set # # Inter-Thread communication @@ -47,11 +59,13 @@ CONFIG_RT_USING_HEAP=y # Kernel Device Object # CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set # CONFIG_RT_USING_INTERRUPT_INFO is not set CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -# CONFIG_RT_USING_MODULE is not set +CONFIG_RT_VER_NUM=0x40001 +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # # RT-Thread Components @@ -59,6 +73,7 @@ CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 # # C++ features @@ -82,67 +97,58 @@ CONFIG_FINSH_CMD_SIZE=80 CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_USING_MSH_DEFAULT=y # CONFIG_FINSH_USING_MSH_ONLY is not set +CONFIG_FINSH_ARG_MAX=10 # # 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=437 -CONFIG_RT_DFS_ELM_WORD_ACCESS=y -CONFIG_RT_DFS_ELM_USE_LFN_0=y +# CONFIG_RT_USING_DFS is not set +# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set # 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=255 -CONFIG_RT_DFS_ELM_DRIVES=2 -CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 -# CONFIG_RT_DFS_ELM_USE_ERASE is not set -CONFIG_RT_DFS_ELM_REENTRANT=y -CONFIG_RT_USING_DFS_DEVFS=y -# 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_PIPE_BUFSZ=512 CONFIG_RT_USING_SERIAL=y CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_HWTIMER is not set # CONFIG_RT_USING_CPUTIME is not set CONFIG_RT_USING_I2C=y # CONFIG_RT_USING_I2C_BITOPS is not set CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_MTD is not set +# CONFIG_RT_USING_PM 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_QSPI is not set # CONFIG_RT_USING_SPI_MSD is not set CONFIG_RT_USING_SFUD=y # CONFIG_RT_SFUD_USING_SFDP is not set CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y -# CONFIG_RT_SFUD_DEBUG is not set +# CONFIG_RT_SFUD_USING_QSPI is not set +# CONFIG_RT_DEBUG_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_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set + +# +# Using WiFi +# # CONFIG_RT_USING_WIFI is not set # @@ -154,27 +160,33 @@ CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y # # POSIX layer and C standard library # -CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_LIBC is not set # CONFIG_RT_USING_PTHREADS is not set -# CONFIG_RT_USING_POSIX is not set -# CONFIG_HAVE_SYS_SIGNALS is not set # -# Network stack +# Network # +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + # # light weight TCP/IP stack # # CONFIG_RT_USING_LWIP is not set -# CONFIG_RT_USING_LWIP141 is not set -# CONFIG_RT_USING_LWIP202 is not set # # Modbus master and slave stack # # CONFIG_RT_USING_MODBUS is not set +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + # # VBUS(Virtual Software BUS) # @@ -185,25 +197,13 @@ CONFIG_RT_USING_LIBC=y # # CONFIG_RT_USING_LOGTRACE is not set # CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set # # RT-Thread online packages # -# -# system packages -# - -# -# RT-Thread GUI Engine -# -# CONFIG_PKG_USING_GUIENGINE is not set -# CONFIG_PKG_USING_LWEXT4 is not set -# CONFIG_PKG_USING_PARTITION is not set -# CONFIG_PKG_USING_SQLITE is not set -# CONFIG_PKG_USING_RTI is not set -# CONFIG_PKG_USING_LITTLEVGL2RTT is not set - # # IoT - internet of things # @@ -212,10 +212,10 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_MONGOOSE is not set # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set -# CONFIG_PKG_USING_GAGENT_CLOUD is not set # # Wi-Fi @@ -233,7 +233,16 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_COAP is not set # CONFIG_PKG_USING_NOPOLL is not set # CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# # CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set # # security packages @@ -245,6 +254,7 @@ CONFIG_RT_USING_LIBC=y # # language packages # +# CONFIG_PKG_USING_LUA is not set # CONFIG_PKG_USING_JERRYSCRIPT is not set # CONFIG_PKG_USING_MICROPYTHON is not set @@ -252,6 +262,7 @@ CONFIG_RT_USING_LIBC=y # multimedia packages # # CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set # # tools packages @@ -260,17 +271,58 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_EASYFLASH is not set # CONFIG_PKG_USING_EASYLOGGER is not set # CONFIG_PKG_USING_SYSTEMVIEW is not set -# CONFIG_PKG_USING_IPERF is not set +# CONFIG_PKG_USING_RDB is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set # # miscellaneous packages # +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set # CONFIG_PKG_USING_FASTLZ is not set # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_MULTIBUTTON is not set -# CONFIG_PKG_USING_SAMPLES is not set # CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set + +# +# sample package +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set # # example package: hello @@ -283,6 +335,5 @@ CONFIG_RT_USING_USART1=y # CONFIG_RT_USING_UART4 is not set CONFIG_RT_USING_SPI0=y CONFIG_RT_USING_SPI1=y -# CONFIG_RT_USING_SPI2 is not set CONFIG_RT_USING_I2C0=y # CONFIG_RT_USING_I2C1 is not set diff --git a/bsp/gd32e230k-start/Kconfig b/bsp/gd32e230k-start/Kconfig index e4706f4d4f..36b2d0eeb1 100644 --- a/bsp/gd32e230k-start/Kconfig +++ b/bsp/gd32e230k-start/Kconfig @@ -53,11 +53,6 @@ config RT_USING_SPI1 select RT_USING_SPI default n -config RT_USING_SPI2 - bool "Using SPI2" - select RT_USING_SPI - default n - config RT_USING_I2C0 bool "Using I2C0" select RT_USING_I2C diff --git a/bsp/gd32e230k-start/drivers/drv_gpio.c b/bsp/gd32e230k-start/drivers/drv_gpio.c index 6b9ecf4e34..288ba6c832 100644 --- a/bsp/gd32e230k-start/drivers/drv_gpio.c +++ b/bsp/gd32e230k-start/drivers/drv_gpio.c @@ -1,16 +1,17 @@ /* * File : drv_gpio.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015, RT-Thread Development Team + * COPYRIGHT (C) 2019, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rt-thread.org/license/LICENSE * * Change Logs: - * Date Author Notes + * Date Author Notes * 2017-10-20 ZYH the first version * 2018-04-23 misonyo port to gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 */ #include "drv_gpio.h" @@ -23,7 +24,7 @@ #define __GD32_PIN(index, port, pin) {index, RCU_GPIO##port, GPIO##port, \ GPIO_PIN_##pin, EXTI_SOURCE_GPIO##port, EXTI_SOURCE_PIN##pin} -#define __GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0} +#define __GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0, 0, 0} /* GD32 GPIO driver */ struct pin_index @@ -39,102 +40,37 @@ struct pin_index static const struct pin_index pins[] = { __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(7, C, 13), - __GD32_PIN(8, C, 14), - __GD32_PIN(9, C, 15), - __GD32_PIN(10, F, 0), - __GD32_PIN(11, F, 1), - __GD32_PIN(12, F, 2), - __GD32_PIN(13, F, 3), - __GD32_PIN(14, F, 4), - __GD32_PIN(15, F, 5), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(18, F, 6), - __GD32_PIN(19, F, 7), - __GD32_PIN(20, F, 8), - __GD32_PIN(21, F, 9), - __GD32_PIN(22, F, 10), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(26, C, 0), - __GD32_PIN(27, C, 1), - __GD32_PIN(28, C, 2), - __GD32_PIN(29, C, 3), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(34, A, 0), - __GD32_PIN(35, A, 1), - __GD32_PIN(36, A, 2), - __GD32_PIN(37, A, 3), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(40, A, 4), - __GD32_PIN(41, A, 5), - __GD32_PIN(42, A, 6), - __GD32_PIN(43, A, 7), - __GD32_PIN(44, C, 4), - __GD32_PIN(45, C, 5), - __GD32_PIN(46, B, 0), - __GD32_PIN(47, B, 1), - __GD32_PIN(48, B, 2), - __GD32_PIN(49, F, 11), - __GD32_PIN(50, F, 12), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(53, F, 13), - __GD32_PIN(54, F, 14), - __GD32_PIN(55, F, 15), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(69, B, 10), - __GD32_PIN(70, B, 11), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(73, B, 12), - __GD32_PIN(74, B, 13), - __GD32_PIN(75, B, 14), - __GD32_PIN(76, B, 15), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(96, C, 6), - __GD32_PIN(97, C, 7), - __GD32_PIN(98, C, 8), - __GD32_PIN(99, C, 9), - __GD32_PIN(100, A, 8), - __GD32_PIN(101, A, 9), - __GD32_PIN(102, A, 10), - __GD32_PIN(103, A, 11), - __GD32_PIN(104, A, 12), - __GD32_PIN(105, A, 13), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(109, A, 14), - __GD32_PIN(110, A, 15), - __GD32_PIN(111, C, 10), - __GD32_PIN(112, C, 11), - __GD32_PIN(113, C, 12), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, - __GD32_PIN(133, B, 3), - __GD32_PIN(134, B, 4), - __GD32_PIN(135, B, 5), - __GD32_PIN(136, B, 6), - __GD32_PIN(137, B, 7), - __GD32_PIN_DEFAULT, - __GD32_PIN(139, B, 8), - __GD32_PIN(140, B, 9), - __GD32_PIN_DEFAULT, - __GD32_PIN_DEFAULT, + __GD32_PIN(2, F, 0), + __GD32_PIN(3, F, 1), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(6, A, 0), + __GD32_PIN(7, A, 1), + __GD32_PIN(8, A, 2), + __GD32_PIN(9, A, 3), + __GD32_PIN(10, A, 4), + __GD32_PIN(11, A, 5), + __GD32_PIN(12, A, 6), + __GD32_PIN(13, A, 7), + __GD32_PIN(14, B, 0), + __GD32_PIN(15, B, 1), + __GD32_PIN(16, B, 2), + __GD32_PIN_DEFAULT, + __GD32_PIN(18, A, 8), + __GD32_PIN(19, A, 9), + __GD32_PIN(20, A, 10), + __GD32_PIN(21, A, 11), + __GD32_PIN(22, A, 12), + __GD32_PIN(23, A, 13), + __GD32_PIN(24, A, 14), + __GD32_PIN(25, A, 15), + __GD32_PIN(26, B, 3), + __GD32_PIN(27, B, 4), + __GD32_PIN(28, B, 5), + __GD32_PIN(29, B, 6), + __GD32_PIN(30, B, 7), + __GD32_PIN_DEFAULT, + __GD32_PIN(32, B, 8), }; struct pin_irq_map diff --git a/bsp/gd32e230k-start/drivers/drv_i2c.c b/bsp/gd32e230k-start/drivers/drv_i2c.c index c0fbd5f7e9..78ddd99bdd 100644 --- a/bsp/gd32e230k-start/drivers/drv_i2c.c +++ b/bsp/gd32e230k-start/drivers/drv_i2c.c @@ -1,7 +1,7 @@ /* * File : drv_i2c.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2019, 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 @@ -21,6 +21,7 @@ * Date Author Notes * 2017-06-05 tanek first implementation. * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 */ #include "drv_i2c.h" diff --git a/bsp/gd32e230k-start/drivers/drv_spi.c b/bsp/gd32e230k-start/drivers/drv_spi.c index 7c749d75e0..1611b1d338 100644 --- a/bsp/gd32e230k-start/drivers/drv_spi.c +++ b/bsp/gd32e230k-start/drivers/drv_spi.c @@ -1,7 +1,7 @@ /* * File : drv_spi.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017 RT-Thread Develop Team + * COPYRIGHT (C) 2019 RT-Thread Develop Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -11,6 +11,7 @@ * Date Author Notes * 2017-06-05 tanek first implementation. * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 */ #include "drv_spi.h" @@ -20,8 +21,7 @@ #if defined(RT_USING_SPI) && defined(RT_USING_PIN) #include -#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) && \ - !defined(RT_USING_SPI2) +#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) #error "Please define at least one SPIx" #endif diff --git a/bsp/gd32e230k-start/drivers/drv_usart.c b/bsp/gd32e230k-start/drivers/drv_usart.c index c34ca232cb..eef2f741b8 100644 --- a/bsp/gd32e230k-start/drivers/drv_usart.c +++ b/bsp/gd32e230k-start/drivers/drv_usart.c @@ -11,6 +11,7 @@ * Date Author Notes * 2009-01-05 Bernard the first version * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 */ #include @@ -23,9 +24,7 @@ #define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) #define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) -#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \ - !defined(RT_USING_USART2) && !defined(RT_USING_UART3) && \ - !defined(RT_USING_UART4) +#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) #error "Please define at least one UARTx" #endif @@ -84,53 +83,6 @@ void USART1_IRQHandler(void) #endif /* RT_USING_UART1 */ -#if defined(RT_USING_USART2) -struct rt_serial_device serial2; - -void USART2_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - uart_isr(&serial2); - - /* leave interrupt */ - rt_interrupt_leave(); -} - -#endif /* RT_USING_UART2 */ - -#if defined(RT_USING_UART3) -struct rt_serial_device serial3; - -void UART3_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - uart_isr(&serial3); - - /* leave interrupt */ - rt_interrupt_leave(); -} - -#endif /* RT_USING_UART3 */ - -#if defined(RT_USING_UART4) -struct rt_serial_device serial4; - -void UART4_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - uart_isr(&serial4); - - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif /* RT_USING_UART4 */ - static const struct gd32_uart uarts[] = { #ifdef RT_USING_USART0 { @@ -155,42 +107,6 @@ static const struct gd32_uart uarts[] = { "uart1", }, #endif - - #ifdef RT_USING_USART2 - { - USART2, // uart peripheral index - USART2_IRQn, // uart iqrn - RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock - GPIOB, GPIO_PIN_10, // tx port, tx alternate, tx pin - GPIOB, GPIO_PIN_11, // rx port, rx alternate, rx pin - &serial2, - "uart2", - }, - #endif - - #ifdef RT_USING_UART3 - { - UART3, // uart peripheral index - UART3_IRQn, // uart iqrn - RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock - GPIOC, GPIO_PIN_10, // tx port, tx alternate, tx pin - GPIOC, GPIO_PIN_11, // rx port, rx alternate, rx pin - &serial3, - "uart3", - }, - #endif - - #ifdef RT_USING_UART4 - { - UART4, // uart peripheral index - UART4_IRQn, // uart iqrn - RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock - GPIOC, GPIO_PIN_12, // tx port, tx alternate, tx pin - GPIOD, GPIO_PIN_2, // rx port, rx alternate, rx pin - &serial4, - "uart4", - }, - #endif }; diff --git a/bsp/gd32e230k-start/project.uvoptx b/bsp/gd32e230k-start/project.uvoptx index aa084f2049..5da1234dd3 100644 --- a/bsp/gd32e230k-start/project.uvoptx +++ b/bsp/gd32e230k-start/project.uvoptx @@ -103,7 +103,7 @@ 1 0 0 - 14 + 19 @@ -384,7 +384,7 @@ Drivers - 0 + 1 0 0 0 diff --git a/bsp/gd32e230k-start/project.uvprojx b/bsp/gd32e230k-start/project.uvprojx index 4466ae7d45..115df957ba 100644 --- a/bsp/gd32e230k-start/project.uvprojx +++ b/bsp/gd32e230k-start/project.uvprojx @@ -10,7 +10,7 @@ rt-thread_gd32e230 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 6120000::V6.12::.\ARMCLANG 1 @@ -312,10 +312,10 @@ 1 - 1 + 7 0 0 - 0 + 1 0 0 0 @@ -684,9 +684,9 @@ 2 2 - --c99 - - + + + diff --git a/bsp/gd32e230k-start/rtconfig.h b/bsp/gd32e230k-start/rtconfig.h index b490faaf8a..ef5a6509f7 100644 --- a/bsp/gd32e230k-start/rtconfig.h +++ b/bsp/gd32e230k-start/rtconfig.h @@ -148,8 +148,13 @@ /* miscellaneous packages */ +/* sample package */ + /* samples: kernel and components samples */ + +/* example package: hello */ + #define RT_USING_USART0 #define RT_USING_USART1 #define RT_USING_SPI0 diff --git a/bsp/gd32e230k-start/template.uvoptx b/bsp/gd32e230k-start/template.uvoptx index 93d9c266ef..090bdb9227 100644 --- a/bsp/gd32e230k-start/template.uvoptx +++ b/bsp/gd32e230k-start/template.uvoptx @@ -103,7 +103,7 @@ 1 0 0 - 14 + 19 diff --git a/bsp/gd32e230k-start/template.uvprojx b/bsp/gd32e230k-start/template.uvprojx index cf0ba886d1..43c9f16629 100644 --- a/bsp/gd32e230k-start/template.uvprojx +++ b/bsp/gd32e230k-start/template.uvprojx @@ -312,10 +312,10 @@ 1 - 1 + 7 0 0 - 0 + 1 0 0 0 diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S index d9993247e2..4fc5a3adbd 100644 --- a/libcpu/arm/cortex-m23/context_gcc.S +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -1,19 +1,20 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2019, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes + * Date Author Notes * 2010-01-25 Bernard first version * 2012-06-01 aozima set pendsv priority to 0xFF. * 2012-08-17 aozima fixed bug: store r8 - r11. * 2013-02-20 aozima port to gcc. * 2013-06-18 aozima add restore MSP feature. * 2013-11-04 bright fixed hardfault bug for gcc. + * 2019-03-31 xuzhuoyi port to Cortex-M23. */ - .cpu cortex-m0 + .cpu cortex-m23 .fpu softvfp .syntax unified .thumb diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S index 50d3781359..4f30c0bc0c 100644 --- a/libcpu/arm/cortex-m23/context_iar.S +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -1,5 +1,5 @@ ;/* -; * Copyright (c) 2006-2018, RT-Thread Development Team +; * Copyright (c) 2006-2019, RT-Thread Development Team ; * ; * SPDX-License-Identifier: Apache-2.0 ; * @@ -9,10 +9,11 @@ ; * 2012-06-01 aozima set pendsv priority to 0xFF. ; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. +; * 2019-03-31 xuzhuoyi port to Cortex-M23. ; */ ;/** -; * @addtogroup CORTEX-M0 +; * @addtogroup CORTEX-M23 ; */ ;/*@{*/ diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S index 54145773d3..f243097cc6 100644 --- a/libcpu/arm/cortex-m23/context_rvds.S +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -1,5 +1,5 @@ ;/* -; * Copyright (c) 2006-2018, RT-Thread Development Team +; * Copyright (c) 2006-2019, RT-Thread Development Team ; * ; * SPDX-License-Identifier: Apache-2.0 ; * @@ -9,6 +9,7 @@ ; * 2012-06-01 aozima set pendsv priority to 0xFF. ; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. +; * 2019-03-31 xuzhuoyi port to Cortex-M23. ; */ ;/** diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c index 5d36fa11fe..842802c866 100644 --- a/libcpu/arm/cortex-m23/cpuport.c +++ b/libcpu/arm/cortex-m23/cpuport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2019, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,6 +9,7 @@ * 2012-05-31 aozima Merge all of the C source code into cpuport.c * 2012-08-17 aozima fixed bug: store r8 - r11. * 2012-12-23 aozima stack addr align to 8byte. + * 2019-03-31 xuzhuoyi port to Cortex-M23. */ #include -- cgit v1.3.1 From b10039f396cb1f32cb0a4b7ee3692bf96332fc1e Mon Sep 17 00:00:00 2001 From: qz721 <295354721@qq.com> Date: Mon, 1 Apr 2019 14:21:59 +0800 Subject: Disable the data alignment check. --- libcpu/arm/cortex-a/start_gcc.S | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libcpu') diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 0f4ff58364..7464ba6161 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -51,6 +51,11 @@ _reset: /* set the cpu to SVC32 mode and disable interrupt */ cps #Mode_SVC + /* disable the data alignment check */ + mrc p15, 0, r1, c1, c0, 0 + bic r1, #(1<<1) + mcr p15, 0, r1, c1, c0, 0 + /* setup stack */ bl stack_setup -- cgit v1.3.1 From 4acd8db61eb366878b849716db25558abaa5325b Mon Sep 17 00:00:00 2001 From: xuzhuoyi Date: Wed, 10 Apr 2019 22:33:25 +0800 Subject: [bsp][tms320f28379d] Add finsh init in rt_init_thread --- bsp/tms320f28379d/applications/application.c | 9 ++++--- bsp/tms320f28379d/drivers/board.c | 11 +++++++- bsp/tms320f28379d/drivers/drv_sci.c | 4 +-- libcpu/ti-dsp/c28x/context.s | 40 ++++++++++++++++++++++++---- libcpu/ti-dsp/c28x/cpuport.c | 4 +++ 5 files changed, 56 insertions(+), 12 deletions(-) (limited to 'libcpu') diff --git a/bsp/tms320f28379d/applications/application.c b/bsp/tms320f28379d/applications/application.c index 4ceb5eef75..5c7b769a4d 100644 --- a/bsp/tms320f28379d/applications/application.c +++ b/bsp/tms320f28379d/applications/application.c @@ -12,12 +12,15 @@ #include #include +#ifdef RT_USING_FINSH +#include "shell.h" +#endif + void rt_init_thread_entry(void* parameter) { - /* initialization RT-Thread Components */ - rt_components_init(); +#ifdef RT_USING_FINSH finsh_system_init(); - +#endif } int rt_application_init() diff --git a/bsp/tms320f28379d/drivers/board.c b/bsp/tms320f28379d/drivers/board.c index ee1c9f06af..b83cb7a966 100644 --- a/bsp/tms320f28379d/drivers/board.c +++ b/bsp/tms320f28379d/drivers/board.c @@ -13,8 +13,16 @@ #include "drv_sci.h" #include "F28x_Project.h" +extern rt_uint32_t rt_thread_switch_interrupt_flag; + extern interrupt void RTOSINT_Handler(); +void trap_rtosint() +{ + if(rt_thread_switch_interrupt_flag) + asm(" trap #16"); +} + /** * This is the timer interrupt service routine. * @@ -31,7 +39,7 @@ interrupt void cpu_timer2_isr(void) } /** - * This function will initial STM32 board. + * This function will initial TMS320F28379D board. */ void rt_hw_board_init() { @@ -68,4 +76,5 @@ void rt_hw_board_init() #ifdef RT_USING_CONSOLE rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif + rt_interrupt_leave_sethook((void (*)(void))trap_rtosint); } diff --git a/bsp/tms320f28379d/drivers/drv_sci.c b/bsp/tms320f28379d/drivers/drv_sci.c index e345097f06..0920d382f5 100644 --- a/bsp/tms320f28379d/drivers/drv_sci.c +++ b/bsp/tms320f28379d/drivers/drv_sci.c @@ -214,7 +214,6 @@ int rt_hw_sci_init(void) CpuSysRegs.PCLKCR7.bit.SCI_C = 1; PieVectTable.SCIA_RX_INT = &sciaRxFifoIsr; - //PieVectTable.SCIA_TX_INT = &sciaTxFifoIsr; EDIS; @@ -223,8 +222,7 @@ int rt_hw_sci_init(void) // PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // PIE Group 9, INT1 - //PieCtrlRegs.PIEIER9.bit.INTx2 = 1; // PIE Group 9, INT2 - IER = 0x100; // Enable CPU INT + IER |= 0x100; // Enable CPU INT EINT; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; diff --git a/libcpu/ti-dsp/c28x/context.s b/libcpu/ti-dsp/c28x/context.s index 019b5def13..fc1734f5ca 100644 --- a/libcpu/ti-dsp/c28x/context.s +++ b/libcpu/ti-dsp/c28x/context.s @@ -94,11 +94,10 @@ _rt_hw_interrupt_enable: .asmfunc _rt_hw_context_switch_interrupt: -_rt_hw_context_switch: MOVL XAR0, #0 MOV AR0, AL MOVL XAR4, *-SP[4] - ; set rt_thread_switch_interrupt_flag to 1 + ; set rt_thread_switch_interrupt_flag to 1 MOVL XAR5, #_rt_thread_switch_interrupt_flag MOVL XAR6, *XAR5 MOVL ACC, XAR6 @@ -114,6 +113,37 @@ _reswitch: MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread MOVL *XAR5, XAR4 + ;TRAP #16 + LRETR + .endasmfunc + +; +; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; r0 --> from +; r4 --> to + + + .asmfunc +_rt_hw_context_switch: + MOVL XAR0, #0 + MOV AR0, AL + MOVL XAR4, *-SP[4] + ; set rt_thread_switch_interrupt_flag to 1 + MOVL XAR5, #_rt_thread_switch_interrupt_flag + MOVL XAR6, *XAR5 + MOVL ACC, XAR6 + CMPB AL, #1 + B _reswitch2, EQ + MOVL XAR6, #1 + MOVL *XAR5, XAR6 + + MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread + MOVL *XAR5, XAR0 + +_reswitch2: + MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread + MOVL *XAR5, XAR4 + TRAP #16 LRETR .endasmfunc @@ -159,9 +189,9 @@ _RTOSINT_Handler: ;#endif MOV AL, *AR0 - MOV AR1, AL + MOV AR0, AL MOVZ AR1, @SP ; get from thread stack pointer - MOV *AR0, AR1 ; update from thread stack pointer + MOV *AR0, AR1 ; update from thread stack pointer switch_to_thread: MOV AR1, #_rt_interrupt_to_thread @@ -175,7 +205,7 @@ switch_to_thread: ;#endif MOV @SP, AR1 - INC SP + ;INC SP RT_CTX_RESTORE ; pop r4 - r11 register rtosint_exit: diff --git a/libcpu/ti-dsp/c28x/cpuport.c b/libcpu/ti-dsp/c28x/cpuport.c index 8885f647a9..2d42884bed 100644 --- a/libcpu/ti-dsp/c28x/cpuport.c +++ b/libcpu/ti-dsp/c28x/cpuport.c @@ -17,6 +17,9 @@ rt_uint32_t rt_thread_switch_interrupt_flag; /* exception hook */ static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; +extern rt_uint16_t rt_hw_get_st0(void); +extern rt_uint16_t rt_hw_get_st1(void); + struct exception_stack_frame { rt_uint32_t t_st0; @@ -59,6 +62,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, stk = stack_addr; stk = (rt_uint8_t *)RT_ALIGN((rt_uint32_t)stk, 8); //stk -= sizeof(struct stack_frame); + stk += 1; stack_frame = (struct stack_frame *)stk; -- cgit v1.3.1 From 752152b63e5b8f3a82de7b39255712f41e7efac2 Mon Sep 17 00:00:00 2001 From: xuzhuoyi Date: Sun, 14 Apr 2019 12:26:25 +0800 Subject: [bsp][tms320f28379d] Fix FPU config problem --- bsp/tms320f28379d/.cproject | 2 +- libcpu/ti-dsp/c28x/context.s | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'libcpu') diff --git a/bsp/tms320f28379d/.cproject b/bsp/tms320f28379d/.cproject index 15acd78f25..3641f26b27 100644 --- a/bsp/tms320f28379d/.cproject +++ b/bsp/tms320f28379d/.cproject @@ -32,7 +32,7 @@