From fe24ae7ca422a735f22fedb6ac03150ba49401a7 Mon Sep 17 00:00:00 2001 From: Watson Zeng Date: Thu, 16 Jan 2020 16:00:13 +0800 Subject: [PATCH] [bsp][synopsys] add basic new embarc bsp support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * the initial support of synopsys designware ARC processor using embARC_BSP, all synopsys ARC-based boards are supported: -ARC Software Development Platform -ARC EM Starter Kit -ARC EM Software Development Platform -ARC HS Development Kit -ARC IoT Development Kit * The embARC BSP is a new generation embARC software development package. ​It is designed to be the inter-layer between hardware and operating system. ​ BSP could hide the difference of hardware/boards, provide a unified interface to upper-layer. * the initial support of synopsys MWDT toolchain. The DesignWare® ARC® MetaWare Development Toolkit builds upon a 25-year legacy of industry-leading compiler and debugger products. It is a complete solution that contains all the components needed to support the development, debugging and tuning of embedded applications for the DesignWare ARC processors. * for detailed board information, pls go embarc.org. Signed-off-by: Watson Zeng --- bsp/synopsys/{emsk_em9d => boards}/.config | 254 ++- bsp/synopsys/{emsk_em9d => boards}/Kconfig | 1 + bsp/synopsys/boards/README.md | 128 ++ bsp/synopsys/{emsk_em9d => boards}/SConscript | 1 - bsp/synopsys/boards/SConstruct | 325 ++++ .../applications/SConscript | 0 .../applications/application.c | 0 .../applications/startup.c | 11 +- .../{emsk_em9d => boards}/drivers/Kconfig | 0 .../{emsk_em9d => boards}/drivers/SConscript | 0 bsp/synopsys/boards/drivers/rt_board.c | 324 ++++ bsp/synopsys/boards/drivers/rt_board.h | 16 + bsp/synopsys/boards/linker_template_gnu.ld | 169 ++ bsp/synopsys/boards/linker_template_mw.ld | 154 ++ bsp/synopsys/boards/rtconfig.h | 157 ++ bsp/synopsys/boards/rtconfig.py | 58 + 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 --- .../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 -- .../embarc/device/designware/iic/dw_iic.c | 1584 ----------------- .../embarc/device/designware/iic/dw_iic.h | 242 --- .../embarc/device/designware/iic/dw_iic_hal.h | 186 -- .../device/designware/iic/dw_iic_hal_cfg.h | 82 - .../embarc/device/designware/spi/dw_spi.c | 1337 -------------- .../embarc/device/designware/spi/dw_spi.h | 190 -- .../embarc/device/designware/spi/dw_spi_hal.h | 141 -- .../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 -- .../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 ----- .../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/README.md | 77 - bsp/synopsys/emsk_em9d/SConstruct | 53 - .../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 - .../emsk_em9d/drivers/embARC_BSP_config.h | 39 - .../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/figures/emsk_board.jpg | Bin 483486 -> 0 bytes bsp/synopsys/emsk_em9d/openocd.log | 9 - bsp/synopsys/emsk_em9d/rtconfig.h | 143 -- bsp/synopsys/emsk_em9d/rtconfig.py | 60 - libcpu/arc/em/SConscript | 4 +- .../arc/em/{contex_gcc.S => contex_gcc_mw.S} | 162 +- libcpu/arc/em/cpuport.c | 28 +- 74 files changed, 1618 insertions(+), 14996 deletions(-) rename bsp/synopsys/{emsk_em9d => boards}/.config (55%) rename bsp/synopsys/{emsk_em9d => boards}/Kconfig (94%) create mode 100644 bsp/synopsys/boards/README.md rename bsp/synopsys/{emsk_em9d => boards}/SConscript (82%) create mode 100644 bsp/synopsys/boards/SConstruct rename bsp/synopsys/{emsk_em9d => boards}/applications/SConscript (100%) rename bsp/synopsys/{emsk_em9d => boards}/applications/application.c (100%) rename bsp/synopsys/{emsk_em9d => boards}/applications/startup.c (81%) rename bsp/synopsys/{emsk_em9d => boards}/drivers/Kconfig (100%) rename bsp/synopsys/{emsk_em9d => boards}/drivers/SConscript (100%) create mode 100644 bsp/synopsys/boards/drivers/rt_board.c create mode 100644 bsp/synopsys/boards/drivers/rt_board.h create mode 100644 bsp/synopsys/boards/linker_template_gnu.ld create mode 100644 bsp/synopsys/boards/linker_template_mw.ld create mode 100644 bsp/synopsys/boards/rtconfig.h create mode 100644 bsp/synopsys/boards/rtconfig.py delete mode 100644 bsp/synopsys/embarc/SConscript delete mode 100644 bsp/synopsys/embarc/arc/arc_cache.c delete mode 100644 bsp/synopsys/embarc/arc/arc_exc_asm.S delete mode 100644 bsp/synopsys/embarc/arc/arc_exception.c delete mode 100644 bsp/synopsys/embarc/arc/arc_timer.c delete mode 100644 bsp/synopsys/embarc/arc/startup/arc_cxx_support.c delete mode 100644 bsp/synopsys/embarc/arc/startup/arc_startup.S delete mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c delete mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.c delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.c delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.c delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.h delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_common.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_asm_common.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_builtin.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_cache.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_em.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_exception.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_feature_config.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_timer.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_debug.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_error.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_toolchain.h delete mode 100644 bsp/synopsys/emsk_em9d/README.md delete mode 100644 bsp/synopsys/emsk_em9d/SConstruct delete mode 100644 bsp/synopsys/emsk_em9d/drivers/arc_core_config.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/board.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/board.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux_hal.h delete mode 100644 bsp/synopsys/emsk_em9d/emsk_em9d.ld delete mode 100644 bsp/synopsys/emsk_em9d/figures/emsk_board.jpg delete mode 100644 bsp/synopsys/emsk_em9d/openocd.log delete mode 100644 bsp/synopsys/emsk_em9d/rtconfig.h delete mode 100644 bsp/synopsys/emsk_em9d/rtconfig.py rename libcpu/arc/em/{contex_gcc.S => contex_gcc_mw.S} (61%) diff --git a/bsp/synopsys/emsk_em9d/.config b/bsp/synopsys/boards/.config similarity index 55% rename from bsp/synopsys/emsk_em9d/.config rename to bsp/synopsys/boards/.config index 8451f5d956..6ae650f8cc 100644 --- a/bsp/synopsys/emsk_em9d/.config +++ b/bsp/synopsys/boards/.config @@ -6,7 +6,8 @@ # # RT-Thread Kernel # -CONFIG_RT_NAME_MAX=8 +CONFIG_RT_NAME_MAX=16 +# 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 @@ -18,11 +19,14 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=256 -# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_IDLE_THREAD_STACK_SIZE=1024 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 CONFIG_RT_DEBUG=y CONFIG_RT_DEBUG_COLOR=y -# CONFIG_RT_DEBUG_INIT_CONFIG is not set +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 @@ -47,10 +51,11 @@ CONFIG_RT_USING_MESSAGEQUEUE=y # Memory Management # CONFIG_RT_USING_MEMPOOL=y -# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_MEMHEAP=y # CONFIG_RT_USING_NOHEAP is not set CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set # CONFIG_RT_USING_MEMTRACE is not set CONFIG_RT_USING_HEAP=y @@ -63,7 +68,8 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x40000 +CONFIG_RT_VER_NUM=0x40002 +CONFIG_RT_USING_CPU_FFS=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # @@ -99,47 +105,39 @@ 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 +# CONFIG_RT_USING_DFS is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y -CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_PIPE_BUFSZ=1024 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=8 CONFIG_RT_USING_SERIAL=y -CONFIG_RT_SERIAL_USING_DMA=y +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=1024 # 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_PIN is not set # 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_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set # CONFIG_RT_USING_WIFI is not set # @@ -151,10 +149,9 @@ CONFIG_RT_USING_PIN=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_RT_USING_MODULE is not set +# CONFIG_RT_LIBC_USING_TIME is not set # # Network @@ -163,88 +160,22 @@ CONFIG_RT_USING_LIBC=y # # Socket abstraction layer # -CONFIG_RT_USING_SAL=y +# CONFIG_RT_USING_SAL is not set # -# protocol stack implement +# Network interface device # -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 +# CONFIG_RT_USING_NETDEV is not set # # 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 +# CONFIG_RT_USING_LWIP 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 +# CONFIG_RT_USING_AT is not set # # VBUS(Virtual Software BUS) @@ -254,7 +185,6 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # # 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 @@ -268,10 +198,14 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # # 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_MYMQTT 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_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -289,25 +223,14 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # 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=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" +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set # # IoT Cloud @@ -316,6 +239,25 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # 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_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set # # security packages @@ -336,6 +278,9 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set # # tools packages @@ -344,6 +289,16 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # 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 +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set # # system packages @@ -357,17 +312,50 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # 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 +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +CONFIG_PKG_USING_EMBARC_BSP=y +CONFIG_PKG_EMBARC_BSP_PATH="/packages/system/embARC_bsp" +CONFIG_PKG_USING_EMBARC_BSP_UPSTREAM_VERSION=y +# CONFIG_PKG_USING_EMBARC_BSP_MASTER_VERSION is not set +CONFIG_PKG_EMBARC_BSP_VER="upstream" # # peripheral libraries and drivers # -# CONFIG_PKG_USING_STM32F4_HAL is not set -# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_SENSORS_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_SHT3X 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_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set # # miscellaneous packages @@ -378,13 +366,15 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON 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 -# +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set # # samples: kernel and components samples @@ -393,11 +383,15 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # 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_PKG_USING_VI is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL 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/boards/Kconfig similarity index 94% rename from bsp/synopsys/emsk_em9d/Kconfig rename to bsp/synopsys/boards/Kconfig index 1bdec3c71f..cfab678244 100644 --- a/bsp/synopsys/emsk_em9d/Kconfig +++ b/bsp/synopsys/boards/Kconfig @@ -23,6 +23,7 @@ config SOC_EMSK select ARCH_ARC_EM select RT_USING_COMPONENTS_INIT # select RT_USING_USER_MAIN + select RT_USING_CPU_FFS default y source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/synopsys/boards/README.md b/bsp/synopsys/boards/README.md new file mode 100644 index 0000000000..aee6059cfc --- /dev/null +++ b/bsp/synopsys/boards/README.md @@ -0,0 +1,128 @@ +# Synopsys ARC Boards support with embARC_BSP + +## embARC_BSP + +The embARC Board support Package (BSP) is a software distributions aimed at facilitating +the development and evaluation of embedded systems based on ARCv2 processors, which is +designed to provide a minimal board support package for ARC users by defining +consistent and simple software interfaces to the processors and onboard devices. + +The embARC BSP is a new generation embARC software development package. ​ +It is designed to be the inter-layer between hardware and operating system. ​ +BSP could hide the difference of hardware/boards, provide a unified interface to upper-layer. ​ +In the scenarios that no OS is required, embARC BSP can also standalone and work in baremetal. + +embARC_BSP features: + +* Support MetaWare & GNU toolchains​ +* Support all development boards and tcf​ +* Support various build systems and compiling environments, + such as ARC MetaWare & GNU IDE, makefile​ +* Designware and Subsystem drivers, including UART and GPIO, I2C, SPI, etc. ​ +* No middleware, no OS​ +* Easy to port to different platform / OS​ +* One example (UART, GPIO, timer)​ +* Code coverage reach 100% in test. ​ +* MISRA-C compliance​ +* C & C++ support, assembly support + +## Supported Boards + +* [ARC Software Development Platform](https://www.synopsys.com/dw/ipdir.php?ds=arc-software-development-platform) +* [ARC EM Starter Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc_em_starter_kit) +* [ARC EM Software Development Platform](https://www.synopsys.com/dw/ipdir.php?ds=arc-em-software-development-platform) +* [ARC HS Development Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc-hs-development-kit) +* [ARC IoT Development Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc_iot_development_kit) + + +## Software Requirement + +### embarc_bsp + +There are two ways to get embarc_bsp: + +#### use RT-Thread ENV tool: + +embARC_BSP has been configured as package module, you can just run the command `pkgs --update` in /bsp/synopsys/boards +folder using ENV tool. + +#### without RT-Thread ENV tool: + +We can get it from github: [embarc_bsp](https://github.com/foss-for-synopsys-dwc-arc-processors) + +The default path for embarc_bsp is /bsp/synopsys/boards/packages/embARC_bsp-upstream, +when you use other path, please set the environment variable `EMBARC_BSP_ROOT`. + +### Toolchain + +Now both GNU and MetaWare Toolchain are supported, set the System environment variable RTT_CC select the toolchain. + +GNU: + + set RTT_CC=gnu + +MetaWare: + + set RTT_CC=mw + +#### GNU + +The ARC GNU Toolchain offers all of the benefits of open source tools, including complete source code and a large install base. The ARC GNU IDE Installer consists of Eclipse IDE with [ARC GNU plugin for Eclipse](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/releases), [ARC GNU prebuilt toolchain](https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases) and [OpenOCD for ARC](https://github.com/foss-for-synopsys-dwc-arc-processors/openocd>) + +Here, the ARC GNU toolchain is installed to `c:\arc_gnu`. If not, please change the path configuration in rtconfig.py. + +When you use GNU Toolchain, you need to install [Zadig](http://zadig.akeo.ie) to replace the default FTDI driver with WinUSB driver. See [How to Use OpenOCD on Windows](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/wiki/How-to-Use-OpenOCD-on-Windows>) for more information. + +#### MetaWare +The [DesignWare ARC MetaWare Development Toolkit](https://www.synopsys.com/dw/ipdir.php?ds=sw_metaware) builds on a long legacy of industry-leading compiler and debugger products for embedded applications. It is a complete solution that contains all the components needed to support the development, debugging, and tuning of embedded applications for the DesignWare® ARC® processors. + +Here, the ARC MetaWare toolchain is installed to `C:\ARC\MetaWare`. If not, please change the path configuration in rtconfig.py. + + + + + +## Build & Debug + +### Build embarc_lib + +please run the following cmds to build embarc_lib + + cd /bsp/synopsys/boards + scons --embarc_build + +### Build + +please run the following cmds to build + + cd /bsp/synopsys/boards + scons + +### Debug + +After compile, please use the following cmds to debug + + scons --gdb #use gdb debugger + scons --mdb #use mdb debugger + + +### How to choose different boards + +There are some parameters we can use in scons, for example: + + scons --BOARD=emsk --BD_VER=23 --CUR_CORE=arcem9d --TOOLCHAIN=mw --OLEVEL=O2 + + * BOARD: choose the board, we can set: `emsk, iotdk, emsdp, hsdk, axs`. + * BD_VER: choose the board version, some boards have different versions, for example, + we can set: `10, 22, 23` for emsk board. + * CUR_CORE: choose the arc cores, some boards have different cores, for example, + we can set: `arcem7d, arcem9d, arcem11d` for emsk board. + * TOOLCHAIN: choose the toolchain to build embarc_lib, we can set: `mw, gnu`. + * OLEVEL: choose the build optimize level, we can set: `O0, O2, Os`. + +For more information, you can run the command `scons -h`. + + +## Maintainer +- [vonhust](https://github.com/vonhust) +- [IRISZZW](https://github.com/IRISZZW) diff --git a/bsp/synopsys/emsk_em9d/SConscript b/bsp/synopsys/boards/SConscript similarity index 82% rename from bsp/synopsys/emsk_em9d/SConscript rename to bsp/synopsys/boards/SConscript index 86b6c891cd..2e95f4716c 100644 --- a/bsp/synopsys/emsk_em9d/SConscript +++ b/bsp/synopsys/boards/SConscript @@ -8,7 +8,6 @@ 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) diff --git a/bsp/synopsys/boards/SConstruct b/bsp/synopsys/boards/SConstruct new file mode 100644 index 0000000000..a66e7ec76a --- /dev/null +++ b/bsp/synopsys/boards/SConstruct @@ -0,0 +1,325 @@ +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) + +if os.getenv('EMBARC_BSP_ROOT'): + EMBARC_BSP_ROOT = os.getenv('EMBARC_BSP_ROOT') +else: + EMBARC_BSP_ROOT = RTT_ROOT + '/bsp/synopsys/boards/packages/embARC_bsp-upstream' + +if not os.path.isdir(EMBARC_BSP_ROOT): + print('Cannot found embarc_bsp root directory, please check EMBARC_BSP_ROOT') + print(EMBARC_BSP_ROOT) + exit(-1) + +SUPPORTED_BOARD_DIR = EMBARC_BSP_ROOT + '/board' +SUPPORTED_BOARD = [d for d in os.listdir(SUPPORTED_BOARD_DIR) if os.path.isdir(os.path.join(SUPPORTED_BOARD_DIR,d))] +print 'supported BOARD = ' + str(SUPPORTED_BOARD) + +AddOption('--BOARD', + dest = 'BOARD', + type='string', + nargs=1, + action = 'store', + default = 'emsk', + help = 'select board') + +AddOption('--BD_VER', + dest = 'BD_VER', + type='string', + nargs=1, + action = 'store', + default = '23', + help = 'select bd_ver') + +AddOption('--CUR_CORE', + dest = 'CUR_CORE', + type='string', + nargs=1, + action = 'store', + default = 'arcem9d', + help = 'select cur_core') + +AddOption('--TOOLCHAIN', + dest = 'TOOLCHAIN', + type='string', + nargs=1, + action = 'store', + default = 'gnu', + help = 'select toolchain') + +AddOption('--OLEVEL', + dest = 'OLEVEL', + type='string', + nargs=1, + action = 'store', + default = 'O2', + help = 'select optimize level') + +AddOption('--mdb', + dest = 'mdb', + action = 'store_true', + default = False, + help = 'use mdb to debug the elf') + +AddOption('--gdb', + dest = 'gdb', + action = 'store_true', + default = False, + help = 'use gdb to debug the elf') + +AddOption('--embarc_build', + dest = 'embarc_build', + action = 'store_true', + default = False, + help = 'to generate embarc_lib') + +AddOption('--embarc_clean', + dest = 'embarc_clean', + action = 'store_true', + default = False, + help = 'to clean embarc_lib') + +if GetOption('BOARD'): + board = GetOption('BOARD') + if board not in SUPPORTED_BOARD: + print 'board %s not supported, available boards:' % board + print SUPPORTED_BOARD + exit(0) + else: + BOARD = board + print 'get BOARD = [%s]' % board + +if BOARD == 'emsdp': + SUPPORTED_BD_VER = ['rev2'] +else: + SUPPORTED_BD_VER_DIR = SUPPORTED_BOARD_DIR + '/' + BOARD + '/configs' + SUPPORTED_BD_VER = [d for d in os.listdir(SUPPORTED_BD_VER_DIR) if os.path.isdir(os.path.join(SUPPORTED_BD_VER_DIR,d))] +print 'supported BD_VER = ' + str(SUPPORTED_BD_VER) + +if GetOption('BD_VER'): + bd_ver = GetOption('BD_VER') + if bd_ver not in SUPPORTED_BD_VER: + print 'bd_ver %s not supported, available bd_ver:' % bd_ver + print SUPPORTED_BD_VER + exit(0) + else: + BD_VER = bd_ver + print 'get BD_VER = [%s]' % BD_VER + +if BOARD == 'emsdp': + SUPPORTED_CORE_DIR = SUPPORTED_BOARD_DIR + '/' + BOARD + '/rev2/configs' + SUPPORTED_CORE = [d for d in os.listdir(SUPPORTED_CORE_DIR) if os.path.isdir(os.path.join(SUPPORTED_CORE_DIR,d))] +else: + SUPPORTED_CORE_DIR = SUPPORTED_BD_VER_DIR + '/' + BD_VER + '/tcf' + SUPPORTED_CORE = [os.path.splitext(d)[0] for d in os.listdir(SUPPORTED_CORE_DIR)] + +print 'supported CUR_CORE = ' + str(SUPPORTED_CORE) + +if GetOption('CUR_CORE'): + cur_core = GetOption('CUR_CORE') + if cur_core not in SUPPORTED_CORE: + print 'cur_core %s not supported, available cur_core:' % cur_core + print SUPPORTED_CORE + exit(0) + else: + CUR_CORE = cur_core + print 'get CUR_CORE = [%s]' % CUR_CORE + +SUPPORTED_TOOLCHAIN = ['mw', 'gnu'] + +print 'supported TOOLCHAIN = ' + str(SUPPORTED_TOOLCHAIN) + +if GetOption('TOOLCHAIN'): + toolchain = GetOption('TOOLCHAIN') + if toolchain not in SUPPORTED_TOOLCHAIN: + print 'toolchain %s not supported, available toolchain:' % toolchain + print SUPPORTED_TOOLCHAIN + exit(0) + else: + TOOLCHAIN = toolchain + print 'get TOOLCHAIN = [%s]' % TOOLCHAIN + +SUPPORTED_OLEVEL = ['O0', 'O2', 'Os'] + +print 'supported OLEVEL = ' + str(SUPPORTED_OLEVEL) + +if GetOption('OLEVEL'): + olevel = GetOption('OLEVEL') + if olevel not in SUPPORTED_OLEVEL: + print 'olevel %s not supported, available olevel:' % toolchain + print SUPPORTED_OLEVEL + exit(0) + else: + OLEVEL = olevel + print 'get OLEVEL = [%s]' % olevel + + + +EMBARC_LIB_PATH = EMBARC_BSP_ROOT + '/obj_%s_%s/%s_%s'%(BOARD, BD_VER, TOOLCHAIN, CUR_CORE) +# print 'EMBARC_LIB_PATH = %s'%EMBARC_LIB_PATH + +TARGET = 'rtthread_snps_embarc.elf' +# print 'TARGET = %s'%TARGET + +# ip_ph_dir = EMBARC_BSP_ROOT + '/device/peripheral' +# ip_ph_path = [os.path.join(ip_ph_dir,d) for d in os.listdir(ip_ph_dir) if os.path.isdir(os.path.join(ip_ph_dir,d))] + +if BOARD == 'emsdp': + board_inc_path = [SUPPORTED_CORE_DIR, SUPPORTED_CORE_DIR + '/%s/include'%CUR_CORE] +else: + board_inc_path = [EMBARC_BSP_ROOT + '/board/%s/configs/%s'%(BOARD, BD_VER)] + +# print 'board_inc_path = %s' % board_inc_path +# print 'ip_dw_path = %s' % ip_dw_path +# print 'ip_ss_path = %s' % ip_ss_path +# print 'ip_ph_path = %s' % ip_ph_path + +EMBARC_CPPPATH = [ EMBARC_BSP_ROOT, + EMBARC_BSP_ROOT + '/include', + EMBARC_BSP_ROOT + '/board', + EMBARC_LIB_PATH + '/embARC_generated', + ] + board_inc_path +#print "EMBARC_CPPPATH: %s"%EMBARC_CPPPATH + +if TOOLCHAIN == 'mw': + EXEC_PATH = 'C:/ARC/MetaWare/arc/bin' + MAKE = 'gmake' + PREFIX = '' + CC = 'ccac' + CXX = 'ccac' + AS = 'ccac' + AR = 'arac' + LINK = 'ccac' + TARGET_EXT = 'elf' + SIZE = 'sizeac' + OBJDUMP = 'elfdumpac' + OBJCPY = 'elf2bin' + DBG = 'mdb' + + OPT_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/ccac.arg ' + MDB_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/mdb.arg ' + COMMON_COMPILE_OPT = ' -Hnoccm -Hnosdata -Wincompatible-pointer-types -Hnocopyr -Hpurge -fdata-sections -g -%s '%(OLEVEL) + COMMON_DEFINES = ' -DBOARD_%s -D__MW__ -DEMBARC_TCF_GENERATED ' % BOARD.upper() + + CFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -Hnocplus ' + CXXFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + AFLAGS = ' -c' + OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -Hasmcpp -I%s -I%s/embARC_generated -I%s/include '%(EMBARC_BSP_ROOT, EMBARC_LIB_PATH, EMBARC_BSP_ROOT) + + LINKER_SCRIPT_FILE = RTT_ROOT + '/bsp/synopsys/boards/linker_template_mw.ld' + LINK_SCRIPT = EMBARC_LIB_PATH + '/linker_mw.ldf' + + LFLAGS = ' -Hhostlink ' + OPT_ARG_FILE + ' -Hnocopyr -Hnosdata -Hnocrt -Hldopt=-Coutput=rtthread_snps_embarc.map -Hldopt=-Csections -Hldopt=-Ccrossfunc -Hldopt=-Csize -zstdout %s' % LINK_SCRIPT + +elif TOOLCHAIN == 'gnu': + EXEC_PATH = 'C:/arc_gnu/bin' + MAKE = 'make' + 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' + + OPT_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/gcc.arg ' + MDB_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/mdb.arg ' + COMMON_COMPILE_OPT = ' -ffunction-sections -fdata-sections -mno-sdata -g -%s '%(OLEVEL) + COMMON_DEFINES = ' -DBOARD_%s -D__GNU__ -DEMBARC_TCF_GENERATED ' % BOARD.upper() + + CFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -std=gnu99 ' + CXXFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + AFLAGS = ' -c ' + OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -x assembler-with-cpp -I%s -I%s/embARC_generated -I%s/include '%(EMBARC_BSP_ROOT, EMBARC_LIB_PATH, EMBARC_BSP_ROOT) + + LINKER_SCRIPT_FILE = RTT_ROOT + '/bsp/synopsys/boards/linker_template_gnu.ld' + LINK_SCRIPT = EMBARC_LIB_PATH + '/linker_gnu.ldf' + + LFLAGS = ' --specs=nsim.specs ' + OPT_ARG_FILE + ' -mno-sdata -nostartfiles -Wl,--gc-sections,-Map=rtthread_snps_embarc.map,-cref,-u,system_vectors -T %s ' % LINK_SCRIPT + + OPENOCD_SCRIPT_ROOT = EXEC_PATH + '/../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 + +else : + print 'TOOLCHAIN %s is not supported, available toolchain:' % TOOLCHAIN + print SUPPORTED_TOOLCHAIN + exit(-1) + +env = Environment(ENV = os.environ, tools = ['mingw'], + AS = AS, ASFLAGS = AFLAGS, + CC = CC, CCFLAGS = CFLAGS, + AR = AR, ARFLAGS = '-rc', + LINK = LINK, LINKFLAGS = LFLAGS, + LIBS = ['embarc'], LIBPATH = EMBARC_LIB_PATH, + CPPPATH = EMBARC_CPPPATH + ) +env.PrependENVPath('PATH', EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +embarc_cd_cmd = ' cd %s '%EMBARC_BSP_ROOT +embarc_make_cmd = ' %s -f options/options.mk BOARD=%s BD_VER=%s CUR_CORE=%s TOOLCHAIN=%s V=1 OLEVEL=%s LINKER_SCRIPT_FILE=%s embarc_lib '%(MAKE,BOARD, BD_VER, CUR_CORE, TOOLCHAIN, OLEVEL, LINKER_SCRIPT_FILE) +embarc_clean_cmd = ' %s -f options/options.mk distclean '%MAKE + +if GetOption('embarc_build'): + print 'os.system: ' + embarc_cd_cmd + ' && ' + embarc_make_cmd + os.system(embarc_cd_cmd + ' && ' + embarc_make_cmd) + exit(0) + +if GetOption('embarc_clean'): + os.system(embarc_cd_cmd + ' && ' + embarc_clean_cmd) + exit(0) + +if GetOption('gdb'): + if os.path.isfile(TARGET): + os.system(DBG + DBG_HW_FLAGS + TARGET) + else: + print TARGET + 'not exist, please build first!!' + exit(0) + +if GetOption('mdb'): + if os.path.isfile(TARGET): + startup_path = EMBARC_BSP_ROOT + '/arc/startup' + if BOARD == 'nsim': + os.system('mdb -source_path=%s -nooptions -nogoifmain -toggle=include_local_symbols=1 -nsim -off=binary_stdin -off=binary_stdout \ + -on=load_at_paddr -on=reset_upon_restart -off=flush_pipe -off=cr_for_more -OKN %s '%(startup_path, MDB_ARG_FILE) + rtconfig.TARGET) + else: + os.system('mdb -source_path=%s -nooptions -nogoifmain -toggle=include_local_symbols=1 -hard -digilent '%startup_path + rtconfig.TARGET) + else: + print TARGET + 'not exist, please build first!!' + exit(0) + +# os.system(embarc_cd_cmd + ' && ' + embarc_make_cmd) + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# if the linker script changed, relink the target +Depends(TARGET, LINK_SCRIPT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/synopsys/emsk_em9d/applications/SConscript b/bsp/synopsys/boards/applications/SConscript similarity index 100% rename from bsp/synopsys/emsk_em9d/applications/SConscript rename to bsp/synopsys/boards/applications/SConscript diff --git a/bsp/synopsys/emsk_em9d/applications/application.c b/bsp/synopsys/boards/applications/application.c similarity index 100% rename from bsp/synopsys/emsk_em9d/applications/application.c rename to bsp/synopsys/boards/applications/application.c diff --git a/bsp/synopsys/emsk_em9d/applications/startup.c b/bsp/synopsys/boards/applications/startup.c similarity index 81% rename from bsp/synopsys/emsk_em9d/applications/startup.c rename to bsp/synopsys/boards/applications/startup.c index f561436272..817bf74c9a 100644 --- a/bsp/synopsys/emsk_em9d/applications/startup.c +++ b/bsp/synopsys/boards/applications/startup.c @@ -7,7 +7,12 @@ #include #include -#include +#include + +#ifdef RT_USING_HEAP +#define rt_system_heap_size 1024*64 +static rt_uint32_t rt_system_heap[rt_system_heap_size/4] = {0}; +#endif extern int rt_application_init(void); @@ -33,7 +38,7 @@ void rtthread_startup(void) /* initialize memory system */ #ifdef RT_USING_HEAP - rt_system_heap_init(HEAP_BEGIN, HEAP_END); + rt_system_heap_init((void *)rt_system_heap, (void *)(rt_system_heap+rt_system_heap_size)); #endif /* initialize scheduler system */ @@ -58,7 +63,7 @@ void rtthread_startup(void) return ; } -int board_main(void) +int main(void) { /* disable interrupt first */ rt_hw_interrupt_disable(); diff --git a/bsp/synopsys/emsk_em9d/drivers/Kconfig b/bsp/synopsys/boards/drivers/Kconfig similarity index 100% rename from bsp/synopsys/emsk_em9d/drivers/Kconfig rename to bsp/synopsys/boards/drivers/Kconfig diff --git a/bsp/synopsys/emsk_em9d/drivers/SConscript b/bsp/synopsys/boards/drivers/SConscript similarity index 100% rename from bsp/synopsys/emsk_em9d/drivers/SConscript rename to bsp/synopsys/boards/drivers/SConscript diff --git a/bsp/synopsys/boards/drivers/rt_board.c b/bsp/synopsys/boards/drivers/rt_board.c new file mode 100644 index 0000000000..1e1b7e494b --- /dev/null +++ b/bsp/synopsys/boards/drivers/rt_board.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include "rt_board.h" +#include "arc/arc_timer.h" +#include "arc/arc_exception.h" + +#include "embARC_error.h" + +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 const struct rt_uart_ops uart_ops = +{ + _configure, + _control, + _putc, + _getc, +}; + +static struct rt_serial_device uart0; +static struct rt_serial_device uart1; +static struct rt_serial_device uart2; +static struct rt_serial_device uart3; + +static void uart0_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart0, RT_SERIAL_EVENT_RX_IND); +} + +static void uart1_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart1, RT_SERIAL_EVENT_RX_IND); +} + +static void uart2_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart2, RT_SERIAL_EVENT_RX_IND); +} + +static void uart3_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart3, RT_SERIAL_EVENT_RX_IND); +} + + +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; + + uart0.ops = &uart_ops; + uart0.config = config; + + uart1.ops = &uart_ops; + uart1.config = config; + + uart2.ops = &uart_ops; + uart2.config = config; + + uart3.ops = &uart_ops; + uart3.config = config; + + /* uart0 init */ + uart = uart_get_dev(0); + + if (uart != NULL) { + /* 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 *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart0_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)0); + } + + /* uart1 init */ + uart = uart_get_dev(1); + + if (uart != NULL) { + /* 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 *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart1_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)1); + } + + /* uart2 init */ + uart = uart_get_dev(2); + + if (uart != NULL) { + /* 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 *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart2_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart2, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)2); + } + + /* uart3 init */ + uart = uart_get_dev(3); + + if (uart != NULL) { + /* 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 *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart3_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart3, "uart3", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)3); + } + + return RT_EOK; +} + +#if defined BOARD_EMSK +#define CONSOLE_UART "uart1" +struct rt_serial_device *console_uart = &uart1; +#elif defined BOARD_IOTDK || defined BOARD_EMSDP || defined BOARD_NSIM +#define CONSOLE_UART "uart0" +struct rt_serial_device *console_uart = &uart0; +#elif defined BOARD_AXS +#define CONSOLE_UART "uart2" +struct rt_serial_device *console_uart = &uart2; +#elif defined BOARD_HSDK +#define CONSOLE_UART "uart3" +struct rt_serial_device *console_uart = &uart3; +#else +#error "no supported board selected!" +#endif + +void rt_hw_console_output(const char *str) +{ + while(*str != '\0') + { + if (*str == '\n') { + _putc(console_uart,'\r'); + } + _putc(console_uart,*str); + str++; + } +} + +void rt_hw_board_init() +{ + rt_hw_uart_init(); + rt_components_board_init(); + rt_console_set_device(CONSOLE_UART); +} + + + +static void rt_hw_timer_isr(int vector, void *param) +{ + timer_int_clear(BOARD_OS_TIMER_ID); + rt_tick_increase(); +} + +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 */ + timer_stop(BOARD_OS_TIMER_ID); + timer_start(BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cyc); + + int_handler_install(BOARD_OS_TIMER_INTNO, (INT_HANDLER_T)rt_hw_timer_isr); + int_pri_set(BOARD_OS_TIMER_INTNO, INT_PRI_MIN + 1); /* currently, firq(INT_PRI_MIN) not supported*/ + int_enable(BOARD_OS_TIMER_INTNO); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_timer_init); diff --git a/bsp/synopsys/boards/drivers/rt_board.h b/bsp/synopsys/boards/drivers/rt_board.h new file mode 100644 index 0000000000..734ffc8aa5 --- /dev/null +++ b/bsp/synopsys/boards/drivers/rt_board.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RT_BOARD_H__ +#define __RT_BOARD_H__ + +#include "board.h" + +void rt_hw_board_init(); + +int rt_hw_uart_init(void); + +#endif diff --git a/bsp/synopsys/boards/linker_template_gnu.ld b/bsp/synopsys/boards/linker_template_gnu.ld new file mode 100644 index 0000000000..e253bc635c --- /dev/null +++ b/bsp/synopsys/boards/linker_template_gnu.ld @@ -0,0 +1,169 @@ +#define __ASSEMBLY__ +#include + +MEMORY +{ +#if (REGION_ICCM_SIZE != 0) + REGION_ICCM : ORIGIN = REGION_ICCM_START, LENGTH = REGION_ICCM_SIZE +#endif +#if (REGION_DCCM_SIZE !=0) + REGION_DCCM : ORIGIN = REGION_DCCM_START, LENGTH = REGION_DCCM_SIZE +#endif +#if (REGION_XCCM_SIZE != 0) + REGION_XCCM : ORIGIN = REGION_XCCM_START, LENGTH = REGION_XCCM_SIZE +#endif +#if (REGION_YCCM_SIZE != 0) + REGION_YCCM : ORIGIN = REGION_YCCM_START, LENGTH = REGION_YCCM_SIZE +#endif +#if (REGION_EXT_ROM_SIZE != 0) + REGION_EXT_ROM : ORIGIN = REGION_EXT_ROM_START, LENGTH = REGION_EXT_ROM_SIZE +#endif +#if (REGION_EXT_RAM_SIZE != 0) + REGION_EXT_RAM : ORIGIN = REGION_EXT_RAM_START, LENGTH = REGION_EXT_RAM_SIZE +#endif +} + +ENTRY(_start) + +SECTIONS +{ + .init : + { + . = . + IMAGE_HEAD_SIZE; + _f_init = .; + KEEP (*(.init_vector .init_vector.*)) + KEEP (*(.init_bootstrap .init_bootstrap.*)) + _e_init = .; + } > REGION_ROM + + .vector : ALIGN(1024) + { + _f_vector = .; + *(.vector .vector.*) + _e_vector = .; + } > REGION_ROM + +#if (REGION_XCCM_SIZE != 0) + .x_ccm (NOLOAD) : ALIGN(8) + { + _f_x_ccm = .; + *(.x_ccm .x_cmm.*) + _e_x_ccm = .; + } > REGION_XCCM +#endif + +#if (REGION_YCCM_SIZE != 0) + .y_ccm (NOLOAD) : ALIGN(8) + { + _f_y_ccm = .; + *(.y_ccm .y_ccm.*) + _e_y_ccm = .; + } > REGION_YCCM +#endif + .text : ALIGN(4) + { + _f_text = .; + *(.text .text.* .gnu.linkonce.t.*) + _e_text = .; + } > REGION_ROM + + .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); + + . = 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 = .; + } > REGION_ROM + + .data : ALIGN(4) + { + _f_data = .; + *(.data .data.* .gnu.linkonce.d.*) + _f_sdata = .; + __SDATA_BEGIN__ = .; + *(.sdata .sdata.* .gnu.linkonce.s.*) + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + _f_sbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + _e_sbss = .; + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); +#if defined(EMBARC_UNIT_TEST) + . = ALIGN(8); + _f_embarc_unittest = .; + KEEP(*(.embarc_unittest)) + _e_embarc_unittest = .; +#endif + _e_sdata = .; + _e_data = .; + } > REGION_RAM AT > REGION_ROM + + .bss (NOLOAD) : ALIGN(8) + { + _f_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _e_bss = .; + } > REGION_RAM + + .stack (NOLOAD) : + { + . = ALIGN(4); + _f_stack = .; + . = . + _STACKSIZE; + _e_stack = .; + } > REGION_RAM + + .heap (NOLOAD) : + { + . = ALIGN(4); + __start_heap = . ; + _f_heap = .; + . = . + _HEAPSIZE; + _e_heap = .; + __end_heap = . ; + } > REGION_RAM + + _load_addr_text = LOADADDR(.text); + _load_addr_rodata = LOADADDR(.rodata); + _load_addr_data = LOADADDR(.data); +} diff --git a/bsp/synopsys/boards/linker_template_mw.ld b/bsp/synopsys/boards/linker_template_mw.ld new file mode 100644 index 0000000000..248dc5ac4c --- /dev/null +++ b/bsp/synopsys/boards/linker_template_mw.ld @@ -0,0 +1,154 @@ +#define __ASSEMBLY__ +#include + +MEMORY { +#if (REGION_ICCM_SIZE != 0) + REGION_ICCM : ORIGIN = REGION_ICCM_START, LENGTH = REGION_ICCM_SIZE +#endif +#if (REGION_DCCM_SIZE !=0) + REGION_DCCM : ORIGIN = REGION_DCCM_START, LENGTH = REGION_DCCM_SIZE +#endif +#if (REGION_XCCM_SIZE != 0) + REGION_XCCM : ORIGIN = REGION_XCCM_START, LENGTH = REGION_XCCM_SIZE +#endif +#if (REGION_YCCM_SIZE != 0) + REGION_YCCM : ORIGIN = REGION_YCCM_START, LENGTH = REGION_YCCM_SIZE +#endif +#if (REGION_EXT_ROM_SIZE != 0) + REGION_EXT_ROM : ORIGIN = REGION_EXT_ROM_START, LENGTH = REGION_EXT_ROM_SIZE +#endif +#if (REGION_EXT_RAM_SIZE != 0) + REGION_EXT_RAM : ORIGIN = REGION_EXT_RAM_START, LENGTH = REGION_EXT_RAM_SIZE +#endif +} + +ENTRY(_start) + +SECTIONS { + + GROUP : { + .image_head: { + . = . + IMAGE_HEAD_SIZE; + } + .init_bootstrap:{ + _f_init = .; + *(.init_vector .init_vector.*) + *(.init_bootstrap .init_bootstrap.*) + _e_init = .; + } + .vector ALIGN(1024): { + _f_vector = .; + *(.vector .vector.*) + _e_vector = .; + } + } > REGION_ROM + +#if (REGION_XCCM_SIZE != 0) + GROUP (NOLOAD): { + .x_ccm ALIGN(8): { + _f_x_ccm = .; + *(.x_ccm) + *(.x_ccm.*) + _e_x_ccm = .; + } + } > REGION_XCCM +#endif + +#if (REGION_YCCM_SIZE != 0) + GROUP (NOLOAD): { + .y_ccm ALIGN(8): { + _f_y_ccm = .; + *(.y_ccm) + *(.y_ccm.*) + _e_y_ccm = .; + } + } > REGION_YCCM +#endif + + GROUP : { + + .text ALIGN(4): { + _f_text = .; + *(TYPE text) + *(.text*) + _e_text = .; + } + + .rodata ALIGN(4): { + _f_rodata = .; + + _fctors = .; + *(.ctors*) + _ectors = .; + _fdtors = .; + *(.dtors*) + _edtors = .; + _feh_frame = .; + *(.eh_frame*) + _eeh_frame = .; + + *(TYPE lit) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + *(FSymTab*) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + *(VSymTab*) + __vsymtab_end = .; + + . = ALIGN(4); + __rt_init_start = .; + *(.rti_fn*) + __rt_init_end = .; + . = ALIGN(4); + + _e_rodata = .; + } + + } > REGION_ROM + + + GROUP : { + .data ALIGN(8): { + _f_data = .; + _f_sdata = .; + *(.sdata) + *(.sbss) + _e_sdata = .; + *(TYPE data) + } +#if defined(EMBARC_UNIT_TEST) + .unit_test ALIGN(8): { + _f_embarc_unittest = .; + KEEP(*(".embarc_unittest")) + _e_embarc_unittest = .; + } +#endif + .tls ALIGN(8): { + *(.tls*) + _e_data = .; + } + } > REGION_RAM AT > REGION_ROM + + GROUP (NOLOAD) : { + .bss ALIGN(8): { + _f_bss = .; + *(TYPE bss) + _e_bss = .; + } + .stack ALIGN(4) SIZE(_STACKSIZE): {} + .heap? ALIGN(4) SIZE(_HEAPSIZE): {} + } > REGION_RAM + + _f_stack = ADDR(.stack); + _e_stack = ADDR(.stack) + SIZEOF(.stack); + _f_heap = ADDR(.heap); + _e_heap = ADDR(.heap) + SIZEOF(.heap); + + _load_addr_text = LOADADDR(.text); + _load_addr_rodata = LOADADDR(.rodata); + _load_addr_data = LOADADDR(.data); +} diff --git a/bsp/synopsys/boards/rtconfig.h b/bsp/synopsys/boards/rtconfig.h new file mode 100644 index 0000000000..6df6176c16 --- /dev/null +++ b/bsp/synopsys/boards/rtconfig.h @@ -0,0 +1,157 @@ +#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 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_DEBUG +#define RT_DEBUG_COLOR +#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_MEMHEAP +#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 "uart1" +#define RT_VER_NUM 0x40002 +#define RT_USING_CPU_FFS + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT + +/* 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_ARG_MAX 10 + +/* Device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 1024 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 8 +#define RT_USING_SERIAL +#define RT_SERIAL_RB_BUFSZ 1024 + +/* Using USB */ + + +/* POSIX layer and C standard library */ + + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP 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 */ + +#define PKG_USING_EMBARC_BSP +#define PKG_USING_EMBARC_BSP_UPSTREAM_VERSION + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + +#define SOC_EMSK +#define EMSK_USING_UART0 +#define EMSK_USING_UART1 + +#endif diff --git a/bsp/synopsys/boards/rtconfig.py b/bsp/synopsys/boards/rtconfig.py new file mode 100644 index 0000000000..0bafd172b5 --- /dev/null +++ b/bsp/synopsys/boards/rtconfig.py @@ -0,0 +1,58 @@ +import os + +# toolchains options +ARCH='arc' +CPU='em' +CROSS_TOOL='gcc' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = 'C:/arc_gnu/bin' +elif CROSS_TOOL =='mw': + PLATFORM = 'mw' + EXEC_PATH = 'C:/ARC/MetaWare/arc/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' + + TARGET = 'rtthread_snps_embarc.elf' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_snps_embarc.bin\n' +\ + SIZE + ' $TARGET \n' + +elif PLATFORM == 'mw': + # toolchains + CC = 'ccac' + CXX = 'ccac' + AS = 'ccac' + AR = 'arac' + LINK = 'ccac' + TARGET_EXT = 'elf' + SIZE = 'sizeac' + OBJDUMP = 'elfdumpac' + OBJCPY = 'elf2bin' + DBG = 'mdb' + + TARGET = 'rtthread_snps_embarc.elf' + + POST_ACTION = OBJCPY + ' $TARGET rtthread_snps_embarc.bin\n' +\ + SIZE + ' $TARGET \n' diff --git a/bsp/synopsys/embarc/SConscript b/bsp/synopsys/embarc/SConscript deleted file mode 100644 index 9e086739af..0000000000 --- a/bsp/synopsys/embarc/SConscript +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 632a3e3291..0000000000 --- a/bsp/synopsys/embarc/arc/arc_cache.c +++ /dev/null @@ -1,420 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 7410db3154..0000000000 --- a/bsp/synopsys/embarc/arc/arc_exc_asm.S +++ /dev/null @@ -1,201 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index a256b0b394..0000000000 --- a/bsp/synopsys/embarc/arc/arc_exception.c +++ /dev/null @@ -1,501 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 3d0c4b4f83..0000000000 --- a/bsp/synopsys/embarc/arc/arc_timer.c +++ /dev/null @@ -1,211 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index af842fddc6..0000000000 --- a/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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 deleted file mode 100644 index 26a6fdb519..0000000000 --- a/bsp/synopsys/embarc/arc/startup/arc_startup.S +++ /dev/null @@ -1,262 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index ce79414fc6..0000000000 --- a/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c +++ /dev/null @@ -1,481 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 55c551a67e..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic.h +++ /dev/null @@ -1,242 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index f7ec0d27a2..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h +++ /dev/null @@ -1,186 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 1073162176..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index bea413b411..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi.c +++ /dev/null @@ -1,1337 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index ef2faa90e6..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi.h +++ /dev/null @@ -1,190 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index b1a233c699..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index d6caf71466..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 999ee751e0..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart.c +++ /dev/null @@ -1,956 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 366c4fccc2..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 367894df99..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h +++ /dev/null @@ -1,253 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 623d54a611..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 290fd313a2..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h +++ /dev/null @@ -1,424 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 14106671ff..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h +++ /dev/null @@ -1,526 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 4469654e54..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h +++ /dev/null @@ -1,577 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index c8e17d6421..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h +++ /dev/null @@ -1,475 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 91c0a3850e..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc.h +++ /dev/null @@ -1,436 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index d9b76124ff..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_builtin.h +++ /dev/null @@ -1,301 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index dfbc7df9a5..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_cache.h +++ /dev/null @@ -1,321 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index cfb9636449..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_em.h +++ /dev/null @@ -1,133 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index e485b159c3..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_exception.h +++ /dev/null @@ -1,461 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 87b1913df5..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_feature_config.h +++ /dev/null @@ -1,397 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index b5237f31a9..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_timer.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 092374622d..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_debug.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 9bd9c318aa..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_error.h +++ /dev/null @@ -1,156 +0,0 @@ -/* ------------------------------------------ - * 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 deleted file mode 100644 index 37aef66064..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_toolchain.h +++ /dev/null @@ -1,121 +0,0 @@ -/* ------------------------------------------ - * 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/README.md b/bsp/synopsys/emsk_em9d/README.md deleted file mode 100644 index d5cc11fe88..0000000000 --- a/bsp/synopsys/emsk_em9d/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Synopsys DesignWare ARC EM Starter Kit - -## Overview - -The DesignWareâ„¢ ARCâ„¢ EM Starter Kit(EMSK, emsk) is a low-cost, versatile -solution enabling rapid software development and software debugging, and -profiling for the ARC EM Family of processors. The EM Family includes the EM4, -EM6, EM5D, EM7D, EM9D, and EM11D cores. - -![EM Starter Kit](figures/emsk_board.jpg) - -The EMSK consists of a hardware platform and a software package, including -pre-installed FPGA images of different configurations of the ARC EM Processor -with peripherals. - -The development board is based on a Xilinx Spartan-6 LX45 FPGA. It supports -hardware extensions using six 2x6 connectors supporting a total of 48 user I/O -pins (plus power and ground pins) that can be used to connect components such -as sensors, actuators, memories, displays, buttons, switches, and -communication devices. A Digilent Pmodâ„¢ compatible extension board containing -a four-channel 12-bit A/D converter with an IIC interface and an AC power -adapter are included in the package. - -## Board Resources - -| Hardware | Description | -| -- | -- | -| SOC | EMSK | -| Core | EM9D | -| Arch | 32-bit ARC EM | -| Frequency | 20/25 Mhz | -| RAM | 128 MB DDR RAM + 256 KB Instruction CCM + 256 KB Data CCM | -|Flash | 16 MB SPI Flash for FPGA configuration with 128 KB reserved for application | - -## Usage - -### FPGA Configuration - -Current, only em9d configuration is supported and tested for RT-Thread. However, -it's can be easily applied to other configurations because all emsk configurations almost share the same memory map and periphreals. - -Please refer [EMSK configuration](https://embarc.org/embarc_osp/doc/build/html/board/emsk.html) for details. - -### Toolchain - -The ARC GNU Toolchain offers all of the benefits of open source tools, including complete source code and a large install base. The ARC GNU IDE Installer consists of Eclipse IDE with [ARC GNU plugin for Eclipse](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/releases), [ARC GNU prebuilt toolchain](https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases) and [OpenOCD for ARC](https://github.com/foss-for-synopsys-dwc-arc-processors/openocd>) - -Here, the ARC GNU toolchain is installed to `c:\arc\gnu`. If not, please change the path configuration in rtconfig.py. - -### Compile - -please run the following cmds to compile - - cd /bsp/synopsys/emsk_em9d - scons - -## Debug - -You need to install [Zadig](http://zadig.akeo.ie) to replace the default FTDI driver with WinUSB driver. See [How to Use OpenOCD on Windows](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/wiki/How-to-Use-OpenOCD-on-Windows>) for more information. - -After compile, please use the following cmds to debug - - scons --gdb - - -## Supported Drivers - -| Driver | Supported | Comment | -| ------ | ---- | :------: | -| UART1 | yes | USB-UART for shell & log | -| UART0 | yes | PMOD A UART for UART modules, e.g. esp8266 | - -## Maintainer -- [vonhust](https://github.com/vonhust) - -## Notes - diff --git a/bsp/synopsys/emsk_em9d/SConstruct b/bsp/synopsys/emsk_em9d/SConstruct deleted file mode 100644 index d8e88ebeea..0000000000 --- a/bsp/synopsys/emsk_em9d/SConstruct +++ /dev/null @@ -1,53 +0,0 @@ -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) - -DefaultEnvironment(tools=[]) -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/drivers/arc_core_config.h b/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h deleted file mode 100644 index 8340e94091..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h +++ /dev/null @@ -1,229 +0,0 @@ -/* 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 deleted file mode 100644 index 449360f3a5..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/board.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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 deleted file mode 100644 index aebf88bd42..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/board.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8701a0e9c7..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * 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 deleted file mode 100644 index d39a09159d..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9e3ebd3db9..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7a63880fab..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 deleted file mode 100644 index 706aac94c4..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 deleted file mode 100644 index d60e314389..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 deleted file mode 100644 index a56cb15212..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 deleted file mode 100644 index 47f796bebe..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9a5c8c14b9..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux_hal.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 deleted file mode 100644 index 849ecf6329..0000000000 --- a/bsp/synopsys/emsk_em9d/emsk_em9d.ld +++ /dev/null @@ -1,114 +0,0 @@ -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/figures/emsk_board.jpg b/bsp/synopsys/emsk_em9d/figures/emsk_board.jpg deleted file mode 100644 index c96c3d6b6efe2c637ff55cb78767089c310740be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 483486 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⪼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

7!PP_GdKS0+Yc80kL<+}UPL^{ zzlIbiAIe;XKJCNfZ8pZFB>cKQX7gWTg~I_uAP6Lp^}W98nsv3S69ZxBhSr@YIVr_HZDJm79&?2;x># zxG!m6e8s-o;W9jx1f%Ve#vX3({6bI@LaQx-_HuCXY=yV=F_(wzx+Up)vmU>g^Zt&P zlS!1yzfRSG&5!Nrk&i!B`Pz~zDVXmp`nl}PnF<2t^XcWRZeD0MBnR5FFLp@+sjxDO z8T(Hv26?4-8hlk#(u1Y}H&qN^cSy`u2#8}w?P(YjrYyOvzcgs^F!aRBH}GM1 z_g4Bu5nuMp75>`xJ_7QUd;s*;e9zPWTd7I~rK}(UDImsw2pSbdtQ?z)qCZN}8IJZ_ zahV@=y&^7z-_Ax6)tz`lxX+vlr2)a{7iOZ9|Z@nn%Va|pg9AMF+ zyi!#P@*oLg*L5F0(h>D8`CGL}L13iVT&w|6t^KohK7&WAyoNKQi}$X!g36W|gRSvqUViUMbAg4dw%B*_KS%BD&gG|YW>#&0bog!>l0*a*uK zPXGi~0hO9AU)S=kOaROE&P(3YXu+vMJUD%qVXk0gDga|p`v7;a*yXTs#2pkh_|$OY zZ|IaPPg7>(i9PEt=}K0wMkwppQn?5!itC+z+)9lc+=J_R0!P_sw5U(0VEKdD7S@@|T{T z=$_3L5r&8eSYuhyl_+rm!T@5y%MbPlr4RRabgviO{bDo3%ojQF^R{j?cyT8c)Qkc& z3P!2uVF9=ZybGq)1RK!s2zv;-P7J_~v5!%`V|$NiE?zp%VSTIpR^(KJNC~+vcO)ej zYWOSicxA*uM`Z%@#di~&2j3IPzuNE%+z7M~hRorjT<|BgS;lZ-?n}r>SAwT=#|e*s ze3I2#CSBMH{rRo77``NL<(;U3Nfn7iGhyF%OpLn=c#qMp^iG03d~qk-woV~MpwGMn zrA^CX>|5%-CZsCgN?-G5kKtGx|GuUFjmIj!D(>u zj@OTl_f(Zem$Uj}8uA9qT&$Ag8x%Xh(mMUyImuJYyA)ULeS>0KRZ3wvgouYB_g5%7 zu5;9=mw0T9oI^LrtpFvZ{?9CKzda6OBU(W>9wYj!kxlxZN6eQVpML=4ghplX!X?UD z16@uEZ15hmS=}Rj4iX?})-$?i+ zDHrUOk;!u=buJ~`%;zrN*sc@g@L9eOR=y`#y?m(Eh9pV;mA(Xg8QwO2egxP)+e9<$ zm|@l9PAeCja>1K{C9vyUoyF8JOfi8|v&o5eRcfL-zm#25lVcJlKmi>0xSL zx5=hp;wkIl0SL~K&dx_uO}_R^a4N>^QQYwJ!XT&s=||^*Mo7)GpHpbII>Mc~F!vgF z%6AfZS2}t(0_7SsXso^`^NyT^iYq`@NnMcY-V0$jxjITW zSfOz&zBv;a#X4-DbRWM@q;V zk644I`au*KLm}5KIp7LQ>-Ey68JQC?LggJZPPuyOm`6A^RY?F0(0Wdw-vs=D<8*&s z7l)~1^#-=imI%r~U&oKjVd`oy&gr{h)o*u1?y;^RcykF}*I!gvLcv$h@b`N+&2E`Z zJGILTQ?`hk^}N`!4BHF2gS>nTKi42_O5%(;ig?d(qXPcK9|%SY>P)`&bgiR9^*pnC0f1RMearTuRvaD?Md>#mdoPR8efP z@{YgC+$W*rZ);C$l39oS&c)Hc4#*(2+>uV#beQI*vQSuC?(t!7R^eN-1`=hUZf!tK zOG>*G{9L`Bh44UoGZn3OB_EWBY9N?lo11#Lro*%=<>k0}=4zTnQlPFoQ7+eqJ>}&m z=#6W~ffz82)pK7)YLVyUTh-Po2w>~+?|W=oD^$@JB)jH_Cio?Z71GNd#^$l1ju$W- zaF+XMIZ;bmz3Pm>M?EyNuGV-lMjbZPNG6izIqx+6+@NBav{=#Sa)Z_*Nuxv)!wt_T z2ZbFnu*W}}yyqRx+GcQxxs(~2#hH$wOXvx37g3aSnJWT~%eI%nYC$&D6F^TF4pii! z`X#s9vL`b9Zp!@$c=q+erk)}Ve_ifhr!u<=1~yL|I6sTA`6bWwo$IM|5|=8B1F&R* zbHnFcy$tgviN-RJi^auw-$4i_du`u3rE@d+j@~u@>A9UzXwO!D%Xr;- z^QGM;smdrPFmgY~1TE-NFa`YGLHDes=I8HnYEzx~0~oSYyj)+%gD zCkdFby;Xqx=e=#E!D&p(WDtqV+7c>Nl;^a&Hn!fsAcht=pPf(*vs>qPCrh|qIPf<# z`5hn#ls$-V(r)ac&UrzaX78AE??)Bh2@g53clO~g`|kYZw=Q|_+vlFrbE+4}P#SGe zp;g(8gqMsu>+XqbYa#cy8WoEYJs-x_N?$H6n~K7lq?LI;;=i~e4*i<3#qtMJ%z)%CQ{f&y_q3ss%E_UjT>TfZ2Uq>Lti(L?XyeX4p-bzkLYNL_wuh; zxBtiT@N6jg{pDnH1#o6v-`8)hctY@-XtH#pUN&jeoR{NoMx^@%doq5zjB~! z4)EQR5g`p5w`P36nf57-VSiAV8vQ$GF7QW*Y?0a@==}?Ba(pNfdeFM5{2$ptCoB@o zsG?YI+qci1csg}=!0UU!Yi-&7Rr}^D;YLs2pP%T`X4?(pVU6m^Ac~-X^I-(F>^GuN zn9$t&?Bm0sKwW~(MxMf)&w{MJvO%;MTFg=ZOVgCJ@Yo~UkJO+&yh#6@>EWXF!O~vV zxkEmiya`!m%B4bTYzfHKD3;{0&hU(nra+!l615IIRE^0(g+I`rE^3+M)x^5Q)}3A{ zCv)3jP8~|pB>c*p8#_~gxlhM@I5u!(Z&0byQ3_Y2dyv@bC)b`Cx&E2_UL<$5bJFPU z`0=1qt`(KS)F$=2hUKFRxz8)4=|< zKB)v2I(=X%(p}0tRJ;h+1pn~Nch=|D)0RUsSoVqK-Vvt?^^N(>>M?*(7@`J4Tm}Hq za_To=o)Vuy4AXp9;Lj=^n*|gDmyAEXuBbv%io?tI?H~PY)w(biQ``KvGEC)G|0}NI zn-Soj;5$9wr91gOPh6U6Lqw8hYjXe9O2mQm?*3I~W7`g+xp0zoQnOKqhoIN6yZVT0 z7>%Grw)u5__xY?%$Zj11qcWv6D~)418UqEf9TkFkmRlUIqW0WbUT@AkLqWm0LyLGhV{wo7<@Gm$X}YI!d(PiKb0tMw*Od#$3h!Kn1b9Fl%e&oj<9Q zWr02c#{~FRI}`hx44cyLX=%8MUSxPuDj`&s5DV@d&mJTgV%}qvg&K1)bjlYUvPofu zT^~a)9}>HG|2MmNtu_=Iur6{zsy?GKN`4wX2z#7x^_VU9t?1b82GQ5G*B{DNyxVxEdP(JFB}=u8RMR) ztmrXGuzpouo$3(_EvD$9bbgVU(0a)%yD+6ZWDK=c<#7-AGBlmw1SzB8o7+%Z- zE7^MB95_Dc1etwuzCv+q!xBuhSKTi?_H4hRPpjj0nw3*-X$z%EMx?NE&`+P=$|Y8U zk@=8j^9*d>#%uLEU4~VEc0o@uXA={{F|zK91MtVbUhZCQDLqaHk6T;6e0n8BJ?sPE zKJD399bR_uS#67rP8J$bGRn+%%Crv98#_DTV%`qok2STOXWu)>-k-Dc0|cLwC$C4B zxtl+nfJfJfJGT0r7oGfJ z>g1??1Ia;5NL+BRAed;T< z$}zdXvfOhIP^+FPB<-3^$^i!Y5cFD^{S9U(t_P*UON7} zy!Wc*E{c~Gx(gtQt!f2v-k8+5E->ndZh03wR=Q{SV>i$@P1#M|8FHl}G?11pulC&5 z<1bWoAD@IrVD;>;zpI3!rV>Gq3!)dhYuDWis$sda!2aP6+vLjB zRr(zFUtyG^|QC3q@Q0uv32ZZKSZjXS) zM%Q{p*+P|d?)p&;_7~axLf&L&`;E4TT?sz-;zp}tjJM5$`rSM1XHl*n_NGt8;9o#r zRp5!1hBB#vm0CsgqR7uH+!t=)}` zTFk1?41xu3MUxDm{h<32EDc@ef;?n`k0pKYJ*}IL&w`y65G?oFgsA+qZx33TI2j zDhJd-uq^qYbca5I=!^`Y+`twYu z1Q;#m%V?DgUesUKkoNi~e9@^UcPnAmT>pB%eI#}0U46UT-|ckLSUAENGQ&-HV1kRm z1FrOl%Mk9KM`2Rae3+cx3W+m4uN$rn%lZxikRN$@_iFhHNt!eM7Ri`2OO<0Z1$n#* zh%^N90;Gg@+?XOTo(yq`F8bl%VVo?{T~FNoofv>W3Or;&zm`AY5HHiB*jDiQ%}D|H z-^kwEE_I9{beUz4>*jSuQ-OA`1xe;~da}}6F~XTiE!w(>@zCk*VE4V1dn*GD0iG@R8@sPX;> z{DLv#m2XT-5K>tR?kp@nK=v?c6?@+&4njtm-FtpT6nj6i&~sk>j<<}jD@jSA(KYF) zaM4j?zz2v?^o6u0hpB?4RJ#^)Uid98@+TK%ZG~@1M@zY|KJo>$abv7gSz6++B*N(7 zVraBKrNn(a)Mx=Jy7Mh z$D{NqY-XFE@Erf}P+Q#H`cjf`;5}Q6%(B;(y$U2%WER&&AWGsar17Ya`(~H~Ry7VQ z4k=r*-N&*m2bJ`6%*g!n)EqE+&Zf{FW6tyKXMd$)ExtUq`klg<;IK(j0Y^(x<)V35 z6^(aRU5;5OZg$;}Hh*f*?4Opw8PI^faiJx<;P6UJC3O(GypOBJln=+rB)>s0iRyHO``G4!o{|<9!v#@~A1C%lhRs=2nhxtX0^j<6GQ1yR zaU^kYb>-knd~_W*b%0QfDe?bDP?2Ht7tyP>v__1@j6U)VlrNkSd4YHwslkEj_7AG< zmzwxkQ`SS1n`yeM?mMg2azZi`ClxV1dgPkMgEHk}+_KOacc>j~%JGE45FdY~OsQ`% zpe8bZHix2A)f>>-*VKRV-samf?qFbM8_VxB8rA)n><$GdIfz8oyrss!j4wt(20h;I zt-+gJ`;vIUI}5r4QSbQkdFNP_gfkdkuzXORf!OySsZa2#P-gDE=AvITn&#_OnUz#Ydj|~T5P72qSWv2g2d)ZFtITu zvvqYZTkoe27q9<(_O>rJsp*y0Hcy*M0uik41|_+f}>)$GXraLNI1_4!3pvBg_V+KrrEs6^DwQj@c<2NUc7~p%i5` zYu2SBbo!pqEI~8>Bm2Pp=V;UGz_BvOQ=L^t?oH6>G$Kg+;!(C_-4c6igRb3Jqap8_ zCZAQ>JB8OCza~IY8v)$ZnH%d5VZzm;KQ3B3j1F<06Sxa*h|iX-fn163+_qnSX6^fh z9PMlSE9rE+4bqDtC}GDW#{kpQUWo_wzRXR5I+oe3?&93|czS0189k`@oo-5TJwKsS z*tOk>v*_~;`my)Gy^_BL5`M?QMmKCQT{Y>}_e`n$$|1v7S5q6q=vH@32F_p({QihC zh`DcnU|o9AKU{klLRZ{aFKr35PMbTU)YEDQI>J&9;O29`Zq`&#wHZa~zY7BV0^e7A zY@_R6yodV|lyF*mwrBg>E?37wqK!|amkdmgi~wkV)x7@LtY`foF!h2YnRFcKpUmiU zKvDV*i5aZyyFkmhStUKY!akaHm3abtP?gi`gFFXqqaLYFERLSo8{+9q3nB%n-;dQ6x*k= z7c-ksmc2qHd^8k)GE{H97BpowzpVUCFxAJR{TniXXKCt21WAl!KoNqHQHfMf!UWyw zohlh2IRRHbzp7Z)Q`Br=dPZiIi5$rGV#ltR$P^ZXEuY+9*a$rDM|8~n)M-Q8W)(40Jgl}Y^gtB6c|7Q*W}f=Yr% z5+`Bx>-E@106vGL4Yio-lE;MV+ZhguwAkg;cLjPR^~oJC`hshXrTS;P@4J<3M1BtN zhwN~{i9I^U(jjK5nQqk;h)`8)xAj&xggT7-m%Yk73hNaiUS8kQ-k3P_@a5vHzDUvC z)V?7mvbP2X9}R+_XcpYsb!`~W#(!jga(dUf;2!oU!@OTTbh+EgI`(_AesfL11(vaI z?z-Z>=qR`Geur*`JRtS?lNSru=^Ev%%^{TykHzpjHXPFoz`Vox>uLo_-}cr zop*U?7%lIn-nhB?bBnY87-Zk3@OZVu24st{}>^pFeBLpQh&^%h-fV|&Cs&R7OEh0J&tVz~O57U6b#9C)jKYqf zj4l5KBMZ7e3LkW_?vn2j&R#xbvzG7a%+_R)*#0#>JwD1pmTlKQsdFJhyj!q2A_G_f z|0tDV&v-d`9 z#-=fxs{fItO)=pkk2YCSN$QsxUH4Kq5Kn6%$qckp&igk)DCnDpmMIUP;v}uTI~um! zIDFZPHc^Ge7m)Wr%OQ=Lz=&-_T=D$M{a>CV!@NvW8&l+CqGP_VJ516)mYd`rulegit3A)p6i>QVr~&bg z2dkoG?T+kx%_#|MEY76}-)l-)#4>opun&qCfJaj#&%0%VF|}Q?3#PFOKHtO+?^|4;dEM0iMchhhBN#L)z#-76yvJ=nzCW4@@b^K@TTHXD$hj8^vY zilqMILS|J7w6@d_K6-sc8Q&K1c8x+JgkwId!>+Bgy!xVhYQK?44aH|{K%==y#Bzi? z3ti2*##(q?DJZ6ueQ#p z_CKZi_L0t0u(03)N`L*Gc*DI=rgKs4X;1)B^#wbL8sYX3T^l*h+ZO6QZu?~UlP1SU zr+UwlgnrRp2MilgxI56T`ThAUVK&Om4lbK((S2~mtxKgP&|^mBEKL2vD5;d6#l=-< zxWimmeDTbsjFg@WmWFfV_OJ6~J>2xXT1HURcQzIOW@*;A_>WLbUA(!mr>&7o{7!1r zw!@m`4-mCsikOsWR3}gt{J`eLagZma9#G`{t(CQD0e?oa_iF{Z2_1bk(a=UCy~;~Meu3m z1W8P6yl4>?5~ZRXUT4#?l9PS*XjZ++6KQlS=lwC7jXm^6#%_k4B7|~ryz!v(;pUpG zNiGe1Y1k7HUNDtAwBs|d;i9XZT}sX`p1S^unEQV?JIl8w|M=}=ARr>$rKGeVEn!h2 zpddM5Dj+e&XhsbM>6BDbq;u35jkHP$BS&s@3^sDW;Ct_P+|Pc`?)yL3wd?qNu6La0 z>#Rz~HJ?GiE05va#JZh6)zWyljErur6JW?fFy%dibq(#B>{oqPcK}3P77!3oRN-{) zrI9DwG^rr*N_WVzyhOTG!sX|z_+NYrJ~LA$(+6H( z-U$YBTulR6_u7~*v=K=i_>nA)yycvi7QJT9ju6WFqBf^Po0qowKeK$#KxrzhN9*|^ zSee_F0B1JM56%A;6_M=%Z1$k%Y|M{yv}waPZhFJ-rt%0n2N^6Zg&6JpJ9n0NK-N{k z^a)pA&-O*T^U%yIn%%s9E85}szvzMGkKuxI&@h{ck_p$<&=aGEGYQv}Sv3=}K){dQ zh2q7o(#!XNk5G zuDdulk;&pZB)k2pICjM}EmqmN_2*I$>zLA$i3`XpHnP89GfAE=(7Y(5+@432IzY85HxURv9>i_cuw1_f>AN z?W+qvD8=oyE;SDCl;b8Yf&Aaz5~Z7|~qk!L`>3J-{aAn{EEf_SbU1!^wi5&~w;0>@ER`^H`z3P7Kjbz#e~W zXb!egws(w?002b4a%nln2lcvLK2Z-y9NnLJ)W0Z>=TDG9Xhzm-vz;%t(siT+3tHfuen1T!ntD`c;PWe9JRXqfk0eQ*1KDhbK7TOeBf@aE1I| zz&n?7JFeH%Lltx;3-DYw?7No%9B%Sy9%9kI6DcG7?DldchxN29f48eWh%y{*KJ~3Q7$*J*PFJPbZqt4K2eknY7E;+kK+uiosPDSSm5{KMIWS zgw^aT1Fi-5?DGAeca6TMv};ePsO&w|^y^#>*KB}E5UaF`%1DAMvKSwlSu>If0&ENM1-dBO54{v?&IXh`tO>) zcDJ6q&Gneh8aqc`Gx3ZyICz z#asKvRsySy)fPr1-^J&Wn;Do7_4E5T8)-st2ZJ}<1}W>ByZ6Hy6E74BW};FwqR#hCD9ResW}7WiZ;b9;NZ zXI{@)5&z!QrU3GTFpADNIlTPZAr-_m*|1MbY_*&2-YOw9D4|O@BeE;yw=EZuuFS=jl4yxpqK7Vy?9o7M?)S3&o;gTY zb2vn8SwH%cA5p^T_5<0GKtN6G2Kv>f7T2f{qiUyk=>LT3cJ$R z--zK396*UUo95&^)Po5OQVh3pYww!Rb%A6DpIw5I27Oa~r`EH~e((ehk}EeP_%b z!ijvT-onS1#75471!}-nfBO$42FU6FWNXyK6egO_b|vhS#v76vkQln;exWduCG_b` za}%$cy_$U|vFB`hJCDTp=%gy;L}?l(YYP(ok=XY-|MRL(f|%06wmEHYf|9+p*vj-` zhhG$4p<=?=89B_>V71+9I|x=h`gdGce&l}SaMwN+i^YLek~<+vS1)n?5E9!<^4F3m z#*gFWU37zJVjfJsP{JoFa(LMlVyql4(F`+g0f+m55WJyH$g*bSl^SdWZC1qFo5u`p z3-nVU3z^H(iXU0*MhktFP8Gk$RHN}m<#!kSJ6X#m6E*!G1!sseeOw5O)avDQbkI|u zQn6=-c7czT2d{rgJhS^V@;G2R;c75m^K*y`BwUjT?VEt=R?TUw_aWbtjKbN3Bo5qb zzeYnt+39R^R6oFn?tiUf}Dc6cK>>Gb4 zxp0N)K)@_u)t`SP4~OsQ^+JWScoMBHBghq2BW%G+2^YSc7)kC#$QIA#RTM65GC#>o?mPvLk?0ovLX9avWa8uzL(~Z(?266XC7X{*Vp;V$bWp@%ldEuUw)}F4DdIs7W zV~giIEG=_qK8RR-WQ-6KI-jd8|`{W?M|Amo{2#(-82Nb;I(R|lR&KuIi>n^d0 zWR+WPqroLTqtPdsrfXHbCUe(3ia>;7;c&D@Ye33xl`Y^#Ge)A7mkN6wWVIHaHkGPo zTmfHD3*Y7H}76y|lA_?^-_mMpoXbuubs_W8*n8MaMgmbhY(r-OJ^ED*hVrwpj} z+WJ(#sK&ix^)vb1%-5`Gb!F?reW`B{Y0;A0Kc(ju7w-k~p-8j)THCB>UwupU1}g6S zz}?Npxaid@aU?y=Majt07FRe8^4VWpC+-?3=u?UcUya!+e=BM+j$^y3g^ZkUSBJQ2 z;-Bu5OO4va?}QKlA>&tG6uL92&A)W>glUI7p+_}bJSM|dtEzL2>j2vsUO0NG{{Cd@ z)0f7>462IqZPW#1R>GmSy;G_SpeoZmIh2X_xW%gLk)d_if4c7fK!C zF+Gmz!WcS={hXw2sURiruR`oXDt={dWGhwbbGsiy3CAXl0%mny-8PcXyu!F)fpUM* z=*7I?Q2K>}{nCqsIA6iJzbVC2HD4rCTHmBi?(ZO4+K=Qk9hSbdDD{&qbL6gsC?+R9J*Dl^K8>aF=wkM`(!8?So-?GCCY)teYC zHf99w?X}DA_AP^+KQLVzN>gbTt;+H~^FGjP*YG=a4N(iJU&!kTR_Z(Pg~`@hGQUN+ zg44Ixnb?N>BY=$(oOZ7?y0d0*Jv@9Kz)ec>6Zbdc4I+10R|c18K!5xS07U+NaRuc& z!b#yPdVusWk!{rmer65%SxeA)P2G4U1lKS)=RB18O5ctxdX9KeLLWb4`3VIttH@~2TKR7TDIRX{y$L6y~*eCTtLn&(Y<;ovCZTrqqo*g%h z*TL`#@ZS!C5-kayCujq^ZcRFv&@6PY@7y;Fp+L?Qo7Ix{W2SMq9C~m6mD&F;OJ3{N zrHNHY7rDb+&R$f-Hx^-V*N&S>25_jzh2eN%;@bwW;h+WLpF^mFrFLdz@#DtZz6=!B zZfab|j?qKzN2QpWx@;Teens;I#293*>HRjw<%8_YHzv*q@1Hn)NrlU_+3apxVlSK; z+KGX+lf!hbgr{KFoby;U9zhFMZ1bE6H?$@{5-1S^;a5C1Tkh~^nIow8pBKoJlN8~G z&wEnu;)_xXMm|x%^ogBdjE#gfVKEDTfW7L$SWk1grnks9hDuZ^nWR`8Du5Mf{e?5v zb)~3ds2BB4zo8^!ynwa*cs&U9c7Re$ha~A~bKTdT>axn`1;c6t$-v{_p`5Rc{;bEOloe40?Rz=m3*pOko?~qW=ic;vdiCt`qdUTUcNEB+()#_Yw&X? zcE78axF{EQKI%w6E7};#YhI#jqr|A&VRU|}2khzZs0(ODst%`rnett9{QBOftllO% zV^}M}tSSDx>Gx6hC)oB|8-~O{%>VEMpefd>h||wU!486iTe<0mr|bc)io;yP9yk4H zAAH_`S}3QPes|{%%i|>nGc^?m|uliyA%>!@)ZqB`&J*mm3j?Jc=3Tmfiq`swreXa0bmXDJhaVz`~^} zR7Kg==>&WzKl1iPk^5Z+ZqpAijBR$B&-fl^Piyyu} zxl8_!KZ|+akJ)g`u*jJkj(eGBC}3o_G4c7EDH(-!%PLnjdDjgTdiN(9 zKhX&NKL^2 zkb7dXO8w^@a=(6mU?p=pYL!o2^Ht30mKb8#@Ann!95@JmX??ajSK_w@F`#k!88h*T zoM8IDQ%(Or5>21^h8jJg(R}hqU$;lRXA@>r$^h@0A-Oj=-)gVy3{eh^ z#Wd3Yu(Sqo*P$89=hoK_vxb{p-~C7NVRnTlp`HHeVrMnEHUwW=IpqgpAypv)K)jcv zrZWN9)!X&q=Wd*z=8T#D%C-bf`F0%0L-7Wqw1cW~DmLv5Vlb{3v=0Ya6Ze#CQ37cy z&Q2vIMC1C4#8pS*=5(<%PCzqJVCDrJyL5%`2ccu<+=%8x_u(9nm2o zd1Y3*b?84}=ok;>eJg{wHr5Z?d!%Ey$i#~W3CYifHU~Jjskh?trkZ23nnUWd%oDD$ zaM@S-a2E1ZoAN zPW1bxn9Dc0V^Wjg>{0HQ173wiZ_7g^0tYnlmaSQu!X!rg;vz3#H!5Xu0k|lhRjIfo z5VJmswabkO@}~*#8N|aNj8bGJ+elw8G(RDI}^PA|)`Ozl%&0lx7_}gU{Tpr;s>l(nLgJdP=cqeQZPvFc2XJTy0=*UW8{&fS9 zB2Z~boo&0>MRrlt=VPf;mC(fr_;(%`>z3M?=6H9nU&^at10rzf&p&SW(*ZBCwIpa< zW9DkUQF6Q{d~Ok$=fJ5YD6g7VkfiZGkmAhq#50W%Z=Y)gIIpLFAv-!o$sZH=9w zel-RtIk#~7h@X5jjgrUe-ZGK7swhnifT+{0$q*!qM*$~DERqdJjUjA0j?No&zE3RI znwlfdjp~H9*1~5P!~_-2I$7;xXM%bZ{Ui7k@a5UZMf5dQ0t(5z=D3)$6C-i)<`+A)+dj1`c zIZml-=?niIfjk`of0TxT)5#*k*iqI#v#s+12yLEuxH$)T*9g#_G_$mQ!xL2-F4-3v zE*gWUAs=WPnUlzru1uLwpH4a=*YqpANEkMeLpU!7q)}Vx!e!D?*J0$_0@Rdmmcscrs25ZnGKd<6+maVbSwcECFF#te96M=C&;JVm45lwlR~Mh+*a>VvE|MkTG`fwZ z)J6+aM$#&^+H?mP2sijO{_z}To&Vau{35w`DP-OF7e(*%UIvL7`Q$P)NQ*xdCb&p! zTet>GTa#N_j5pE{#mA9 zh^XBCiko)|Bw0B99cxVC)JRAM9gx(-}B?8#*M)%cm> z*OO%C@KG{$e6)ciQ<9C5S4y6psP-$gMrLc^l02Co1@?nSA2N40xW$*CVyy^LRNI<6zB9Srz6^msdN#W z+5vGrH^rQiyRjqJSS?E^pHn6biZz)+qzd$DN5LP$qAS5@YuEljm~D{mzDwC~wx zSEIN1wSp02tz% z{bP(dXYLBQ-6nhS>T^l>rhc%0I6&X-aOf=S}f9&H{d9N6^VcXrVIxWGF3{kKz- zGkdb$01TXD&*FXzR4|X}e{5e8e&bzmQnvWbER~)C^y%AGpOB!j2n10 zPTs9{@TS8==q*`bc+iD-kOQHGx=%~l)h{5s0xf}HRVQh<9RRw=G<51BFOUJ-()$7Qn8T`IZ z7pMDeydFH}%aug)1nx+ROwe()?Mv7!3jWdch{{1CVtJsS{-${o(FB9+qvvV0BB#7$ z#Hg8Ia18#_EqjUfDd^{_43)`$9gKyjF&!JXwLQk$emlQaxc$nIUn@U|(_jPOHRLW923NWl9_CGHBTD+2nNpL+6&^ zZ1K|ro5iQ^`7^)XxXTA>N;X=oxG~Lnsz6@VP`)JgU^-(0fZgy2v-1X9Rf1#B5u&-h z^KPtNepku1lGkAI+_vwi0%A_@B(>?S91TxBr7>IQV{dZZ%HNPZy)?VXOLQi%0h+73 z9?n|nw10>Jj~<-0-+XsTv9&Wt++Rlaa=(F4mV9ahQAOQrj&5^c?W=seTWx;nGxC%5 zR9wsLgIsnxwKi3?|E(LMeRdm`W)+;aq}tTCZnzWhIj-q&NL!jS_`$)`i&%4B7z;8u z;0!JwbXcNKSG3|RD+@)K^}6J>A4(UB=rlU_zmnh%ryUi-4Jeme4I>j^{GhRhXNLxp ztL=!9yhp<>Jw{3SO~G~IN{n(zik=)^zblxw*cCHz5#^a~%_UA(>{EhmO%uNTnIGYS zAkRFsBK5C~WPlytsTpnjPO{OB*$^iqG(U!_FC=P=q&?oy4i>1djTl)mcLHNjy(a8Sl!R%ylk=Weg7W^mDNTc)nvEvum zBcgeC$Bha3990YQQnStB$J~s|bjl*5hh30;%r;glLhmk~@80J>Pdw)dF~kb&bhP)` zN-}z==Vr&dZ!U_+4|=&z<|fW`=XqzYB*QWZK;|GzyjK6*f?!W3qCx4^AN9#@0JY>a zC8^(O$uquJ+J80XfRp4;d8pD*&uqZFk6!WJOx^qNaGn%4oxe5JW~&<#xNi$Ax`OPT zY>nnFO{V9zkS_-kFCo0+JBGUo)Zg-}qYjC9XxV@i0L=)!uC5b~{5BqOL-2k;wqwmD z`7uJhM=`Nv5MX2Z77DE+wei`zqI8NzAX$$|-{7OK(o24y#x*tnyg*5+mscPG!baq= zQLQC#!QiL%p;Y^Hiommcd|!PI>0QDA2Or{m@`4{W)_JYdQ6{XD&D#Oh=8xr%=I3(6 zM~1Jq#@I+3h%D);7R<0GJsR*@Q;7Jn_Iv(zs7F}X5vR=qLwTD#1+hb^TvA6?yTYsW z{^>F^&9^QZ-KxbI9c$8Ndq*wfb52JyXPR9Bh%Xv+E``TNz*jK`m9|a;FGjf~dyBS&(vHip*`;p`i0@}?u4dZ1T4GpIn z_bxS;NwWi2lL3jLL8AE7AhB^7c_4#JfNgzIQEr8^zoVBzUyc7-x>hn;51FP!{q64j zCpifWKY5Bi)8h8E620Ro|A9~#Et=>xdNbG6tzUOCtdHZywKT`GOplMX!O9E`$?Tz#h>5F+T@bJUDX%WahQp=g#O_6>809uYX0}@S%##}H7LpVgc3OX_>U>UxFX_9YAgbd5y@73SGgF8o z{pYhso7jl+W&f#D-v=GmUIwa3^~!fTc1N1f&|~MZKdP9(LQYt@apSXjViQl)Sp*`C#oMlStev&GGBh{v?nVR zSu{jRFYzILyy9Sq9^hU19DQ5VaeTmoo8JC?l~*vmcTeo><61)VdH zzk?e#M!w-nKEoamjg0W3U1!J2QbCl3^YhjD+5Pn1AsOV^qOZkZu~1v=vmHTsr|={nOw%ekV5Kt(#ykbPL*&PN zO#NpKLR&L-mCjO6=6|X>?#arS_zXFUvir`(VG)rkD_8_gFIrCICq^9VWN6{1YFVo$ z*YjDZ{_ts4`o2CRs|PL8be>R1Bd1vJ6ARQ6kU_6>mT&&(AZ{g zwLX<^Uj*2Ie3op?hb}r#m{DXh)ynclU*hb3pRcN07B;JbHb=j^L#|_@KhHqoaGz|!>LM=7B414 zcLKbezV758<$7Sl{qg#fxfeyByQkNLl+b;MwBjO+LI)Ch%$<>9t<0SDoKL_*-f?g5 zgSPfvuSG-_AV*RtgbC=vHHkZl!Vmik44*{V30c#6K1(*)$tWCrY7nxkMMidUR%KYrP|>5jb9;5OR&ktT$wsVVs}}k zbB3?+j#)+JQguUyszaNHQ=%ut?cG_-cfrqN0ve7BeJ~FIF{Gbqt5FF}=H$W9ti5mk zI0yPeT+z(Ev*KecNtziA_8zCfJ4N`&FqowEHm=GB%018_fLACq;;Slm!fT0yfh42s z8e-OpeH=jk5j~%D?cdSBOHPQce1ddOA2eamC*U2Ch4hZ9pennS@*dfoR|b}-I8(cELQ%2A!k%unfYfk0i^@Bizx&Hae81K^YKTVIc5X~W5ta`2ABBN_yJny2olJQz z-Evr;GNLI)@0#%ST2RuXL+@1&piyjpFod2)TXsE04=}E{gwi>vJ*??gwJ1_qJT>;S zazk_`lYIY?N~aMI8Z^0_{LtEk>G6(1i4sqtyswfLL{^h=4kI+rZl`zMD5iup4G;=2 zBL(=YVK~W#Nnaz{5fZ#+t))I>?lHh^Xm;OYU3ux(yIYvN08$4*sfV79=)$=t^+V&n zcKY`Ao?L}&{G$Iyx-r?cfj5vo52m zxT=qFY9;nHk)9w!9_mZX za%m#8aY+p5wxK2YZ`^ZxD}pim9oKekv+A-0sR|?l+7w5cSE-lSJ%- zUmq7+cw1ow*bBs9@#nR+konVJzqeJY5r(n0xTR6l6}`cdK931JI=+2!2VxLXy>E9O zby=eja-CRlLVKB^(EiwTd>Ma|5`wJ=EP$vNtz1_5@Ms+h2Gu$5=`u(Ha>6y~{#9SC^rWmNsK4tsWcjV0RBtXj4^UcK z0o&rT%mejw_NOkqWs9P70%}jP%U?T7+oUyzaL+wIe59{mrDN6hJ?PoFbdFsW_qU_8 zNsV6P@oiGLRwFw@bKLV!g(8a80UyZ(4R9o08&OS?ufabz@KGceu15skIr$|=)o&AR zGod!@$tpd7hnLH48v8CMbik7jM7xXUP_m%bf%yL7QIOR*_rMZMW%5A(IXngux8vYb zNc=c{z8Qf6x2-!{}d!VZZdiGmypw^2lhP3we^1>&(@u1%e6te5`%uf{AC8k{q9L$~}{ zkNkS2AlWJUf`f!!J%-1*p%K%nkDb^w2-7~6pm05FE3@@ zEy5k_DW%hcb}N1>u^9fvD*d{VY;DsWQaSbLKXaeuc;=UrKKysKjDhsb(Lq{2wzv{g z2i58ZDz+J42nGMmC&xUFEW1C$KeD})Occ%auHDI*ibKUg_6}{Vwkl?`y=xVA)_k1a zy2(}mcbJ@aMjd#$#+Rl8$MD1J8UAH9h@+FQ+O+cSv!itLJBM)}spp2CQSoY8om{k& ze-zc1;tm7Y-}CiVj-R#2=EmlU`q~OdVFe_WbRqdF+4;W)Sri=Z0nP%!9GfojUfQZf`vNK-8s<3J!lDb zs=0K*nV*p?Y;>D}W>^His7te(goA(7`lpLDIrB1tP2J^&*p;jKgnNwpHA&(5$PsbUZw+>&E7 z5X|4bC`QnRml9QV<#Xhy?e(4V?VpzZS<`;wrswc*@V?oT_za0diU9L1?es+|B9hz@ z;PH!z_+pd}ejpLX3r*~mgU)q{nuLx52ydAzw^Z$w(sv#YR9N@J@`QW@?m+%Z~oz{*$eBSmF|TCP?uz+-IMf^sM<` zCq{ER2#k?fpzrcUHgZ+%WtGe=xQO{qtA24qhnEaXGRqlpUFVlnEL9-OH^PpV?ryaV zWu_fB*M_}8-LG$I1|L3Woz7YRbK;j2wRW4LOZzNRUDiga2lAP}A#p%m=UMC66=%>h zVz^Ro>5y`p(@>v&(5Xm&Cycrl36&Few{DwSLB?>2!SOA!@yypb= zE(3t+xV*(kp3(kBp4EG<|t_hiB1qus}5m`Gfhul0NRp;U=fcxMmle+DU^T|`D76UzV9mlI^)Gr zgG~KL9<+R(F!&2T0IiU zp9HUjkjd^#$c!Ecr4{jTVCe?QrhF5*<>T@5xpTpY!?={xAb0aXp4?9zE^xZ>7tHJ2 z0P`UxJs+lw5?~nG+~cm<-=} zh!5<;?9**dtEN7J*1z~XJdc)&Z~vFZw_B4j1YFea@#OvW2}Ev(h+-d`f@JXND`pLZ zyRpLiQA`ikVqZ>6LJFSVPo5kMPRDfH?R&D9DUe2Nf*=IVPhevsIwCm(Q*|obvyTZq zerX?i>%L`<_5=mP>l@h^Z4Ut2u{V&PcXk6y-v?mA_pE1+c?<6s9?y5dr> zL1x;`r;3CA9P$np4>>oA1I#zc=gYpNKQDgi&U>P%+7h#5n*#p4d-TopJBQ8&r9YTq z>Bo_B_u||7b2%-N3ncGq`7V1B|CBu=$1n#f9KwRnzfV-r$iQq5kfz|HP7*JC&Saeo zrlr(iAVRvPt@6ICYW52aEcUAmTB1C{B9bfF$2-u`)kUZuS#L8OYqfftSrl zrE%ATxAPKujK)uW1QlLO-w9j@aL*V^r}T-F~Uo^pz+#rag*>7s(P zmgyeaZe|u&c}PYx=1#v%rLX_RX~}kMeMeh~<(ko=3A&xfO}i%5?v6Zn>I$p##S(7{ zs^#FmS!VXf)yr8iCtNwAQ?Q&kyS(t|7t`hymx1r!6^l%%Y1!Bd=Qs9D+SE)mGtALc z_wIW2`IE13HHiWj_8oBbLZz23R(azw*L50Y(+p@_&FV7GAsMKfpLfR_7;3AGA5M%S ze;JG@cdo=E7=~KfOY+LtxW6NrmVz3bjMQ~c;Mtu{d32irlfw;*v}2V)tl+{|wt!$c znYtd4UWdcRvXpe8pjlq38>};RTB)m(f={J`-f9Mpz(H01flenOYoIi}58~LJGT0%@ z&vL2cwU-*(TR%H?7mTe%G5GK{`dwwXXWQVU7@?Nr(FM6d77YEAVaSi+Q z3ocx_IhU;^gTW=+jD^VLzV$Wz+QpaMZE<&d=?!O37HE4l9ujOCrnrz%@p%#6gLW** zdh#)K{_Zs^_sWD*E(%h%L1|%FnJ*1FPaE>9s;lU-VXssjBTIlpUC|fse=}2l>Ggd3 zF02y?|BdRlSCMA?;9&~VZYXcI${x2qiQj9LI^VAz2y$}tFX(<#nExm2%e_2_DTcL| zC#bB^>E?YasxJsS{#OYrT^fRsJ!s=6{l_a8l6A>tSLH?ur^OqRU(&gsYD9Ec6NJuX z2{wNSbfnXBv-}EClF)hT8}6t|*V#AH_6^C3PJ6o1&p#!LtTaFUJ?ui1!7{m6Rl|AM z>vM#I_8)1>T`w*C%Y9)i)8e3RNEUTkar1nrQPZg)sddo()UR?5kmM?qQ>jS+ig8BE zQkZ}O6V6UTo<+2yRKiyyJkD-#(2{GxUrGa6&X_7$Uf+htnm_10;| z>DRtTdMpq76<-w558pKCSH00y4PTMz=Vu@R2)Ez_CG4$smds*=tBkbT^O9lFuccZb z5N{Kz(lO5~uTkrIU)_@%s>?~TK&cdWu+`a>NV))0NcHMSAIX-t3aGvM* z-Gixb%^Odo?ix#zFMs*+(8RYr)5`Wgin29LDmBi)l~K;w&6ax!2FAe#l?}~~4h^Ob zcYizjcE^{((^IpvZ~TFyq(IAw2^xIF$0n0OrYogfkfR5?@_|OX7X`In3%)BomHF0| z#yOjk4BY{yw6G^oh4~l=_S-T{$uvCB`rT{^7qQsmA|z!*+ujN7vdA@hbqMrB_Jwdj zce+o!T@6}x$;*Ni=f<13oo$r+19_CdVg2$pT=xn)D%st-&?YJ3{rZL-`}q`z`uST)+bwkK z8AY_tTxZ@pgE;B!Kl>ej8%v|e`2iYJPg*lLc|oh2$LyAUYn9Auo_S|9)}Krw`)~2{JIHPPWd^Gj&7*y4l)~4 zLbH|@eEu?E32cOlTbkkfrmyyB@8D!<2~>MQ$t_^?yboH z>gmaqos=dE^=D0$KMwO`1NFgfbsiljm- z(#~{m@_8K%u;j8&9L1Y09!Ndz)x;+ie)$s{-Fs3ieb8HayYhMhY5Ced@CSa1N+dP+ zZo0#l94ArEeu1M`)+p5BCA-?Ha|lX&l&8|Nb{BvM~4g_N|^-&@U`mXhjT(#;95l-^Q!B z?2Nf6u1$K;+_>1t0Bj zKGRW~kv)?GF$fqvkoA01^!}Htx5Ak$D4z(>MXGj99{pKzMfBSF!Tg)FEb(yQB%3Xj;Q|vbW^_!s8le%D$51{PelnQ!-xJ;&%m6+91A$Cgf%Q6-D2N##4sQxGL_8fEih&scLcVT+m9yZz>24 z?wB0jM%~2)`&K2}_0M8GJu%*!-~b=WXA@%dN(S?L45w(R6uB^Wqk!puwPr;*iMDM1od9@0x2Gt-FMO zyEQ`I{`mwPZK|wJ#o5tbg^XHH4~}KCK0p~?V)Zj+d_XRNE@MR;6|K(j!TmV^(;F?; zkMGHG=>Iz+{r^24y|pnyd6XR6v>>0#7oVH;e^r;7;iOLaC&~3iKW0DO))6;pz|2|}ooYRaKw~amD42t9o`JEZKlm=)& zA{ni=_Wt$WS<=A#lZ*@TYp|mvZXDul;Jc?7Fcnr5$BQ@lwJ2KaPvTqwvJMvQ;EVn= zM68cX$*u3|__+VjvE#@Tdhem~_G5RbA*Fw0RJG{Do;mJ)WB&{VA&FZB*EJjv@{9jA z6p7XBy%fcC_JGZ#nEPSk7m9hsE`BM&$#hal2JUWP>6=~;o01>7Wgw7U6_C81 zJW;dWOVd&^2w={>p?zutV<~Lpn3#GQIb{r)M=JgwuFf-%&G&u#I#sQV#;Bx1R6XtM{;x@&Tc~uXI#LOO@Cg6p=p&T&7#wO^&>L-RGDsaQ%x3e%uwTLN?r}=fyn#f&x*L1^f7jCwhf-8 zwx;3wcQ+;+C&&5x<>8WBkl@$^^s$5&b8p^?17O$}A(6HDIlaxURM!CeA$2+C2 z23@=)GArQp&97hi0NGRhm#gc<<841e)|D4Paq_ZaohuH8*XvSi>(D2sD+4cRYKo?G z&Jpp&f%vBP$brhpeKkN{(xQTMnb5pj3N7*u)UT$QCr0=NRPdM@s5TdiQ@MLfUG z{OyaAauoR(K8$?`s0Ka(z(ZzI4doq4P?)`me@t6stVxNZxCEM^Q4=IQWlNM(Dr^0< zAU9RbDm3$2nEu$w==I(k_g4)(z4>}eld0i*K6N< zmo0qtYcEbyy@k^zG>*!J-gwpq_vxJ^xZY{>DKpwrUH5@YHx1PF^9WyW^S$)zX=^aQ z&2DRdpwaAF9jzAkF!2vfA4{sXQmBgGKHYbHxfX|wd654im7hoc!Rxok!>|7wV{$@# zJ9BQ4#bQf6axXRMme`6_Ip=#Er&1b9d#c@4l38R35yLA7aTZ%2m_LHvZ8b<3EwcK8 ztQtNcO7Y%e&wf?(@HLH^UvoS3=|8v;C#17(Z(jGAz$&e)gBz)+lnrPWwydrnSEMdl z@@hZAI^H#1>uVHF-;vRM$9=-p{=)59uL7?DryvAe*1!97W#!P)Sq6=^mr48!l~w-a zH+rWS(m#wX^%TObHrktwamHAHs}g|%7#7MEyU-Oy_b!FGlkLkTl>sATcT@+RRV0Ry$;4-MV2w#TLs~{0!jQf;s zo&HOmqoWOwKFF=lk>ZU9K#RhWX~KXO)HOU0y3@sP8prFP)i@+Wv^7c4Qto;Zv&-62 zVtPRymw8$Kx20DT+a8z&Omzc8EiFBXPrdaSE7Aui2p(`j?Gx(tsK(U%8*l3^Qh~_JxVxG>w<1;@TtE5b z$T_ml5^(1raydaR^XFhNYS03Fvdkn?mn!gz5U&rFK^ElL#=|XgAJx=H_L|h^H8Rbo zTf7!|am9)7{utTj8wX-*(k07MtcO7E!jtNrzF{CvuO_uTH=#Rt80hDW8QIYiA3&QB zAC-+C%R84nK#7kF+wU!|HQwQqi1{!Er}J>OgE$XxiJ|Am>D&vsREwO`gPM~5o(r-Z zTIFf-;A{iqDkC3PbbZc3X-&3cz&+z0g}v}$+y%}0n!warZ^73D)N>rSklGE&69 z@Uw-A+l0cGg{-(Moa|+@_O+${m2yoPzBxulGxq&&Ck0N?e|dy(8YJ4)JGz}c_as$z z_s5&!vng3j_eBmCafN<%*A8at>Ld`N#5@jntbI{hvx+I``_YPZ2S)|O2vg~NoiYh` z$flh1okS>sCTf1eYu@3=zKaHtN_~M#b>DrQo9u55Sh{aFxp*OR`k^xAUaLIFIt_@0 z{*l#Azvt>xLX@U!NCkB1X+pp#{S~|vY}vAQrfrOC|5GgSfILkygYNahbwPYSJfNT`co32AXeGJ8gYF_^xBo={7P~yTgrPB~y94MHst`Qd0T6 z4c_~utG7zw;qU{v5VdE(WKD>k-LZ<|Nl-r79B@;y=` z5Pj&mFV6`$PWgeN)rS?Xp_(sr4K|%3C5&B{ZHHfih~lb8e7Coxzb{vR9Ph_38$>LN zGnIRFnB6qc9*91Y`lV_Rna6w0B-yxU994UCNL=$LMMyik(Sm}Y& z0@ZY)NM(lPkgg~nUv0tZSZ`kQoI6T9q%r5c+UYdwc1w{1I;Gd}-+5y z7zT?}OPUk4a?hH)8gYQTx{19;Iw?0TpPSLlolLU{)+cuh^qs5Z77|Sso%{WTXsMF6vETpwitg(`1DX%C{8*t6T>v4}; zGH{vGBi@|0rpCJ$d}>V^DtCmY#_rHZ>x}yU3X)wDcNA_qSosQ|e& z2QD0jVYPrW-@@h}vJ`K@8U%n9wK8qhoBN88o?bFs0}19gV?W&I zrgqV|L;G`?LGGrG?KxMe-^r>lL9!2qqXfphXj{6!Da#6+L&(i2DrV$B>1!w6L8-7bd%ZXO$FSSLdWl>EUx4XUFnWcnB7YC? zt}&zdO4RAt`_ocuP>K%2S|NUyN0Icd{gky5u7lk>vjP-?no;imWp z4|t6W#q1cJ>w03Ht@zVgZ|)=wYq3tv)rJNVIJXW+;6-$+@Z?@s&Y8^ijKhx23MCns zv1_tYP2Gr74zpE7d~Ju5wKO_ts3-2!)CHvENkQnTwfPz_@%Ex`M20uU4*FJF{Qmfg zwX4F+^t9)gcj-FgxuH|WY`)P|$s+vMv)*08^<%i|#I04@W0=cH`hQHGWuPhWZ^l&; z5WKB$e^gV45O3DbuU8!PFKujPdofrakBD&4#C$p%k|zM|G_aw=PMWa_RLP}c;zzRZ zqIjDc8$WyJcf$Oc>G@v|>qa6!dOHs~*GHHKrRml0YA*DCc=(}&=_A;@b@EXa-^5U$ z$GUBZ;(Q3op;*W=OInXQ+1%PK^6ShL`HUziZL_ z_GKHN9S+DbLtnCV`qc&^r{Gj^*RFxE`5NCaZ4q~V+*U(HD6nv^DxDv>Wp=wwrEzNQ z_|1q&$Yl#tg(o$sJhvP~IR(5goHsg;jZB0BPNs7f_t1@*)kga}6_v;uwd$rhrImt4 z?D$S^Wj5CibuEyq&P(Rlk!{6Zwd(~|<%DrSAJ-}_ z;p`Nlnq*aWx&DlUW#FQ41nxXN5Du=9l*Gn&&&nmTV7Ip*rBsh>_XX83UxzKE(F-AZJAPyH{z} z6%esB!++=tpUMpED>`P&COfE1U->wg+Xp0!ZU;j;|3Ce(-$>pT3F zm5n<}3PSNBybj*@KYt!Sbai8$v0OSJLkf)J@AMMlZqfFqdz-gV)!Mo25#|VS@98@9 ztif^PQO?H&aGWs7gyuWx*g0kJLHhzU`H=E$q;~fG+}ef%@3@kd%A;^g^awpUBu!j(Zae%U6hz@6gW3SBg2T;7^Iv0(Te;^pC>hSF z+i0HBvz5n%$6wceO(@|@0@3FjKkb|?MXnNHASBdRcLYF`l^>La2z9TFqblwqFv)A} z_rI@tiGZ~i9&@X8gnkB&VteY+s+ev`2$(H+YCiG^+R$NEYP^nv%=Ma9_;wu7;(RAJ zUtrPHf*;U=#rZhMG(6(?bB{GO*-$O$BWC3UjlL_!_9=CPlbD`S2hF9VZZKUa4a?NnP`sBudY8onJ?Y^jr-`m z3r>>34yLja#5;0NK{1Oik>&JTf9UTnl;pRQBi&T6N3}DWrMm}V!dr2U~uEGAb$e*(z<+IR-x^T(e;l0(jbqm zCk1hx1^+b34whG)xvSl+D;+AtXkGmjI!9LSy$A`x0rWvW?r}y)S6kpcXq}dF$b*$t zovLA^jL@PjRPjWOzo)IAOG<90qc+<0L+0CV)UM7A5^4u`7Uwok72}P<%20)ks6-kF zy4Ttm7^bOE=4Mlw$Bm9gVL<%Qu#N4h-QH(0bG;AcO!yhQ(|^ws9It`p{9{Pjw#GvR z)F3~ZieUNmi(}(l7_U8kx79E`)WtUlA#X8+2SJ1SBAy$emF&HWZZ&5{R z>XKGlwYf$WcP>K9?vnzeA(Hca5hLEk=y4xd-(vwIQFMd+Z=`2b*vC{U&y}^;k`jKU zCe*p%%N7_|wTEoaA$%0I199(ZM4<4&-p;G|{`nQ0Dj?owXC{buaZYh{SORHA5j!w0 zQkyQRC|xWG0iKw3PubwT8|2ScI5|6Q^_cZH*(Cil`s{C!1UdLZI*uI%stg^%-Wb(1 zDYS;hH(evlU+w}$LSo&VYcec`{$*$s)?pKDp&iI%5ii}nWLvdvZD6IJ)G+*fQ_3L9QJML6Gw4RfZoo#EaCZ}pLB z1}C}N642bm?FO!mv_oxnvT|zK#H}6mJ__{7ieE zPR{e)@Hb9l(J8$#6NIJ2a@Dw_h7=pwL()L7aBXpSvTfNHsD5KF&X47)!fGD_zq zElxr6E=@Rui{|UNOE;l)P8aCQDVz+mh-a*YUWF+E>^xU;W*dW#jEmRw4p}tK@WHqf zY|{+zJLOWhVxPMtY4@ay^F)cfZaQtI`Y%-BQ;&lBx5?g1%bt}l@I$k~jXS;=)1AD- zQGYKf(hI~@q^P?$HdiKF39}Z8fwwrJfa4b$SG8S57+`hFVXp$QOUoSGsnt5&rJG_~ zFLZmPYkC`jCrVBI<0G?*EZVo6H)1+<6s}z_)WaBd6inlqZk5WLLZk(%eLec%Y~rkX z<7FKGF`PmI@Qbojx7*?Dnx}#hwp3rslPtQt=Cx8=eHXo^hn-t-I$CcUWqBMQm({d=GN42 zYrZc|F^`$FPs%FEmRnqevYjc7HsK4JT0diLk(YJ76%SR|HrdRyDh_&!(-lj~b!w;H zv>{h1vRlhEHUP2N_lo37`9M{xTz{Yb(Ywi&ka!jL439*z1*)4yr2kZyGbT;j{$Wl* z*ff3WllUNze5xV3fvRV8Ip3sN&aTwD{ffc5khSH`)bMNiabN5UbQbKUJhEN zYVqgkj#>&aBoD&BrMq2D|1n*c-7IRR_m=>Ps|dxkenzP^AVi319%vz2QXr^0>WOg6 zq%5yVJj|qs`u@-|6>Zz*SK?p`m;&=42JEZ8M}i4*S^N8DiJ_FC@mUofqIJvr>9S+@F5>%>BjYzL{p`U8bnX<28#%GfcS=BSyvZ`JjUXvGaLQ`Z z*5KmbSgqZ8dt)7%aTd0vo~X8j2)-tC9$H$W1+fpDE}jkTE$y=9Vo%-LF(cLVUWe<+wFeS zP+YtEr_dV;+P^Y#8cNkYHWiJN3v)f2ZbZM3$X?XxQZjfvG}nK(a>vWY#r)H63}2`D zd(hdpZD%Q~!x)-kGx;H~cL!;L9G!pJ_g%hlx>RIaf%(kE;03=NH6$K4TDN=Dt=~II z86LA3M~okMn=!MP_wqg!%UFFc&Ja#Hf*gQ!75hvWEVeW?7zfEWrU@B!oJf>jnD9br zXy7>QphI5c&qwmA5}#Hlc&pEu$nL-N$$aTv?_N|YL0zWrl4^=FGSnak$37{?U!n$VLOQ=AHJik52moT#oVa(T^*|9U5$xh zKG@6d46&+YH*G%A!ZE*fxnDd>A=!H-fdUT((@z!q9?%c?=pJv%(pR{DWLkVp9uKH! zWT5B$*Ozr3v*s_O4v7`bux1Wd9rFCv$@@8Z)Jb)K8OjEl&^cg4`cCRhyh%Gd))-^g zU250;W6G4GS}CP--}T;yd9lR_?gJH~tT6owFm5=96>OtvyJ<_~$hc^6{LK**wUB%R zJ$%43avOy@%E9*}efR?UmLi+F{N+s$l9j4OmL_Fat~;Vw7F85(V|~EtoS~(EJnk1H^E%r4l_XkYbJe6PyDDYsz=r^!r~wO$8_1}%X%Go3i^K6U#rIe zp@-S3OCK8un0F88Rp|Ch^NMe~VOhm!pW{Et(9~H3U88DHy2-v#qEvB&9#69?!IXc; z1}}p$eW~mB(-fB8=u~8VGx6C|f6*T?58Vd7ggyt~1eX6XqoUl-ZCuW7BSlV9iNLn$ z)DeSD>qb2&x~Fn?^N-RY^OoL{@FaX;CjnybOF>bCRJy#i?G=%qHKiSkvftY3h{kn? zrYjFRtXH=pGGufcBtB)m#@%1c`Z(At`t1(Z!!I10;r|xd1z6Jcp+Owd!9mZ{TbD&$ z(PmWsoqt|*i<2s#dyR|A7+q}{n5?-^)&ktyJTqFwZJQNAO2{qDb)l|IBgb&dS`&W> zrCy>Ric-b&F>ALG9*w}u)Pk>gP#X2CyjN4o-K*W|T!J$%Py{Ak&azbs+Fr9ziNBUb zyuayH+~z+6&{8;A{I~FVkP|eNiF)Q42HQ-sjN#Q8t&Pq#yrn8#K8b_~Y?{BG zbIRm`&;0R04a`o7B{4@pf@z4D&HK%0Ov0reORx!Vm{ILgy^AhHP>k2Gu4<2TLBo&Q zY-u@#2yDdJ%L*MH5T~DSg&<^lyTKuK_{zvhU~jAdEhOb$r%TgxWKch-=`Hf&Q9nj1 z0wl-CXDy?-kr9i$Dm=fmvTJ`CTipZznHFvwDp*bF ziQ(M+e1n*$V55e;4z(5wNVVUr_%U3JFHngDLdAfb0Oknn=?$!8ZDw1e1G>l>>N8-5 z-4g-Y(3+%4vup7W{mis_3iFj^f7Ri?NSFvuJb%_W4rC$-n~b4?g|AWT*g;Quc(v^u zuAv*7BmDlIAbUN3lnmWF3Rj+aKi)}3bGW{!`c=%WI%Op4tq#G5T(8x7lp9s@>d4;K z-fbr^1a}UHsAvS$48()#`ZE{JVi>1M;=ki9ACborIa|TeNl>&QI%eD+HN-Y|*>^u$ z;6&nl>d1hm6t@HKqXHj6`1Kqy(n>`zVC6kdkCbLiI*Z546paaaevL4J&=ehBhK;=y zNn{P<5q-k4;DR%Szm%nl4-i!V`=)TMSpr>_yxJCeYMd@gzy!0K>6l&CJH5fL5(NX5 z>W0#M6xUZ@H^MV4J#S@GH7z?D(Oa{NCVj3?N1Noxk+jG5uh$P`uj;a&q)g8|YIEA+ z*Rb!u_JFN!PP^%ZljGm_&r&EUGlg9BIWj((-KWt#Skf9&Wj*H{@zPUz`bKng^bI0z;7Pp#8@*B|*VkHsZTlo3-5)bJ?!> z{L3I#peFYhGe1Q=ZNDQ}^U%7^5htt!J4F>IId;s6kRQ%pZ_+IVtk3fiwomKv83Nah zrFCsgmDR+QyG4=dfoGHZ*wX&AD_n2+aN`shBTOnZla%wh4Ha}%8ky%92HQ&Co!5jG?&m(H0}c3 ze=(PZD$x2L6UTwH&EcZ#q>^-_d8_;Qy^Sw6Euvdjg33Y=-*q?~U0h#&I+N69B3YrP zpN|tk;Z6B10MIl@R*N~d{dvmQ*Qt0)@x15wpw1QDXH?A=(-`B9ynDtXHe`i9y#aKH3{HyQ|&^j%*tMvO~b9yNV2gnJI;L zi=~ohdlbtm>Nd28!&a7hQxDHc)`I>rJ^gYYIbk+sMsV!_v%zG{fcDyXMc)YQWq|F# z;u2u$G0oQGay`p7`YD8$K_+HwbXUC{&RK-x+ zo{nmAFP?ZlsZp;?DSkXmuhH@KW-0SZnZFp{BK;fXXl`XkuR0Gm> z>pc~%kztRgUH8^M%zM7{@A3&B%NG9)4_EkwMN#EQqvsm-L^D)IRR(_1|Kip^DF->m zLG~*VsRlG-evyW>v^~@JaQi-F)?zV&YImR$!H> zvMn|aiC5=2YT@kEhZ|8~%PPEchVq7w1 zs+h;wbmTt4^p)FGw7<2wrdgr(`Yn0trL!x%@kup%gGhp3Tn2gbpLLOPw#~(?lRp@1 z?cTa$7}hpu0@nScUH?jBQ|kWykQVP8TKgXpoYw3cb!VH2>=wpXxOwMm&fEh`!M665<$?4LEV>ZC6$qdomsL z9yT=7(%g3M8{Z#|3pWD;R&bg11+pEl{MjCJ%6%mmXZpm9I#|{*vNbCQMyj(q3t#D5 z85S!q4Q%h(sM}jxgKOS<)(i=E%+s&(GFUo_*5DjiF__~>sGxY;d|c?&W<2D&jP$vD zb>>(_TC<75se<);Er`jZ_fU7+zd-pO+dXANH~n?;<3Q4z*%+O(b@ z{rj)Jz3mXK!VP)-?OA_3EfbiM;OP&Bn-l=h5{3P?)v&bojR9{*=YlCz529_-Ov+*} zA1Uu-t-xO>GeXAl zUwf9_aelRI<1mFS_89sj_W8#I!#4gqFeO9@WFBDf+mG<>HQz#qp9Wqkm9OXf%{TK? z1G420o{F9Wo^F0 zxuAwNwmOIt2KMxd2ecM#AyQ-q=f}Czja0Mq(`HxZp|-lDx^N`a&tkf_Vbqk8R2*-y zuNZd0{PwE||64fr+*MD;#dEZa=&fsuW-J>ZW{77l7wj^%!WDia_ZdyUST+*E^s)wB zB@LHu?_IT@GsKKMs0wA6pfeNmbr;TT@uiD{(JT> zJSe_`?~i5%9TzSywR&TT?Po4KncJ>Srq2`47%kv$+K|i2FUl?!*$D!h?xPY5`Wr;Q zjARwCme|fb?jgrjNR~+ptz&iyhC&4=x@Ep)*r!#TMpPw9B#KOjZa;g0{n8safnGi4#APcDmjtpo-X)8739H zFZkpC#47?QT?*`(%xU7x@RcI{+y4Y#;~JYD^{%$fh+fnbjfMV1{fgZTa7T%M&RXvn za5?fW^XTo{2-R!z!@l0GrDS+}k7B0nl{fQFBX6!p{s@{$p0laQ7~HYO?_ zC7a;51psmr27cobAQ))X@ePJ}-~G*6yThEa4*o1$=ei|LT55w|#NMKNlZ3;Sb|OJM z``*vCaAD`R3*bc_@4Cwj&Sbh3B(N)wibi;reib=;>lX4pJKWcSzk0~40FMH5*c(*1 zA7}Z^RF-=5D%BMV-!QK3d}mmJc6o8?^YQpHh|Z&Zj3>-*;g)2hY-AGia=DDIrg;`i z_QkmtO7D?&jXR^#=n=Nfey@U;7-r>FPUx3_y z$H(M+bSPi@Qtrv8q&Q_&RpkDp)A#1bYz%z1TCiE^gWAklqv1G2Fk+mZQ@mhZ=c~({ zi*J!J=T9wPOg9k4A2))4DapdO{|POL&nf*w5MM#qLxoAYCLR(CrE3&c6drqb?3Uxh z!gdv|qFLDnrA%+?TQZ9fqCj=IC<6eNPI*O2Y%yiNPX@J4D%vv}bmj#w5`~|7hSQ{b0hQc^GQ5wd~YW(5F*%n*awvwFfUM~0-6PLm&2Q|_vm ze!M$x60qVTv%?=X9bkO*ni_I`K5m|4k(#|=cA0A85HlAXVocc>+nPOBmZ+-UV3}2+EhHccp2fhJ8&TF`m9M zxYTJ-xETOJtpN&pl^M~TCSyS8d;A|$NA4NA_hN<2>cerTgmr{TW?3IFz`5p{y_(IA z>KJ*qwY^zis>*x|H(1narlC8y^5U|t(pS#2w(SujYNu>;7*+NC+edUsDsY_-D+S;# zsPxX2zDl|@jMX>q>^_l)3lLkaIKSm<@;+^~t|No!d!2p$%+{BPQxJ^H{{Nb5P zCWr>n!5aog`#)H^boPaN(!K-;>(EQx{vXY@sNtp=_QlDC8~Bn=Xs5fz*S)!E~TXR{#eS5V$cmS#>jN`tDf5 ztd`kF@|mgf{NkDv8v{>bWyZVNY2Va=e@o`|$woK#L?YP`Vfp8Ln+)t2A++&YMo%s` z1oshltx1WT`G_>aPst;Au8R&48hD;rpA@kMe-j|S3v@#KbxTyt{3oI>3Yarf@<^!tIVsz;T%Pegs^7C0jW=J!-Z-u|S~O?w{SvZZ*4xRsR|jublQFTVA2kTEmJt!X2x6Vm&C@OMIQ+Gt%&eDicP72g&`}z)+Lv4VUByd4c`1W7KuJG| z(mdq{H05qlt!eyJNz=v@0#L1#fM{#}TAR0(6)V-gd;(X6tYpFo(oa$Kx5L&eZ;c5*Oi&6w8xOP%)ss8I{+hA>$8;Jw@TQ)ga<|XT zCD***BK5m}V^hV8Ia&MXz82YYt0R`({*NACRCKi{EKyZb_oh|YRv+0K%>Q8s6p)BZ zZ3vIwGu`KEQWIX??(*7kxoT1;_WRB>dXHs=X9AKKMq3Tg{hLr-?^VaHLjiTQ*w_lKdous+7@%Nyw+%uR& z@v!%BQ|B3z&mC`Q9YdeLt})1yMfjLu_sL?{no+M|(3OsV-^y|7ac|-Wn;#;!_A!m` zeM9Te^HsDnG#kcj5_O&uO7d;lVTWlB(zRR(#Pe;B673VlA9$N}*W$~G1+4xaNnn9E zTc+KJndxqy10WDLH}VP0iVBxOAYuL_h)r z{+g7?V^yU?G|`}{2I-jBvB@oy|~MO^Zpq8S^G+8w=m0VQYxc{ro+H9ln0y4m#)8` zGc|O_a+A(QCUO~#drd#7P2Y+crUt&KN$&tA4W>l zmEJ+{N*X!zkGaOmF*;hd?5GshG}AnuOl*7=$CVS2YFLk67J5=*eG@D>x8Fag9z zR~c?{U4XMu=Uc!vBg#UTNX;{iGGC5e(BhFdGy0SeC~RGpok_4aNWm~7(9YNKBlse` z1(+asM4X_o3hQv505G#kTi+SII!6C6OiA8G(em!HtxX@qB?G2BmPQKqUA=lQtY_m? zzvupD3!G#&A0~A7q#gqP^xo_fD%dOxRDIZHFSOcD8RNGf9m!E3r+xovzh={vFW%^i zvHezr%66%3JVkFRf2E^DO(!q43SZTfEw>XEoNmc;3%x-Wj?JgSi)QOlI5g=n5|SC~ zUf`)#v5+bhELzv9@wX%D;*lDtlxl7%+4^dIEF8fW;Jz!d(Nipy1(rT}ojLB`v$(dn z`QT}(g?~IHrFp!#7_QI?GaOS-NJV7J+-O8J7%HiJi~f;z|5{cH$JK|$k|-VDl8S+g zZ5+kt`ab^z;!rL)ewtMidiLF)t3F=2YD(qashYKrAWst$gO4&--l1xFUlEgE-hP+p zqQ9I}EfAiRf-mLcc2K43mfC~auQ$~bEm*#f)ha5B={_XVa#_GISYvz&y^ z^rd;;xtSJCtg5%HahirkiI;2Lm06hrZ_(w>c{!1nGWzCB{eFpmy#rBT*DvTR zc|LwI+CaGL-jn5n4Gk@x$6h(XAhD;q3SmOjS0&WI&KzDca5s~^N+oP7s%}qtTehWx zovK)rNarQNRkM%9(e0%mfp4c`jxm%zpd4gvfa+vheK|t=wC|B*(g_3XRQ+9(cm;FP zTqa^oSw&Vf8vnVu-6p_x)j9f1RmugU=PlQez>8vodbZl=H8=eN?gl093p+t3M`#&1 z^by?sOIknEk;VdtXDwd6{ys18CGkFTZ?S zu56pwPAKW+I}(+8n7q2;p%Pd}(*aG6i3h;pSoO zo|a*mNarni1g|akI;glcLxpfaI4`yP5^tM|Nk-1|1ye_?3rq#tBOo$}Q#L1k)b5`! zb8=v7tZ(FdgBDi!WXeKXl^QN4L$}B-N>()aVKU#Cvb)ax z-wZ4)5J;>b%fyy2M!~gh^gxm#L(Hh@Danj5!w?_?#_)9)HEsO4G(doWM>TA_{Ekq4 z37xIk{pCU5>ncCThPl`FR<&OJv3wZSIiP%h6F9=;9cT+#K{S9ggKmTxofGq-^jO4Q-;0kRRGGfKdq8B$FpE|p;f zB-s_(GMp*l@H{A&LGE+x-b%t=TQAo+RJO%x$VnaZlz{&yCd+?0!pi|Qns7zv>MWa@7>SG&th!EPBiS-D&V(w`FHN807OW)zLn;)e%(qmL=j30o3*lH z2PDK$XQT(eNB$MHtD$#^H9hRC<4v*kxOF_p475aoS-(q#c9zI3TYo!3hq<<=bO?>4 zG6Ijv=5E$_%i3oQZiZRY^@`ldGv}b}MQexlihe!Cp4?tx_c(8h>{ncOBveC71-7d1 zG@u{Mi~Y?G_gl|eJ@aE7$p7-!AV^&EL`Xp0bQZZVao+Ee55`Wkmk9TQzWyAz%wmKx ztuzl&B97Z@XzffK4H$c#C_HV(d|avHO*(>mMd)%*wngquE%O09l=DJwfjl!arFZ?q zOD{4A2ht|yBT18j9VOry`;OfdG>d}z2RSPL;K-ItZRS#;y&>Bd<-b=HI`40>tOav; z*xr&(){U!iovzwHCJ!Kj_yiM#hSY0s-&rqAsY?q9+}p!uKO(DcJ;2qJsUj*9SC3^k zIydY*dDD{CmEU8_imj&GmSeqDo-|ZP_Bb%PEkN{-my!l8!rj6KOz{PEyBS*A)~n#J z*9y~!;r-)R4!*}ahihMW{n$ucdZ^r|(%T0xi&%B)e$n0_=Y-&p%t|%InQk|rMY*u$ zD63sgwclM@I$h%#w7)`@X)o8GwYO$VaA&1e8JU=f?gr8avg5r%W#zIY#!J=hs%ix@ zZDrCqD`QgM18TqSF^jx9gRvEF$~c{ zirF~&NZ2TqAfYS3&9lTa7Hi@#HUD^itZQ|?!;E^@lE^|{?etyZ)7Q>STH70i_{Q2B{JrFafeoNK6FkP8RAqdeuP>&XhK_p?Ae(`N+rW)E;jn$Z?0s z9rSB}$VD^T%w_hf#H!NmsPRj}7h&h|X4G5HI?{c^Iosogu$=u1aj>F<3UZ=1% z_4luR#en|edh37ItHgOf`&6oqjtjE?YL}XZaiauV9}J$@vg`X5es#Um%)R4@v3K`v zt8C{1F62PRGDcgJ%DiOuF-MxJK`>cwg1G+#;+GxxNnMcv8hyMp8%b)@W-qlM**2Qs zd5|G)bj7eKpNl;%RG<2;fAhYnuo2m!3Lcn`PWLT!f8#Kt2MG}p_#3mk)|B)YEUfUi zyzs;0H|IiELxFY$>2Y>2!E9@js=j!gGN;cSW~lAx;_RmQUIv87;kl^(Wu@9SlpiXLX#MhWus7x7FQs(jhjc+THgVZ34{j>FoxfaoRsQ`p67)kBwWenh%;yNhP5bJH1D<2^@bQHd`5+%`6 zZxp~tc&*u%B&q8+xQa6jrm%!O19j{Wt^>!?bqkd1Ri=-wb{dF1m>w z5}Xgn*%*i*zhb44VW>`}G^mQWjpVWYQ#eK}n3Z}n%bjsQTqA6J6$Y}DwvHDrA1aoT zm0t~yC%hZB-yS!)J&%kiyU>GBoHgfl!HS@8z_t=eKohfRKr^7t5(XK=%Fj_@R2T4N zHvpbpH+0dq3t{EK4?9%x@1{sPCG2v-#{2cUDVP&#cBfGA{1|ab&tCQ5K53#k$ukTH=+HeC6KBqkD8%{(K=KH!e<; zmvMg?ZhIC`VEXLor`w+Tnx&Gq)%!=e+4$nP9LHzo?rJDyd@`U(No&TBn;dH8J~_$H z%U$S;Y*VKCpMjP=9CRF11Vs($7Ui#x4T?<%4a;#-V)_%C=_B<9Q|<3li1QcVKJ%Ah zD%42##b#f^1~t6nSoV|XV6E_#4xx;?Ap|3A%5K*|N8UuKH|pKD??o2zEw91={ldj{ z{&y&ZY01D(Q^bXlltQ}>wx@P)iZAS4RydRV11WyKCWkUS%oAytu{&q@&+krS?PXtq z1Xx{)U%-v)aq6XKA>2ptKEf@}ze;p|5<`fKx~(s})Zq?(x*~Pu+lMP8tfIT0+ckah z8G5|&ACn3Mr;ie@q_)!984~2cct~cPCqsoSu+bQH?j^Zf^K$z}y@-BzkKGUNhL!4V z)P=OY-UcRHJ1M!ot2Yb;dwKYHpQZ+ir%M$Fb!)Et`sZZZy}hE>{s$m+zavZw%Lf4I zm3$|j9=0ZTxAG+K1l8Y&{3 zZ9KB|M$q~S76k;u*SWtPBu6#X7B%V%c#j#0!NIR8W^io7rlphJ=Vp=> zG2bvfe>=XVq^VJx;vF^&_j@0nt#lEyxRZGcbZ_QGLZqs=rX`XNvMsai;HZngMU-J< zMCLRd3>@``8e3o8aCj5;V%lNLw>P+O-$r)RKSOn+W(*=&k#D+DhxVDz*Y3m9O)9Cy z4)CiU4vOQl+P7^=8iwiCB^x&Jb5*aUlbql+9#?wCfBCrOz1ywi^1oHJtf$b$LS|hw zJ*ds)3B65??cybRpfj#hn#(+n3*VtRI-WZ5e;ysWC&7F2C*X-K2&@9oH2>OUO&9zh zS!Ws7WdFZ?ycAI>73oq!R7$$pWdH&K0@5)Ni802c2aL@kB&7ueR7!FZW0Ipo1SBUT zH%fW~8572?|M`1*-w%1T7mLsN`5xcncpq4SvvVsBwUQ2L?i_!FUykVcA5@R`Xwz_@ z7Yt*!&ofTW(9BG0_2k>{ckR0*dg{w>pVrbndtwH?$7*+G{Ee1tP7kyRWf7r(o7gP1 zy;m_c0N*2sAlJ)``dPy+1L?wxH>3&Z_U-zIE5w3%a zmzl$2SH@v(^e{3!E?y=^AttKDsL~PQ-=mr~ZSiGc!S#;pd^hcW>tvHDyMfB}KH?if zok0YJ-+-P~=%W#UlujCD^3N&uxu1RAbysAIo8vDys^6&pSDu@idH=zCt}s`$eyz zrjcV}b)72FZbT?xwaWei5wgvN6#kyF7Jw19v{AVtn-GX_kx9pslhKsy*g>I_rIR$! z6A(KvJ^{M1Y%7qwndLWw#AE5*quV0Q+tz1EGev9_+Rs^h7wcKXe`JZYinw$&Dy0|yPcM+K&Lqg?OLz=G}8 z_w5L~`u9$hKE1c|pM7xALOp?Tr5sJnBJl&^k+TRz+VgRJ0YvThLx9v9$@A|hQjJ6V zjiY%{md00yX*%lrxhl>rlSln4DXwtkhY72)+;kb-Rx1fZWTUatMa82Jj$IhN@aac^T=G8 zl$0~LU{zIIZtQB;65fnr_xlu|UTm6z8-zL)=Ver_JVQN&=qr51Qw^*9$#7P{X+Kdt zijPpwRbJ2MvCR!79*kTc**Z#466v~{^k7is(}>84&ao(S415--pv1@O-=rUqN1_L* z4pZNkjK>)&mG%w;r6bZk#XT=uYU`+H^ZcJm8a?}_@5qygSAP!OMe`sd>9=*2sQBLe z8wAx6A;x8@co*MT&;r{pdx)KO53@ndDWb6&zE!`P{P?Q|pPRd~LCC-UHUCPb?Pc|X zE+gD&6!i4?U0_|fWdA#Ko^6sV1-MxZe?;6e|y#*fRpwPlj;ga%7d*Dty_f6smT zU`4LvA!paFe`8Cah+Lj=;Nq;!Z~V*Ol{pbkpYaQXmDcz-#4e1N<$!FL5#Tu^Y#=R< zZGoq{CF&~jDHXPwLb7<1e}UqfT)D|f7Uv?aw~0|&^M>O~Kg@Kwg$9>a{$sxsIR>CF z47-!lFXjAA+NXV{*O53)JDJxAe-^lXMm}wX5EDzHr^26&ZUh*sDht?1eaqo^UOZ*c zI~y%R*bd$H02ZllCmBm8SdgdUbYZ)zC^b3eKrvoOAvbI(4{S(TnOx0qm!5A8ESYUT zN;rCx`TLbxR0mq>g~|&pOd8tLf-aNQ4(3PH(U#G1`WLB>k2JPw1T0vjOOn4V^dj>HqvY+>Q7n#{=6X$Ep457t7T(Y9&gN^Q71(Xt8V`6EbCc7^%PMI~6mvczaU% z-eFeyL^y6G^0}(k=FD_992vzh*nuE8%}j!w zU3MVB*3M+_-gBvUw=d}nxV^-Dx8SLqzna_oh=@QfJ(_Bm#LfFh>r<%OwOsySPr8AC^*j_)_1k23(?GBJ8bBG6NM2CSdB2R7a+o>G zJuNrT**B049tU*0h+lta$64P3ursY2H(eBRW&p@l{`N5!vweY+;dU&K`su28QrgBw zU+7#A{_~9tx=@Wl-ho5h)=Wt!t`TNWAP_I5R6Wq6WV38Mn#cW`sHq=VXaeLZPW0+s z;9&3;(+Nu!UGf^n6ql$fW_AQ=gd5$dxAf~r$ig!x9Xy}o=2<4$ekq_Yge^O3=EKq! zoQPj4VDQP1*OLEOoZA#X)51@Q?+Oonh27jXKfFWbE4#JfDqP!u`!;Ft9ZYvUXN#^0 zd-qu~dO0eEdkFkK$2Oi+aPfEe5(48mwVmJfxH<3c2 zNB{Si;LNEZC7bNdO1BUhu6)i&KiR(^-BV`NG1C3?Z2`WC!X6OkzM_b;a zy8x%rIl}A1UW$NQ1A0Gs##B_+Zt_p_=|D03=k9eU%&PwEBC)-@on|+ zNX&&bx-LPj^i|NcTP8O(gWBST9H)Fv;1Nznfg^n@zv7fmCXMfz?v-MZMngwn zz)3x0lC*33jS`IsbPx7Wsl#qr8zA5x-^J2|4ZGj%3NC!8`THEIL35y+6*2y$?=KD( z!~qWSM(DAOtJ7c^JxN&n@&*wclQ6n*N$v)vxQ^Ij*gwblYG@*H4tHUHTjtJ~ul#|i zj!Db-PO#L(QsdX?Jt(3RDq8;9j@c)Zz}b@~oWE3X5Hxi%)@gi+cs) z>Btg1I*U~L)_1G&Q%q+#@6hbFe~FQw)wmU6r%Ls>P=5KYvD4wh#^e=GLCFpA=_PXL zwi+e0TVH(w?T$X*Lv8LpU$xFBra&o(z25vbs9({y!G%XOD!MM9JkzP<`h%yNssFCx z`1K2StWR5WUEm_Y!IgJ=w#}Lid<)E(-SG+hd&Phu|^2K zeag#?%x9+E^?=Hsd@$XjPmqudc=~PJ5BFivrYp51i#sY< z&*{$CD!#Gx5~tF$##dA1#pN^qjQ>crUhU_(M4~h&qGsMbr3h@5=4<*q-iY82>xnq5 zrNiJ6_i2th2+f07Ym*EIgX6TbjB4zk2A zp+p%*l+bNflEoD|doQ}~0QZtawXIt!p_=EO6qdU5ec|(#-`e_=Ip)CkQ?5houak^G z`xyq1Cpr^+@_{MOu%tI1+XGy9fBA#HuHP7arFBAOi8 zY|$JF@Pal!yF{#03pzn@`aJYLy`Iu-87f;>0UJZ(i|$a71;D0U`Gdom^5j0Ncba3B z3HtUeLwZ{B%goD^Ug)m42)g4Y1UB}$8LJ*vhL z43QG?QaSauDCfI+hGRQs`VNw|i9-K;#pI~$XQoFB_6_#6h8Jx8r9^at>)E;&E;7U@ zOVbd2DKsaswQ3%_Jm6KfV2m7nubQ3-4X)2?DS4-v&iu_QbGBvHr3)SmKM$@q3yPKv z7HLf)OWwLGQewZW)Auyou96`urS(iTFa?~T6~;`lbshjf&*SnjlOyl? z`6pr5WUssH{8HID6_Gsp?KP{@>2&S)7sif8WLm8*9~OW1+tvu32|Z%$2+w2qb-vrR zuC(qnt^W=fhSWvY>PgU@Is&13Z&tmh z$eM?J(N906i==?M-btfm`g>~KT3jH&a9TThn5BxkPRu1@u z%?P;XIC(R6>)Ng6THZR;c7@4>(KpEF)fQq41S_kSvkV$?$=8dfruIKZ&q;V+WfuvU zMUGwFnwDu?2gg3CeOU39Dv*P`bJr@9_f|FT)>;-`;CQGi{{(xWPZrn$x`H#Dbv}6A z_|lg#S5@!Cz^pAtg!X`m;3c-+X*EF3jMZl1mxO0>F^a}@@itAk2FR`ghou1xT2Z#- z)<}MkwQ^1g*P#E44sfK-e4xqz!kkwtKRLNi@uH7D51vr@d8!4pXsUT&M^LD*G*4!C zUAGA22*my{6B>}STnfnhw%T@;9xfM&m{7Ner7wr2PWu_UVu?C6wt?T;X!i_91QSEG>aLRPXQzTSioTD$8vbL=diJJuUv z)2*rLd24>zAGOz(Y4)wnW@=rJo7@LDQYfaNm*KcKNb872d^|zhq8oOr7n%!>*1r+c zjcXb%dh)KB9a{0Ns&WQtIVACA_R;;o2_XiR5*m+^V4S8#?#8xU`ZDNI@muJ%d?I!> z&@{BPweockYreh79e+6qyC`IR@GU1j=n1dB8o&!W!+?@y(eX!^H@cugL|vzP7NN=R zt^D;=w!fKml|NLYSDgXduVt&_ubk2o1Rx21xF;B8P~FSsL{bW&yB>%Wouzp3G4TidQ5Dj z&$}2%YpHo=Hb5D}ZIVegF`bWpC?n(%QD*MUZkar_j0yd1!IXu400qwI$U|9Mu!q6SEWHYpV z>+45jShYGJlLUiu;EA7!PQi)A_vAuZ9wZGv^jUo0tCMo91(?IkQxS}t$NU@GtV#Jz zd6=%qyR1TQnD=QnLt&rK1SJ^+l=_MIoz8H@9vOhoYrK4RWoITtp$p$O48!u zEBL*>r`6ikMsklp{5{>WNj^`gmKBCk#MKOP{@kBG_*GO0<0?Ija@ZrLIr&FCk$DZo zt*g*l+m0&y0bn_fUPMACUsbu>gQSghsj|ybNj;%;$R!cGVZZ{YpY;hbLaS(| z6eLxuCdY<4_Put;woq_y;ldV_7VhiiFR>78gu27$58JnI->8WlCI>)i`(&?n^hJbD zFZi51LxxgFa(zoev#+Chb{Y4+Anf|I^K1M|rZ=?N2Ote>iG`jSHiT!XMya>ig=P}> zZ<)qYk$Umbve!S9j~6;NoYxMjXuO+~=4V{eoV)y|>}gt*(CDWFgJ4JQj46M}JZ%!X z@EN4c1hk3{caS$cDm*!%P1NP2(3(Pcp_WE+5el=BN*gw{U&Eo5A;i1cnGee>(}s-% z|BftqZ5LBVXfe$bYRR$T(N&R9z3rh^TnxE2RbDy5TE)msV7zTqzT)A%l64NW3acke z++UE*RLf=ktBhyO@s?DH^+PeOu%!p8H;R&UdcNZ9M}>z5Ic|1H;jlmla0EX3D63mM zMk8N&5Qo?`{(yk} z;TfJTmD~*?29nSWDKXGwU#BLPZeB*JD<`_no2&lL3{E#Wa^4uL`*B+KV(z1DVpv(5 z1n{<9(^a92bcx9WW_9>de!-HWFv6-AfEIC-WRY*oIA>}VzM1Y3{S(bOgPab$=FuG) z%X{*cIi#(S97)05oq%o0`Kjta^%N92-}gKJ1_%f%uZ+fdZpxkV|L|(AVn|<=Inc&A ziMmFQAh%_InFBOIk5tHko;(bA#X30Il)YCrOm~bgk$q(Ka>ZdrgeN}7AJ`%DqG=*V zas+5BZ6FrX&FR9&M)X`7jLL9TqWrK^5A-JRKzc&Yv~VQTpubi>yq|t;%oBU> z)XJv|%B-jih8OU7B{Te{+IXGm=&pu3dZ6W$-28l3H-8l?QS|Qpe$R`hSN;;4+aPQY z{n&W_8Xp^qbK`m!k|@8+6_D~ph^bD3S?0i*8mTOv5!&2mb-+-P{BbdHZK}+lr zNXi$_SOn@SyQr!U%CU?8`i~{_r8ci1D{A*gNWuYT!v`fw3B5#_vgoyfvSoX!ezJ9l z{B-Vd*)1PIKEX((Xua6jNbyS639 zLs6SZW0d;so};VVS|?{ox}C;{Gmq-mF4H5r#xTaJbb;G_BS096nn2i}ip&}xsEd2I zk~}%PEl|{W8K&33#ClCW>TbEa+Kt*XQw(=(RgdI1pZESVD9MZwuYCc!w(e*dIScSZ zHf@7n00`7rk-fr$)8lHz;_NSHl7HI8sD;muDIUU9Ki4O%mtc`zE z`G2wA|NHy@Lwg4;S)}ROof44X?U&S3R?0WBaO9nV$YPruv71k>i?aPh-*UY3Gm>qu zcsSg0YAz!97{~JYo$`mp*Gb>5E^V%xKN>l_;~Pvo-?x&(VsdlF>9`6wzvbK^2uLkb z&RX0X*29}XZL>noz4*|h9)J!pLLD#w|3b$QZ62L~I@jyz{kUq_q+xdHPA!p3OLu91 z75~+SwebB7xsXdyf?9nKxtMcM`ZjQe$PaZ!>@OklMKBX_()_ zD*8sDabxNsw1jSbT_;BPZO0jy?;7Tzd#On(UlOOQj!x7iwJFJ`FJxPM*l#>lNl8h` zk4cOBBhHDq*Xyc)YpDaUY%#&xCSArOGr>ck2l&=;dD_)9exbzH`i6Im1n^Ja)qTNj^W(W%V6xfY}1{!iEPwIqTrYg)C7nItJ|od7;CVt_Sc~Wkj^G zFVMTofG%zuFGZ`T!s{TkqKB($x0qJd50hV%b2+^RH{kj8bs2I~3yU%@8ETlS!?(IF zRB7K9{Ueuz@TpH;kqXIy5+^lR!%D}i-uP=el%Bu%ZcEsnj89>het)dun8Ba^Yz*;71W2tIoc8X^B<%vjDU+e7I=uU__mj1=_WnCRInt0qH#yWbSj+@lgqpUp?lb(BqhdAVR z+H%8d*>tFiS=UnDv1Fg2VanmU*inY#vkQZ6Fn@ojZt2s9UoM_WnYp0BlX@OBg_jtX zovacOdAzNyY#C=Jqi0(t6H44TaorX#U-TKxcd@lvF~5k-F|Mcp%z?*;`!$R^fVo-m zK%5`xF@a4h^%2sDdXy((R;HX%HV;u6fap$b3$7Gp^LZ&`U;Ep|1O6a(v4%NBE$ws~ z%*zr+U8Vcz2!{v;b4F&Iq0Xjtq$0#DPC-$(ni@}= z=X5bIYbtI_#u09+f_fVKBr%==r=D6FFg9so6p4~I=@v&W8& z-XrdglXr1dO`)K0HBk%NN2*NE@1Xx!1btAFxinN-XShiCLDt(H&sNG%b*>lZkExqb zZ-pF9;q8=ZL*agp_QZb$&iEp9$e_e304W+w&!t*LY>Es0+Gr3HJxNnt+~%qYg+vsC zXLKM6uFs&{bmOY}m3-CI5!CNK@OuOrxJUHG2q6PcvhhAcvSjt*V#L2hy72um)TKT* zn&80+7(CWu1EqbD-?EX%vfV4`6Rt3<+qI%wDMOR#8Pv2sM@;7eUB;sOW#CPE1_@@e zU_y^t#ElllAM11-iu1^u(dw#y{T1GB8~8+&-pz~jx?HJTpYPKfTCkGfdgnc1h+1Ev zonF>k`IqkJKHGS$($OEUaLD+h)5;DAvtdPyJ9Go+ zVkA#DF}Zge-POd`N_9QFpK)!>9r}BRbv2D#aZ~NwjzS4;;;~-;esN;4Qf-ao^S^6M zcC(L$1sCyNIv8xX7nqx#ioWPT+%bMKSuHW{+5CX(!hNCr;p4lnI{GC;!;fZ2c0Fbh zonV~ewi)KPzAiS6q?n*DS{h59!aA90k9}Y04o{Bj&dLEtWBlHCg-p=~g^jrK0tD_3 zNpzN_ffL2+v-;o{kqByHRMy+k=tfHIagXg(R`E0$fIp%RRxUSRu{Sk>To6bPdy^J* zmE5-Qs#b0%+THwvTP*E@>0z7-4dxPA5zxweIR0rLX&oPYXlhavhKVlvp-mM(c!DP@hpXGmG5)2S1_eFK&3-;1RLO} z5vvB%J2?BwPTe(7I54rA5+$JTs!{+<{Njiz%v**UD5`T_FuGXctNj~`)kXoW$E0ch zfvZmxjCBbIH1-1Fn695Wkg?)(##ks($-<_vwdDZB@k43YIwyHwbq;4|G6>wozRG#< zcU2SfWa48pSvVJ+sg({x5S~B%(!O%X&rowjZ9Xx;DHq~f{GhtH3H-kQ<@9^h!TZ!O zKa~Q}d&)b_e4GUPZfq=&iRG|!EzwS(<#5?toe{$o+eiOVwyuncI9Z)gY|TL|MS)+;G3iQV>n znzKVBtLW|-R{xIu@#9j`xz6L1b^*W_Ew7HJF>PI?0rka zOSqzx%544YJWu?M;;oNxs*nv48XVwAkxMngE^uDGfV$i6tDFBJNq77qU)nq6b@h(iRE|Oo%|Yn<@|~dZp)1kGA1VXVFB*K~lm8x-T-FY7 zB8elv*l8j3n^bYyZ7Oi@^A_`I-UlVpoMm5dYz@Z!WISvbh5XEPGGnbKO$2M<8fPxw z-_v=I`o%;1=)n&v~Aid^EmR1P?14NTk2A2c~BN6CB7i!?{?b;_In-Kih6Cz(P8t%yI^ zBO?0GYk-Oxw*V;231&Zr9Z+suO z^WSMx4BaE3?{#1n45k#G9`k;TbGjIN^yUuVfRyEmM*54ewSy_9TJK6yb7V~cvlVrm&^rAyj{U6M8Crum| z!?Fd;-Y?fkvOG&7e*+*}bn|h`*x5T$CVhb{4n~?%?gf@dKWo2e`#kz5*VSs!BKpMLs_NY2S6VE8x# z{#f{15Tw;WU)~jAVg57AWS)S(BscSz@-A(Q-yla=;8V`y0@Uqe%`EqjrTtn?nJvPI zSFpB}wPNb|phuzNyMDr&qIbmdHXlDsE_H?coO3o#`x>v)=qqhAYX|bJ56XBU8vo7+ z1tqJjXopyJcX9GfxC^Bvs^?8*rkQQ%%8S_O_JX&t>CSEyh5B|4Bbf_RM+Jm#5F6+j zXJB^@t$;Kr9_=ba(aX!5oT|e>!eLEt>O+0|`Z0!<{7}8MJ<)j@_r788-@&!BfmdaC z_Yb=Z&M=52Q(sV{@XMuJ1Mapbp z|8M`iIM&DliUzIpvc7vuN${duOkD!knTZE{4qdQd5_qyQ0~}a zmX#6cTU`Aq;91v`ZAZG;t-%^ZLfvd{uk)a}<6B%%Lp>Is_4sJ_Krj;Sk(8|KeA#Em zA8K0VHr09I!9Hw*dIa|wnK9>r;o31v|XKO)3xtc zYnLYDJAjT!CTeqB+?CwoJ+6L z8$BwYNpM{dabTq7MC2f?NtV4VmN))KmBfs z%;;99Jr~thd+i*jB--+oyQ$Jn<*O8bhh?8HVFLs_HHf+7(k(p6Oy*u4ovg3BzQB(X z-w+d<401ckg}_MP4)i#KcoV8K{E-#XKxJFk&;ybBGY#XJ;^|CIN(ipn1=4nLY+5ZW z=05b1`}21ZtM=J78t=C3HuC-q!DUR zxvf=vLQd9n=tfmUIDDobfK&V%cX;=t7{x=+GH8k@5Oa1yl+XOz@bbOt-W+7!AosJ9 z#ry21LGrhr?7s_-JXuoYW&%12YYX)FU&P>2ax~JF*w^#zAen<9J9!X4Xzc6T;$G!I z?EBo7b$Y{&|Dq4Od_4w!E9~Lx(BZ}*lp6!U>cC$CO%S>|)LYAjz{HEG@{O!|uwOWbk%N}GJ# zyPfQ<(07v|j4ch+f8xst)L?1qSlHd9h*fL_rR@nW+76fVUsQ_CEePUmcU} z9+jPB$57Y~B<*fLpT981P$Ju_xyV|ia&oPrMdYhf4+A;`+a~T)?}a|EbyRK0M8X_8?sIdJKO-<-ms5zdwW(**&wp$hj@Z3uNMRj6%L!Z~~5&%WKR z%5_W3eM$GH$}HKI9a|x7&~YeTf0CB!?s(T|;kBQDn1R+#*3q=VZK0I#Pi6NWGJ_d8T(oK7^ z9DDPUx1pwh8Hr~evUs_YK>O*aI`z_3>q_pMgtLZhtWM(cV8Iu8Ufk7g!4bD6X2Lh? zo6t@LccMGZiv@Q6xXk>4R1+q}wcsO;`h zzUM98=LhNT=C-w=#?!ue^}B7fzhcd$^F*i9E3^G#p+@ifSCZ^Bx7T}(F^|7e4JwuX z{W{zK>_!bfOVZx4iX)&LI{ukk8oaLlZf5#I`QF)68@Hh! z>vD#58VbywMFhh$ic;>P7al%fD;Uh#c5roZ9Xsk3H8?Cg+XVM&$dAYwE3@gdAKXF9 zlmjy6>HCpxB-0_D$4V`l={6-htfPK3vUiq z=$s_^$M=bk=QUjT7fpt!C6%n`mF ze40Mef#zTW_{Da0ZCgwkA_vYsz2R7OQk|$?@I@g<*FY3I`vWd_iL7qN-RNQU-U_?_ zFdV&Y3_F(KK8Nr7kA>ZgGTsipsCr&kvQQyyv5yLxkuR`rt()+3vERh0+a9Vo3-)vk z`t(yP`%bYiK8;mb*$5?+e$TZ{C=N-D)4xqClwJ;EchWYD&M%?9OYQIde2P%s`xZH6QF$-nQnfY#G zWn}aAl-i$#Zg1udL;>wQ#q-m#@tq1|z&YAYw4r4|m)JCNstY0RWOi(hwWMi)sHDV| z$ep5S=hMUb*7<1SuJuXLe=MFDVF+5VO}I31rn61xYb{|_jHRA3mFwY7s=Bka;1oss zZF?Buktv(|u1*#&bej%3@4Y*m<0lNC?NkN;E1!)BED?TW!9aF7GnxbU@EaDeM5|n`WWJZQRbkLy@XTR^ek*SKnW2Qge{H(! z2QFJi8*-Zz7r@kyG4{ovch9)lIK|;xbtJ{>xb#wpqVff3PbMQR)swUm>bx|+{ULrgBFXBg+D_jZ4}8`h3_|7SDaIC#jS zCuQNwsGuOf1y^O~{j{)W@&0KU*Y4OHg;p1KF7PwLD7?DBUF$`NP;!F4)CRD}Qd;M$ zB0P^ml0`zH(9noTPO`H-F!Za&fNI7KR`>Id+WjQgsS{%Cth(|VBQk>?{6mx8Rer6! zG+kdEQy#wgxAVK^M4-GYFZts(8m>s>VP51!Em%#e>VT8mxVeKD6)z)Ro3=GktIJp` zuXaF6HjH(gV^>>4o@1m;JgoZIc>mzz@V?FG+)nb;(68e^yU;6oPdmobFki>F&y8JE z&ljuDC+_#qK;QPGc4LbsMfg*%DJiniJfBQ^e)9YKie&+>O z@!pG-<@O(%)sF^g7osn#Bx4U17H*-%6`@DrAHrJ0;{+g9rMD7?7E%?E zhH!wV^#N&;#ftpv^jt6MX)^b=*J7Uf$OB3V*1wF--*pLrGt6Vi%h&Te9<=^Y1{-@_ zjr)F60-cuyeaG9!`xnGZhzU|Wj~MRj&YG%oFo=jibJzyR-G=g*Q2JKqB%_b-nG~q- zvo!oP?&n=Az_+|9pE$Zrk0{$R^~ z@!2rINl+8$Cz@%aFKBG5P`xaHBnF6mff3kPU=!2RWE7*ixvgV1{wZt;+B071=kblN zJnNMD(+!vAWYNCPg1X`OYJ)GqMB!r^t-;VN-TUVSHG+I6ldZck8mL0O~UO(g5q!?;uOVvmmq+gw$Z=niM55~^o` z`+z%2UxosHqkrbtIv-$+N_OUCw~4XD*CZ`jA>3cl2=+YbfT*&BjElwrP*k@xC53*aL0dX25! zW0y_vIb9x#41o9D20`JA1<~{3Xu6Rql)Zr4v7^#?dfvs=2|pvzx}f(yp9T%{vnh%4 zkI@2%++=gLrRA^dfrjS|ObAJXUO-&`&%V-t*R4sdS&zZu8Cyqe6^-B$$u0VIv`r2` zsOGrf`Y>0V5M4_;bm+ZSyU=`#n%{Pheh{7A6t8Dbrd|tr^Oibtfi*(0eT0QMHLps? zk^kbKSX}z;dX`$#)bNeEd{ossG@1X|t>$fs^1Tw*UplwPy9`T=#a{!HmM%{o;XsX| zx%{wmfn>$_11O#cqTCwYT-BxG<7$(b(U%4nZAq!?{aG|5(e3^u3cRB8T$YUl0`?qb zZh;NQn3wvu=&!pnb9#mv>ssr*>b|wWZ(bXkntqBP@2iMZZ&~tWT|;0-0urK2!mPR9 zl=7>^ti&kCf3Ruvn@NTqfhck@4i8h(uek{vBE@4wn`%)_nApGpeRKU29DIzOOQ1$4@i&5{#A zfKlZI>OzbQ4BC|gitTAjAytrd;~jR?5<%Pdr%m=alb;t8kOrdK$P&EskAU^((WXMf z#^0<~L!4{;lv*oi8Zs?%fE2R-{x75jLFvlkavwYyzJ}I?~q`h4oBL z=)zQ|-v3xG1nHUfi%E>C<^i+T1ed?{0Q~4%V?zxhWewk?VycqinX>GOTqYbwQF&;R z)aoko!X-q78J<#|Tq^1sX?Ls-I)kuXzx<0uf7mm1JO}~meBSl?fXR;bt~ky^FX4Lq zBfMAF?oq`G3mwf$W`tSe%s>tkL2HdJ+5?hrzdq$*c~lXiiOHZ0CY4h?;qhIBf#<`C zT%m#{s*N5uh+}qftDyulg_h*1;co#^y!__=p$RCyyz0*cTl~nR`t#5NA+_X~{F_w2 zLehfhCIldL@&_n(zlA9(=C5^65!5Nf4e^<(D-oE_Ia9(2FP{G6&jwcKct25uNr|P~ z*3_jA@VOmiL>0mc9Lpb`R6v?@9kgz$83#gM#^Z`=PVriwqh&tyiST^}Df)1TjF0#KZq`?xHUjZ{`H!cO^GV#jHob^A#*iDpk-iZNGMfTn|HOe#AViH zeVof@f$|qv zkgoBwa!r#AQOvoL41&riirvhnzUFUD8U5*Q2TGSph*DF>HBX_0H^0&&6(sI0`_v4b z|1j5IdwHy%_aa*eTUsw?q{{JCB${%#HGO<<9WRQsSd6BZep**YJHc_qd4m`Re1pdssvu*aabt$5NJP-J37re4Tf&Mq zUBxDX;af17UX3>K$%8NCNj24PrlQxO!Xo!Se5}H0*Up|>sBOpb9VPc6y(eXu_ z;yf)8OBS3A9&~KmRrE!Os}OZ1x)$;0mkuEs+= zJD6nVO=cgMLth2q7^&E2r=4z>^BzKK94l!a8%`|kk3xQt2UhiG`{c;(yCKG}$N#~n z(d!bwmFwP#?Wgm#3CnjsZ7h3A6{wWfHIRvk!FxB=_*@Q1O7!`I-9fcxxP6^`PWPUC zl`b{8g&ETr4V{5*PcW}CRZ#TGZVx{AHvW9a2b)cj10Ko@w(K$tE7@m7(IEqZ?-5og2v=a((}rb|RqA2emDZ{4z5D*|oy%W~DD`0<3i(dbT@$BI(hsILXfTySCo(^S ze{Y}mkq#y&M}fHX|6$yrR2Pyr&#P9zuQ)r?kw%`plX>%|rr1W}XyNsX&(5FwZH(zI zIQ3g2o*L7+z{L<<{Kb@FI8syEQV%=9&t5SH%^{e@XxP2(2AmlucC^mvihYprs9m0pU4NaQ#3>I``5<^74B@ez^y6EUb~|nU&EXGLsGNlBPKqZB)FZ?eK1&`X1{LS$8Oe}VRE^t*$g_^{JUZ7u!dUDw@a5f>^W9^9iG%!%+R9WT!Qm@ zXPO390v!3nm%Z6b@xr-YI0&hxWkTWUIH~cnr}VSD2^i{u7Ung`dzYx)N2_h3!>fJJ z91J(gclgVEk%<;@a`I_J+@^{4q*PlTc`*6ZxjO}DGwI68->O(*L259b7bOVTnnz8->DBo+8; zY3b&lMhxV7ArX6G@`dN51+?vpmaL5T<|0O$tz4}(v9trkvDBb+S6#G&xd76!Xgu9c zHehTRsI{HJt!cF5g*L*ap`w!{TfypcW&F^C8EnCLxA`A#Z9qE zn#`68$r~Ab{FtFI{wMF&pgAQmzZC5s=qrkc6Wl-tZ{({BbmEmPr z3!|G+(i=Ho@O#exdHH;v7kj;(opbK*eP8z#+Itt-%NLwi9S~Lx{uy{J4ydp<=84Ar z-5iA^fpgw)l81f%f;FT99nbc<#tPaio|3JbMfL54r{0SEGB0nFIBuS*%K#5v0ksD1 ze{6`zFSZ_BhOije<(r#Bv@7M;zSa!qTQ3^bfCJ6f68ye;hy-I3A+tt6F?lyk2ft{~ z$cj5b2Ij*@MB)-I`K~T?TVmTy8NpZ!XCs*T+4@!Ou^l75{Wl3xqVy1LdA|^v%xW$ zKJ)zTY*ea|f>&=sWuyS(da;l(ATGkjE!Yb`yBrbYCg)o*W#OF48nL^R^^O7A-<~>p z{dx-s{^W4--sF)sYlj9~zihyC7{Q43OAlSeSh){Vb4He~HbyXSm!OAima9LTU{yn@ zjoVkQuf`eK`{qdQt^V8`Y38m~a|Vz>)~LN>i>6!4^ODa2&gDMSmd92`PlVh-oXVhj zYhB=WQGs_@k82vlDQK?h?A;OzuEA)AA26^7HY^H6-JH8Vh|lMH7^njyG(-@MKazSZ z82`0AN1^i;>Sp|zfN1(lJvL*qL4+m-uMcEAJ{j>Y0mXnA++0Y3E1;Mf6oM++Wlwy6 zRui2~6#>0Q8;0#5_cxR7v>1@#fBc2~Vb8W(51@?&wb6gJOo&xuFYGV2`j^;uz7SUw zA~+h!-VfMhoY>m+C9`Xm=l`9lTHp8Yx)2IcQ?r zNBa;wKbxw8-mgD7t`ogwCDp(E`|I46q~or@eq{hs(ie@%A0cUPW6%;=7tSGLn2OrY zOVP*UK`a>By(Uro)%K&YceSii^KegY^7dLr>-==bgqZ^D!V^DNmx>VR<$YWzRFzhv z&q&lhPpaeAN8j$}LY_aqAFC5cB}CuLa*RESjwF3qhImgOXG_fzpdCf{)Ro~qQyAuA zx^S&vaq~3e>8WhYgLM1IVIP0~Bp8kYRRFz+)v_gs1l)m5r>3PoON zCAM|6{{b$xA@%i~ow81PSEJk!0&0V<%}I>+NY)fD?q_M7_Oq_tbTi@~5$krr^_((= ze3%GB_>sM@2%H80q32cx0jxoDJq(ltnb9jQLG+uHs1(FWCh%48In7_ z2`G6_dhYp9{}el)hBcKXZjN8v7JnpU#Yf8x37qHr9uWxK?|LUz5{yMtVuVkBT*2l(z( zv0066vxI{!-e(rL+`=sTi%6hS;Hr)gg*Znl0AjDPd- zC0;qBBeE-Bg0~mY}N2Fbbray$~HBHDe73B)%OaR8559QOm(Y$;+H^ z;=9$zC!DGeP$XE8+P}9AO-bxwX4+Q%JX2Ky4$k3h8=%j&(nMG>ys)c%)*+M40S}JJ>?uU9 z6n-yMe3^Zy!$l4w-eQ+EbwXZ@G{2GzVi_yI?x8~HiKdEJiM(ufM*Wc&!VB59BX>7{ z@KLIU9t}xj<&T@Fao}ak!-0HD<5!NuG+zs5LMG+~7HTH1Xop!YtAyC z7!_GqYZN`+JfFIH1;9hupc`sNxj}veKqxIl5~(Mcg>B$Zs+m-T3JYT*7q$!p?~bU| zrrfDW@hzGkuam!|CNW&5s$DCFw%j46FJq?7I(V2SVb$>2r(i%HO>}L#MiM0; zcBP&&dxjydVI1chM#N!!{Nl?D1KH)WxO};~bXW1+qg7e~$434GT&1;G+(9`=f-1-i z9DHH0$uf~_HRZHf@T~J2Z0VKm%6Gg&WEYcTI=l5fHu9oBDA_1tmIsfB`BkvM*zVA7 zunJ_jAi)dspuaH1*jxfE>N$^8(C;^ZkU(~a{5_C6$HV_~dA1fuHG%Nw2Jib8TMK%+ zWi2fIzx4VkhKVDO{`EQ~Z-fs-XFGT-V2q7A_gR8;Myi2%74ERC{jRm{ru*zt6IzCibKaA(yOBFmDW@Plx>GgEf0Sd%++}IAOqD?lI76z` z%`u1gxR5(f2Fw@wElgO-7iJB+UGOKj~}xS1-nWp`); zi>+8N8vJgjOyS3TIS8~4j3Lxp3-=lcys;sSj)2{j>yL-pr=4_@1F?BrEe2tFy@W?1#1?hZg`nq^S6!vcFIvqkay5g|;_ zt2_Ap4_~G7{QqRoB2SVixe`4w$Jo_LEDc->8?Ch!|yQ(oj zIw19IPnFR21-}j}L)sG1w+&eE`Cf$QzV@x5XD?kNAa)4Q!m<>q_H7uip`$Rx@67}}XU z-f07k6t2H1vC7`>wBQHvt-ecUOQ%sGtj-hLFog8j`dArKOkhGNfzm$7oX=6bm*2xh zItEJD1O$UMm*jAU44POys3Xef!awPaPNQ$lY%tyB2p>3{s^QtX%Gi)JSI> z@Wyf!wh!|VU1!@DZW13ZtBbxwj~$`zK!Bh4&e6mUJc8mIE6Y6uRoRKhDCH&e(Sd_o zKkrRWtcIwL_7g+0X#+t{Y+YV*-_tq}0h5y+@4r)ty|hZgKo|S1d@dSuiH``ZpPF9$ zYR*ihg(C*n2#Us&|8~r*6yyYK*AtE@|E)<%Vr3h$r4hwUFFsKM-TPpum;%IEB?yf67AT$J(Rz;;sFGuc_6kD#=<>z>bfFP;$4~y zF4=cLd98z0qwKN|7XFquRL?PgoKYmZMNWQiHK(6YNJMmTOnfSqKsgW0#EL(7P0i9q z^I7d&)(14qym`Kh`RJVxp~0r0SPR0V&7Up^jBZra*Xjz$&T)Q_c>gNYrsy^3J}8j< zC-eG?Y5!gIwOn%H>6ODf_@}WqzlhXOf6=@6vB8cS-CVaYe5n1agva-5Qj^We$oz4z z+}v3PyMg{IyS?d$qMI$n0cVJgZ;agFSD2QGA2l-U7TNf4fw=y|jqJw9dr&&3GQ)AK zSY}Wq)3@KN$+6j=t9*tKmPfP-a5T5jS<)Mkx!N=-$1BH$r#@uGXCJnQxf@I&5u=Zb zVNK5J6;JG~s6Nd(D6S*RG z-_CeD!32!+6h#8A(<6P(K?x*-%b#w!5>>z9e%kdjX=w^3k#`mBs^_EV6e-)(ypPJ( zSM*Y^R{J?5lWScqfSP{uiluFZyUU+GRt+ScwS0Ga&PL0-fd9mQhB;bDAYD->v5EHy zCo`Vd=h=m`7D6!{ty}kd@0MUfn(1{Yqf$8+$3-m{C-(Ynu2#0ei_wcL_6?N;?Gl1! zPqJR#W``brqS&qYzCyX)`vzA#zh_0@H*9BAkCb*H51f57!Xq#U7k!|d^GNW@4sT$yDd|cOU3-xl6d;!@2>adZSy;uKPf!UE+n}8BY!0A zQQu9c5;#ASpXzmDDYWN6Kks*`SQfe=Gt~4wWi3Jmu8|Vj_qsYxX<@ee7N{z>a$@n* zc0JZiHbu)`TyFF-30s)46|`7lqlNfQRa^VE$8jlOZ`jC=7~oeDO5K0`*Zh#qfV=Kd z50>k6$K#`I!i{8D;bO1aM90pGFI$oN)b$$+s;@(s+acf+n6~kdS~^Air{XDfGiCBw zHj?N-&$9GO(PcYB@i$urrB9Qb`!;P)OtH+Hf+eezYl*+Ex}a<@Z^ItwreO8Q8-mzYPh6PJ*KWDL&@Aqdz91WK*W=2 z^^J9Mw}$m$mw)Ofs93Fu=G!>05*r=H&6=NnrTc0>U&$Ww)wK6OX<|K9%>L&@O#z@3 zq5ecSU~~B42oqx~GrBT%yw7Y=eO!%P1wX7k-TiyQILb1)?m6Ov{<5SHVgZf=JHc8ZNheHJSZf&|3#>S(&f^dxd?D@!*chC*s zn{E(uaOx2;WkLD`2~?idv-^#XyKG&esx)$U&uS_k#$MO6&h~(~1C$>MYNFzsTM_+M zn4JEXtm0Sk4ngi`T}2e%xd`#lQ(2sFms>;*Wsss`RLDJe2DXDkKD2sA0bB#_Pl+>x z!FJwwcnD;AzOoDdwnFy4#c2$)^egA48t6uH@Nc3Oq-um@oFL=bpJDOP5w&4LuWK$^BRsbH~mSrBxUN$uCWvIC=v9J6?TbY%R%|~ zm%)g9NB4po?&0jCF-5s-jZbcErM8?(EC6QsjA-C`8AArPmt)dl$(@Yw6z|?2HSfVU z9QUlm(mdYIDINSFSART2rBB=hEu{g%sGwW8z~P(D84ghbV?Uyyvsrxb(i7*CXUPUk z?Tl;=f_#BrI)9w`*+m0^l=oMfsd^erW03Gb6MNR{;`m`F@jSw;?!X`o{uzIYpcoX>dVAJm7DFE#vAwF1+62NYp%PWq`sK6(w=e5bnTrv zSE#Yvtz9||LoB5Ni9l)=_>BD(){~li)(%P9g&u!3MR91O(FJ>BdMQ`w4JHc%WQWWA zpR4{#-&BKp#w zV6=N5AJYaRKT05j@9T~S$c$t<83)zK>BWMW<(kVdz$ze@qQOOjogi5AgE~0-O38ct*<8|MV{m@tdwUTnI-4M%(`7*P+Q8f~FjyWbWbRwD^g)2K2D;i*hN{ZAP>+W@-BtXV>$`D~cGF z^Y2go-f2K2*XP~+d@y^uMDuXYUo9H%k&cS;ws(d{M>PWht4B2%KF3aHInqV~Ir8%} z2C9LBM~Bdc1}s5+Mej0F9K3PM z1~Ric*gSM&uyRz6S>U~yFd?DWeZ}zGR4ygt_3(9clgWiCF-?~UTlU6lR2MD;J^emw z4bQNOlbP$fb>m$&B`bMfP*M1&T)X6t8KpvjxQ4I(Tl!YQg9H1uJ`<-`=xuX$RD@(c z05Z7#M+TfJ5j)$!)4i0nSXup*amv|qkp1}RrZ z6D${r7uJuZ2c$2n03o2h$w;I^q3;qsf7#-*$u~m0MA^mtku3NMhB=mysY?+1%nLgdWX%8$J$X z9#zksZ2ALf%DX{7$&wUY{9U8B1TNYtDFaK`I}bYQ9KK~FTbE4b8~Yl8kB>Bhm)CR{ z266$S)JMO?2;P+G!b5z3?e;N*Y?Swg%t- z7L#w+V%2+K{{8y~GK75#fexwv5u{1*LA9z=8MsCKCHCx$4*vdElkt6~CVlm(CHz?Q z!cM$Vg*$pVy^XS#e9&`d0mVJk=vNw?0a7%+?pLFm$RCP(doWNEKBdqUM*D+2;h9-_ zSO-op%H(9+JE?LbC(ZA7fDd$EW0KPLc`l{E4EERPrsClNz;i~xNv!|Za#re!(|Vh# z9aEXsF(`gatIc1uWyV1n2E8EuNmYRF%UFz8VX53)%zARTy(Ni4ygmEOTRit828be8 z?(d)=YHq&Kn^WmZuTtK>z82(j#c+fgl%?x%5$C$PhlqIW~z^6M9?0v^`pEfqfopX`EGt479-X z*JPb@m&~|I`;OR1^qz!Z@I7_Tpi253@&Ex2zfMW!X@y>en3zj$OURQ<@%q_0URx@; z47Z))i(8xLqBGV(&k1+FR8a!VyZEoSmIDyE4nO1%d$BGqd*%D$^E>6%hJS>-qvc=G zw$0hG8`DW?d|lj`7kyqG&aq(PuU1zZCt+T4w=i`3AfEKyYty!UP}cJ03R_>vtP|M4 zZu~0SCag#c#uhw}Tw6`ZM**AZgsDVa+&$uWi6dc)$D~)Fp&*B;GLJ%v#&jT5;X9p* zqLSKVo)(_|uQw=i7pKeCwGzs@Z@ajX}P&X(?P@ev(Slw~_>hgm-oHV7rt!TCsX ztFsd4c*@!gnQTkklXuGVShe`E8iILun(^%Puj-X==~B6L+t@+Te^kn+NRR0WCo_6| zP*a+?Ty|w}ga64~?{X$A-#&1*W)fgQP6s6vxFLYw>F}~8=0)a8LX71g0}DLOY&5!G z<)?-HbC-(hRn@VIp__k>{xn@Cfb6K1T{Q*?i(S3>i`^3=PiDH)*4hPMu=!pezGg;a zcuPrryK4{j#vY8WojNIR7eMQ^(OeIoKfvp)=6ua=nve=z@V9G>veo_;e!(v-N@qyT zq!v^+JWrJq@ExTv;P_Da@$MvavtV|6*8Lo4vYN4|oD3TbZNi(n%LIfSaTioYwM&nq zul(}d&a!+qR`OEW?#IS|WGKD7t9D4m36?u;mlb(0E$IMis$pw%QKRmu%ZtL?y1iL2 zqm})j?bAMHdK~YCK47GxT0|OoFgIA~xV*B9-=x9oCWZ;LdtQ5e?O8=PTf)!ljlwxA zYn<8=pk-`TO_UqvsO#9jS^fx9n3i#s_^&dgBd5yeYl)rRg^qK#Fu$r#iM7{JMbG2! zy!sV|fG2O&V)U_SAUR>XGa#iVyJPS|0p+;Olq}`gG&u3-y7_f7uBA)SKJ+@=6r!Mx zB?~HT*;#V;bBJBKR2Ri+&~LhLpRXgSPFhE+Uxsf~Ri$du_#JdGC3R=}rz(v_ynN2~ zJ(Y~Edd<#j2Ny1E`SrWAR`+O5W&+|R1}R(o`Zx{^FNn20EltN7rydhi?g@GlGSK`qCss8An zo10q6>IJj{>Ki`6nKgPRn(vVMHQ{5=D27IZ9$sZi==vX^M84ph6y!x50q9?#NS~6- z#u60qks3cVSfSc3;FptbO|Tm{Y3nbWP|epn~13$bSZapJDe zpx3kd==FB15sm@DdJmV%yI-C$t$9`J?hgNyB;Dcf)-(#;0ZMXQ9>Kb?GC1E@D&*Pk zkM9lVl4B3!k1rnuQ4%Sa-KIB|_rmdqZRPjJa5YgR9TbFjm)poTRp^WLpHnkHCNvNw znPjmZ+{j$@p{{yGG68YBg~Qs~Nkeq9Wn5zp8J|cogPs_e7GlpdywDUYuC=4OJ^Pto z%?#hed@0=Yx^;bAX2!?n8FjG;ydYnx%LMy7dU|u_^blmxr{u?i%l%xiCMqn4%bN=x z%Pv9gHTzT$x$y~C0B0j+3AtWdNjrXHqE^^!S6?*a@ zHDdpA;fUIsGwf?-HQ=kS0RzRix0z4``8)$_sq z1ViON?$hr@?zCwH7=E`GYMi%KmnQ{ee_k?*^&&A4OA6s9s#8tx)p)rIEk-tc>qp*= z$gBFH%WaG$=XKu%`nvJcF_o(~TonZ|U!pLMISID(#6leJ^abE75R4lpBdThTp=Uu% zaJvqb@S&2Wx_qqZe`FUz3#-nel)nuv4Iby-JoDt`r!WJueknp&EQvWMN+aG7o*;Q5 zRI!`e>sd{L6+W&R6~;fIrnf99G=dgAo_Jk*=v{0#I%A-fawrz}&Fb{~WCTfs@OfwZ zLKW_}0@`uFJ5?Kz13_6o_FUDZOSVn}keA1Rt`l6k$?#8M_6)xhC2n{%f@WaBKUCmBODsz!>s*-wmA@0Jxq0)c3n|HwFlq%U3v zIT8hz6)~4dl1-d;D{gnTG}u0Mo`i5^&s=m`7UWQVJvBX#>wxH|u@KIpJnr({xT|lD zcULodcKI3OGJG9Q43e(A%nGt9CIapa&MN5C=l_z_<02B>oG9nl20Svu(m6z(R=!IM zJ{FAZrVPQr3tx_hh?1`1Q9H9sZk!N};tNV**#*w88x(nGZXSt=L^r!#sJ2VbT6Ib= zokjircld0OdAwItX|C~+-Bt!<*W^ax#dEmB$wV_DWH=1)0|l>0-rl_8_@;K~>~ij! zwY<5vnw94ep}U7}j4KvwIX#pq^+>8Tlx=r^#iQ@cyX%FnuTE?3hq?V)G+4+ekvlhi z-co4VSmkN3bvzxgkNpiw2QhC$n7m669B?h~#(ipHVMjr*Y-fNkI)OHK*v*5+q=U=7 zN~!MdLA&-WIs{R6f~c7M07JYV{;*gB+1Vy=wremGQr8(oSc)@!VsiYLo~`KmUMD7w^SoEa%&dB_~VJf zK%OWE=fpubxla~Z9gcz`QyX~&$ zHfJ?mrcI{Er@xwd_$IiAW|}Wo3fEM{ zY_krhp%}M>)fqB1UofRfHc+V@UMs_?t$j zyd>c|3bBdOrTf8!>+jXR)0nkv=2V{o{mW-tpz1yTHEm_1kq6mjnN*;blVOeIH{4Wj z)E<3ctjRo|Dts^5*ap$|NaN-fAtg<(;=*K3t*R;Do#{?~kJNoDEs@B%xI(w`!Qe6* zT=uhax_G-!->t&)@^55X3O8alYGIH;J1I|O?5j82%E_}spfybJ(F4-Warxnh92PZ7 z0>pB(S{H{eD0K4oJ$I(acolju;c%A!x+%tYOUL#SQ@(#4(dLP&nc=dZ{CUlz465BvK$>r63PjKw3FOA{{Ib9X|eo#Q%l1wQkWV~txEF8V zl;D^kD4hfaCQMP@+yAhgYjtx$`QJQi#vay#vkLuHZAgaawdbBIvQFcRRv zXabQ6@ZY!DZ$~9$bfpwVkc|9p!=asgJ~3M5kD0rYdKu>$>a^?YWhJJD=Y>&Li}>ff z5ujTLdl>an^J05WC_oDpJdKs$eMZR6vMYllEK(QEuxK!JP}9`dUXcgY_iqX^a6IK)4;4CN zbKqxQ%Fv1Tp{F$xD$l8Mtt#P!uP6qHPexy1^PCkb>K+((2kN=NGIU@A-F&`3G`~;= zY8PI-+&VR_J$EE`lZws4>i3>Opuy(>ykc9=DPYn#ncx<|~oxes|k$ z3g~+FV37W{xq)Sio4ok1+u3xPnxVUcfBUYVe5nk5bC62m^01eJOnK9)g{~5tA`VFF z3=}wrX)HC1^x!dKZyn;6gF@Cc^}Vp10Vg;Ns;boOCV@^ft~jFs&Nk7}zxB;>G*%Ei z_aatV;K*+gnb1=i>k6XH=(7cqzpHIen^Mcf=cg5Y7V9rtNUXr)i46GzVQ*4~;%umK zw0W}K6*hzU1^LjmDJJW0t|N*->RAtzp}G=E=()PRa)BT*607i5J+?H&=LgpCh6AfW z?Fo5ySRTG1d<^;6KV;xPGU&`lL4WrqiBT%ctH501#|s$+Wd7C_M>XN|XV-f+Yu=Ye zkm`!NVx71Z!)o2vbtd!n+7x$G+yel!r=S-^cAPTIg=A2$tup?#Tgg6SY)i#5a*A?Z zL=4nyzhzTm^|G`vxaU3~g93M3?nb1SSOVu;Wpx-mm$7Q$5{_Ry2RWomcfs z8-@BAydQb)IhEy&0ikA?>3AFNdqcT}Q_dRqFJP-8dJI;g)BZ3~-8&yTX~>hG5tEle z)6|b+o+WERm<*ry2%NZYH!N$-^EFDCJaFf9CF2h8{;kk|A?QpEgUbywZkD*jY|Lp? zAPuj*>b9KvA+r{Frk`!NGKvXGW3-pY8-_V|6=7el?2FqmCGC$uH)j#C<_L$#6g?fY z7mc%4%C`GPotJCCy^{)=o1t%~z2O$I$nN96<81?aQOCnOX}Ziex?CNNTU#6ojF`LM zXve8pp&X;!hWh8QlCWEGp|J_M?E_+gsx)r%aE@jBql;hH)g<+shW}jTVnN>Lu}4R; zCmPNzWnA5q1E4t&rOVO&PO}WHpHWrB0cR#>LiN^rEf%bQxWMb^17tthlZyK#X#)s5kObpp zG(&xYyUdWMrOBAlESoGq~Tj2zWgXGUALn_M;YfV>&q!qOQ2Npuu?p4cR5! z&C{t+FQudfdnvLQGX6o+?JmSyP&qw`S)$`)n27YpM;qOiNGvvoi(EjO-3h9Cw6Q06 zJ+E~^^i!$B(C`KGW1h=zG@r=R-i*DBAk9rHmKKLE*{*6sey}0+itK>56>^Oh zb`=cZltclqTXuDko)iYzMgyO|NDot(9^DHg`<^&KoK#r;Q-xYpxK8 z;h0}77s0(gi+@w2A0RuKUTBg1zn^zd2w`<`zwjzdw4>#|zFAv~B+yoU3!YrLs7S=t zPBizMpCN-PpF{}ue_sx2QlJAhe-AYKNYb{j$Ah8^o{Cjk%!w?0Y>VWIO-!6zM0%~u zdLPV;TIv;ho?^k69?YN3*1CR%Kl8`>!-JxdS$hceY^jDMqr1+D?{-*|zdKC$BQC8G zah_?4@8u814&&#k)Q*RLtYFk8U*P@-e72nsNKyFOSkM3c)5RH_=Mr&#+}_%5Cvb4* zKqJ$mVuj^8{>j3Og^(}OZi}Ua}SJeXw+8?X&^piZt zlqr1z>0i0)XLPUbz=xz{sMJMM-rl#U7fEzAz(k49Uz`V#hRwEW-BLNcXN}U1YqDs4 zf)nB&Q?YY{hL>NKaUt9L3TdvfpD11BY(z&xiO=?m@7o*t!S1~dOksZH>|rA-QhY`y zTjw>a#FfzbvPtVfueOhIquFVLLfSELDr%`<>C8!V)&SFpflW-z{`q%5i;(T9kzF`@ zHfmI)tN%cFO_>B(fsMHvF~mOPSK7#VMwpyDf8|6LiSA@2i+!-AOs-7+^Y}#L?7YR{ zG9zEx(5cIUlpMGV^nVm*o1WdM3a3B=r2X2J6QWfRx)~OA$Z(`_Nkj^b3qZu#zvsNB zw+2v1P`+Ki*Skc4L7{0ns;`eF=#1FAK|EL4F(=8g-G53rKIFNbMNx5`Y=P1O*7^xA z2}~`>Xkn)Qp`_iB<5D9C$NFOdHdHg*B=~vjpv1glJ_u}+K zB5%;-DpBhGVecXEj+Gdr&J9%;9TVS+if0wdZoMC2zOuY$>n!LeEBB(Fr;` zv2%pFG39J4IrhF9%idJSqA9RK(ZeAs`-hHQC-t}aJG-@w(dJU3Nr%Rrzv~2rYFuL` z(UjcrwU_hDdAou6gK*WF(E4G+4rI{uGPfI`+=tK2zo08-F85$^Y~$JPUcX>jl^8m{{{xmX{VP(!IO(ON?)bi_81WoQ{gG zB?v#OURFyZ{p?<&6F1)hvXeO~6j`4*AFZL_@l|Pcl8eB&?(HG#EIqB^5I8+sHc|imU){tBHuOcxSKpQ> zNepcAj8|^qtU){1zd%nUi*E8o2D{;Y`p7ktZt2+Ywm&E{;$!>edY2}fV&W%@>c8kg z;f|S0?3Q1Z4u!o5xG7tyw)Y?euT!C8tjmsK47C#1e2H-?<9%KcnEux4TYm?4$HU&7 zcR32YMZ-#J$&d#j3o|tpKSTbg{6}`egY?RqgAg~`I9|;k#~xbg2_+zK0_ZWA+8=@V zN3JgUNwi(jp`I^3bos2ATPj6w$(D|@3XV)W=a9G&k5}?dv*;av?s<}IvQoD(^OF^% zfsnBfzRWHV+M!z=(Q%&KyIddSR;*Rn%c*k`cp-GB!Fsl#`0%YqikWF!Pqq6MEfI@@ z+;W!c|KWVNnPDHn_&j?31rw_+{9x7gRewZq&+QJ*l79)ahfe_GosT3Fyl_YMT`X4b zue{_ZU(2x4e$Fk+@U!v#`>dxKVIDn#bAxwYItkJ2qV4NYL)$e?sS88h%0B`fB_#7O zVVYOT0hL^{0$#}nY~~JPoPMwAs;hjfFa#s`D{RB zqQnw!pxk>h(kowRyM33r2)Rb)`+18PIh{my&S zp(hOCJSoS)7!qUP()*}o2t9mzg>^R&=zoZlZJwNwOL`%6Ubq;Ca6@H)e!H zi{IjKOJxhpaN0f^j)nJLBgAe@?XH`%KL76=g7mvN{`L-wrjFlww>YqmVOtCrU-dNzsbfvV~-zQe0I0 zhSIUVr==eK-Q!b*P81%!Zio;lD%r?D`-OKXyFiWV_og@f zD`mHOH>i@gt#6=$i>$Uz-#)zCEm{x$Jmsr>Q;Ym&$A`y5ApP|$2R&P8iiN^rCIoxf zu;cUQUvaZ4(!17Zcw#Yq(PrI(L+T?oxdR&?_1Nz!belr-9P z`e?Iv`>5>mBLaoH4Xw)N#Oj|y*5ZS1_K)4KYNgv&Pzcw6^!wP+33zon%UN90Hd(^z zgV7rYy>q;K6{~cHs_*M7*hm`u4+kE;2pMhO^mKCIcG=lEu0gG>`q(`X(_rx$-J4gH zN8~Ke`nZ;yIO8Xxii!Kn@;}}+PN;ziz*$G_6~Q+nt^uw4NVY$FQ9~Xon|*v0qd}E1 z2|SCpg9MrLJS;VHi3Y9%q6dd|1wC@PR3QIfF0t`VW@ock-7`TAZU6&p(mZJhx7PtC zsIdkFl>RPu@O@n$xA$E`Q}pST?b!2am%V#t=XYo1R1!Wksk_FvbDMPF%?0~v__fDe za%B#NY!T~o!<1smj;XL-z8>-OnshY^+fZ$$eFac^QK8&hP}!5c>6Sv9g-!qCqC zNN6wNXlV0+$!?0{l@QVzrLl|B1GaS$18S8e&(h29+ciW+SPnjMc9aZA9t;G zVqfSGeKzwx?n#s9ub)yw?=F5MdDs9hFoM4={{5YXd-l!C!g9|R9!vN7!3k3WHHl(V zRKR}8RB2Wu`pJh}6hQBYxe~PhyKG1Y)Z9;acz_Q9?!v1f6UNVxy~tn~U6h&746oV8 zj$Jm2^p9(q@W!N7<^3KKF@sss3RVR=o{$U~dl1#95iLwx+00|_FBCF08p|v!7A>di zFMO-TJ7aTZimCf35_P!V&gVUfWcS@2hKvL5zR>b*4bH#Sy*uG^D%JUAxls7lqEjfh z_RYMG@cT?+UX;V?=Xf2!8r$!JdxrQQS*ITc4e2?PsBY}}+JirB^E8mN^bOB9tQbl& zt6{t>F=|elIcGN{j#538=puVJxf}oa`X$D2)GqEv1}F4EDGd4Nlc9p+hsPYVLidf! zQR?)MKX~MTr16Z5t!MAGy8O#vVx~Uv;VMUX<6`ALL(kY>$Uv>5k?oKyIPnuh>SS2a z65+OIv{{3P!K@j#E9uDAY+^AHQ4Q*dyGaTlxOEJQz&N_yShl2sAPLq@nY}P2`0beq z)-0>_a2oB6L9svXX0^)1!z*g7i&tF);bk|#69&jdCbyJ z-Cx2jbihUpqop~R*-w%pzk7{eo$7$#ctwwO(-4TvIN1WKzD^Y>DlGa3VqEr%WAHr? z47&WLtmfWTF$qio{5J0<3C&+U4U>%C|3@a^tBN1#Jq;S{bh-GCOyl||;-NX;HTJs1 zmm2?u_+}6J?rK;c3HaR$VZL};F4L*aY!_|pJQ}z-UrVAy1)_s0D^v22elR~j=%Mc! z*HNQ5?(QvXj7jV}ca7x|EOd}__M2z6*><0kde1( zJ8>IZhcX&zQp@I@c=ZFGVRZjvr`Ds}+WzWp1t% z7`X`A@KdqiEN$<$32v*I4+UK>D2GZ0ZcS8`G9!^qs%q=g}C1e^lP8o_T+X0 z4FDiSi0}HFw?c6q4O$Pl9?(pkMGCVQsy!pz@pg!MVK{h!dRp&WWg}UQIvBnBDJtAM z4lS4wRR?ai-O$yXWZ7d{2}QcOYrB_JmQ!PbO{oJGmO})7neLu@t~wWIOB?rAcx_Xn zXeeX+B{@K#hlYrZrB6N0wh?&qa;v}ZFULLxp^~BH?aF^tL#3%EqkBb7l7Ge-Ct2p@ z)qt_Kvk*x3xYS5E>p+W9RZRl|thIRzyb1;y5+tSyqHtO72}~3i*YCK>XFAQ{D45pa%c2_xPDlHDVDt9f$p*fv7hCw!(J5rKo+gmi&BoC4KC?$*Uy6`ERT z%GEM}l{Gv=&A*V{qt5`@2eOXyPu$71p^gg)Di!YYWamHgQ#ARYOuoH;jM|CgvxZN0 zwFzGcNE7XFj;XrTTEG2MRV0vWg|pbZFuF$HPobCx_sn`GyT>};3O*^|pB3>Ow^#rr z6d(R=AMG?v3eWEq#k8oOTKc;LB@={k!l4@UdR~B(agOC2?Y@{LYTC*Pb0rhOcK_A& z?B|qFBqVu?h=ZPo{zqmI>T9&f+zb4%bp9J>8`zAq$qrlEM#2LG%htd|hBXg=Gy*+m zzwe_Q7Wfqm=k)%i#U}bdwI=omm3v>oy@#x-)`{=W@=b^#akCX*aH4+o+dUcatll4o zVn=6=)xRy@=Wv#;=~bFFVEuKeVIwbwYZ#OGQB$ia*r5{RvzjdN=oy*vy~KF>(FR(p zwgo9CBuQN&P0njUsxB2F-f=UZ^AjVQCg}5bzx|9Eyx4?05!0clm??(rE_qjp?ttHP zWxN;8^QoBEdU7scvD+v-t_+&s52LKwF=iSc_d^q+9N z_rpLDxvv+hqVqEgzSx$m&{W zzSlYDb3X4+NATmkhw@BoUpEn_WMH2KE2vQ;A@40_>nZUN6BDoW;p^r&*+B>Qm+hrl zaaoE6)c3t-Sxds@S=IqeR_1$*tz(guCkxIV7JZWvekO47|0JUFwyCZE z-W9B>>W63z7Foe`Zg-9%4o`18kJ1yJb7`?U`@Oum69OZ`D6Bt^fdtR^UBKF+9v7wp zh=~Ttre#CxhHodPgpt=S|C}CPI=AYe8&f@50FVSF)+;4lENNuBLN(4sTk^!F)ne#O z`yE9KYYe}tVNJNGe+eI{^m<2IA15(pAPSSRZh7Tc;qLT569DqXyx?D*?Riaa`ew*@FIj?vTnlu#bI+|52 zW_cVs)!B@=eU1}QaiA?iL!`vsS1gNys+JqCS;_OfEX&$raHI2k+`_fi-OM8o5f@OJA8`i)h>kWaAtAFl!i zngkV*fgtf(J#R9{o@l=)^4A`Z!saV3I-g_4E)Et7|G}ANO+t9vX48(<;a`R_rK`>? zN}l(BZ<2@WN^K;hj%qdW9%a!u_;d*%bTh%hJ|`#C=2q!TgkX)!U%QMb)3<^^9`EV1 zA%!8B1TMC8Ww$`DW9o=!%FWhY2|fAZRb9^zR^_n!Grd^&fDGx@PD!CVbsmkTP3% z8h}>c=82*Ovi`!{Wp>MoAWr<2U!2M=3M;SK&#ds+GB!tPb|8~Zk==l=P)wcT^V>g4 z5AkLn0LD1G4JB%4ziXpSD;EMtId<4SC+9o-2Vp{Vm$-qm@w%VTx8>EvuA9UVwtr9+ zeZJ31_Ll{)#x0oZp7aG>G%w;er@+i<^X(XS;rEwwqwJJ4KgidZ*jaCVl^lrE-(R-ZXq@#77$C5;KQ$#vX$(W3?9_x zJ#5cuzpmfKy$RnU2hr-KueEl1d4-zZ*iA@(O0*fg=Qn0C^V?zJ-Bo9u!i)hR))Z_$8;E z9EC#?kMXhxfXi_?oEZBfG^@z2oW7vBIASjZS^y9%>mphOX*SE1OkiViuQSe^g#3sey(ke4>AB*e)7 zP4Hn25et#frFRJLP2MdvBw;dbqIVJ!*!Okh9JT!Q$yC(_N)y;f)aU6XoceOq~2>vw6OEs ztZGx2H2q4a;TX2zC&~AszZ69MIllkAV4El*O5!$Hi9LkDS&rjLDuJX@an-vC;a=m7(T@2`SecK`}3-vLOWfz z7Y1JpkiVKT^S$un|K#xIz~)vdsQhUVmc@v_3#k zgBuUSlJ{wTeuU0l$O>M?cXXjBFPOY!_dsIOb*j%ETrww%k%TY{*;fGuLOgxk7DITOb@0aEOSL@(K7Ze zz~^mSfpY$Y_dDf8*obGdi?kEEytHV=s0%6=!dgEkzJl^wi|TO?Yc;y)6^YJ$+<{d> zONrrt=kb4qyXp%PHUEMY2iG6K4#MwO3)?p%om%5!kCR-#ip9?}2*a^l=hn@*q@o~_ zE`ozHkY@g(SCPGo6&PbA?&;@HzW2_2FHFYH@A}@m9NoiXGt_N%PKE19_{_X|p1!;@gc=T%g8yuPw#dKL^V8aBka9yA)-tWT+qJ zi{%Vh*tPvxC1lPDXQG>S%NFtXY5LoY_0*p+CICkZ4;u@JO_Uw`XA>gCsIt88HoMd0N8IX zP5T=h&x1<967tz_(#Zbx5_3aM#SpD%0+4kqcp2u08p8MECVrVioceN~Af6_xK}5FM zURiE=kP`3aW>XqLzr1i!l)_f0uLXjJ#EV-#e(vf_KRB=X8o9Ck)+mg`2&HJ4(*Fs{ zdQ{ms!3l}Ac>9`RX{&G7;qlT_5`hRO@`p)7f}~1CA8^mA4mSP!+b7vl$vFBe!iBVeMYc)$8 z`F&4c{m13>!0>ae=$v=f=ow)Z+KIsMO!XEp|5>6W-On{YMVFpW2$x z;k|Oquq%5rn@5_(ZGz~3A(-go$z3nw{Y{PFyvr3OP#e8>Oei&Ii|SOk-K7Le5Bh&! z!i8T*U)|bv@_mKGlKn7ApFVCb2cxiC=2jN=!PHDN%!r#~Eps_DI0C!p0to;upmk@` ztO_6l$9ISr&Nr|GG83=@Sbv*Qic7gBS^UD$QMJe@>Bk+iXZ2oqD?aPKhn*{Sf=VABFoLgrEwY(GabXecY`+1{`T6ws5i3TeRX=%G(T)>0`Sk z$@9=&)7!{)!a~$Notr8=&l-#flKA^psLsl6ovJgjV%NMX;?U`Dl@G)fcHwR%6At`$ zQJ!F_v}ltn2BC>r!Du8dz1MCk`;(I zUOO!jJ!IDq9pqK`+R0M>S%^&5j;6&%n3 z^b?ZTlZTbi9y3>)C8>~Dd|6Z}iHV54Q0j137b z?iboZDFB^{66RKGrYxtDwRI3y>A9Ky{}H9HBGD2ULel90)wQa^2X$J|wGB zlur?%`%7Cl!>d2XrK5H3nfnxHFk~B`1~>ESYvVNj9@=X52a95RSM>%H!vRFlHE$4r zEr@nC-o$K*^*yrKj-f7pyaGlR!;a@uyAshXzBuRmwBI`L2CoML7a!(TB%sb4Lt3x;C!CnAt#htpF>K8r?>go(O*YAb(C{r(t}1P2%7Uv9@WsO(Q2z8dm%q{zk7 zQ&aq)$q)YaWG@*s zP%dOzsp+V1f()1b9y53Vt@_AGj(fe9C5@MTjo*Xrq@Y z)i`-k>~8-+>-B`<`?@Kor3j^bHG0Y`5a1#MPNpWHTTd6Aqo3N&e## zxpQMH*QUKTOAKKxDD2(sUnW^!IKdE(;J6<>a)ST|N_)SlS zFIO6WP5{l>!vG<}DC5uj8ytqFUraKlAoEojlG>Y_0A7?*I=$$)KR`F+NDn8-)K7CS zh^GUa7>$3K59z!Go9l4t)lb^~J)IW@tClbF7EbC2UaEs94?K9r$vE~22hN5Qode=Vd2||$f%OfvU_X{(I)x8rT<-jh!55ExU4Vaxf6X!A=Z2D>%``<0=g;3t7FVfPZUUNbnIjk8H_b!O<7)gF>7Vjb zGTVIL>W@iz1-&+{-vr_?p214r5}xELO2jpt+qF0?hlrqKRORj~YNPrFB=1$=BZ z&|JOaE1!xZ|C^jg=hQK`E{}fiuqW!30INuPb>TGUzLJQ~uQPts43TE@1IFtb7Npu| z%xM}a%3>(N)TGOg*`;vPmGXSi@#8YUSjH+L)_VB?cO3%qNxdv*eZf`v6TU)(AVn$CijVNEo^u4O@U)Vf!T~o*RkLc{FZ5@s7)*1GgNX zQJ~DKN-WUjToNw8({Yfb*~*w*V=&^ID|KhkWlf}$4@W*k5E3z&5dEZAVgU61U1|B7 z`Rl~N#t>dm9u1-MVGT0DE)CD%U%{EIUt%98^EZ-cFhHANUug&Hw|*-YdMF6&(vXD= z<`Q8Ue%4Jl<}p%a{HCfmC3bti<7NXc$(0N927blrnnabzX!%++EgU&OQ?E>~7gNNl zB$#_MirjKcM3&%$yE-Wo!V@Ild~={Ef~n7-UR8n%*7$i(>zHS{C&-IDQ;q5ip}+GL z`10Bp5pdVTO8v*{=VGtMWqr3h>7s7QCNOo-WDx*v7Ns&|Pk7sfdDfirOQP(adr5C( zHY=?XAO_T@%g{Av2wL)_0g`ZFciga16yp84$6f+7A|e)(E@zM^JGlY|`gX1QT&tRw z$E4^e0(B=&Z!0IS0Hu)F9#C;kr`X>ko}>rlnK>!7()T=)b338|Foxc4#Z>p!ZMF`H zjNt{o1-tHh*{g>G9>FBu`@pBWc^KUll6`yTTS2^5s0XD8XuV=6oiE?jd^0Xsc4w;7 z6svSlvED@<tOB%&6tbLpzkZ0)#;@P*fWf=_S6d_{6w(5I zMXMXPz;9=Gy~}lY;jGYF{5|h^O|JilMy1`1)uc(o9_?hu5hi3xn=c1}j3F`*?E%^C z=)xeIS-z>$>s>IKJIi2t^Lt-2%049^(v^NlA7~fy8_E(Qg8Q-|9sr1K_v4HH6s-D~ zQ>PDEujy)QmXj&j{H@&o$2;G$A$H_aC-s2MvEyaVv`}^Wq*V1S46CS^;J|uWo+xqi zACYj=<)v9j$*G`(>U7bIj@ks(@hQK!4bu2I4&46Ldo<5T;)=&^#5-!W{(G?9m@;Uq zb|GVFvzm&NYOhW0bTXM@RPL85Nl;^?Ufl?HvZb3yGdsx;F`vvX&SdA27ivy+Dpk{3 ze)bv-x>%`G9DjGS>44%4Hu#T7Y-OR4%iZ%ZFa$7Ly<0oxU4iNqNMbLI0G9t8wNr@F z-HDr#dD5VvGBQp!fc_&r!5819HH*Pd{^_<;51!b{czII3x;ik&=DCpgj#T25_LlUf zwTs*A06-l?Na&E)^Js17d*6_}tbez^Rhg}wl8ak8vGq@3vYsw}cDxbmxV{ZG(MI6K zkW%z4j7*-s@nIwn$ScVJ%9a=1b2gEB^e%8k)tR%Hdb8g0(v~PTK5kd(;mh|TTr3=| z0qMObzwj!^wdU_;yR2g^hW?KpJZ|)2XEa@ZH8-wy#}+hPrf8mUxHtiAJGyPXbD~z_ zudtX#*w&eIYaaxCB{UK1EO+3a)n(AAs#itav0Og^6B3;HrMwmE?)36H%(89;o{nqX zc2Bzl73zLytmz$&N(RLEoUZdmjS3_eJl@0-Hc6}kn$2gMjtFiE^vVnIQ#P(DT(9;d z<7+om+%~<}pGOwq(VN2BRG%Lfh1i8b*fX!JH@c%t5I-^QkwI_Rbf*fn6X{d9d9}V0RiR$Fa+yl+$Cu|+QEVERruaM+c zrE1(5XMVDG=WLT4S8+>DO9Hja@tT?8R3(%=z2~E!fl8QUHSaucLUuBX5V@Z@?}F7~ zCqRf$bgS9@NAz^`->DvE|0*v6fH8=j&Km&KRpg`cF!|znFOvP07BVBf^IV4_yL#fMe;`zZs79TeO=+WD3Y(m#t zZ(#NXg~w}nhQ$Y`$9Y}NbOD>WziI5cVY|W<-H2QU9D@>4MBinBqSJu>$#xIFp)?nU#inN=%(} zL5w(yHC)=L8HTgb-w*1?B@enrKOGoQ6%ob_D>?cw8x3g zyiIPQ5b)(2HS}s`Xg?q*9Tnd&JG&~F(vHxGJ*gFF4ug#BNOM%2adHgj%Uc>XeBTH@ z2ZM|AwvVby24=>}^-GM-!Y$66S0-S`x{YRg5Lx&(JLN=L+t|$Tt$5Z+^h%lvxR($Er*J?D~llmD9GzCA3Dwff}ow{OZ4%{_HC5ADV)5K|dc z3VlLPR_y))sjhSm0*ZGh$aUD0!D&*#QPm!5i{1%?9MCFf6woR*Qu}y(?n75P^QsR% z;Fdwxq1E3CJtXaRg9*rfs0-Pj-i8I|7qr5!jXEzKh}iEWly~v(075S&82TwWC?zFx zX$5Y)E)Fii3r$f)vQzywdj_e8mF+7%R~MRB9f{DJEP3tn-8>fjy`N&cK+LxuH*9iH zDEq)ZVpj`0-+3z%;m!5^#Q+x&`x)T@HrOhKWF$OBSk?qEqtMC85XIO{ds&Q0cLA7J4^=QZEhGTW-;UI5!u(6Mf ze`DiptH8%ApAJOZC7>vs;ujF*Jj;4kvFsvi%e5PDBCx5Fl`6z$$J4qNtN3D^>=gE` zQz+=+wESzVwl?u!ll9@8!;YrGuJlz*cqwRj-c*A7J3{KDwM1|Q0KDF#8BP$|xo7%-Fo|$u} zQ(dbZL@MbUuf}KZQ+0r54NI`gQTj-0 z@{C?OmqzK$zB9|S9JjEp7+vjRPyw}puxaFO$tzdAB^LC(`h+m+ z2-D*(om4}Nu|__wr5Fp*$3t*875ER5%knn``ASrsO#i}kfNO)lLBo%muqFxjYW^eo z=_0$?WUzvR8rHTnUXxUT8G0AqCf=*wt84vvJ1~qBiIGN%uPq|P&+CRUFAA>94!*Mk zMrO}00W5u&P4qM@dSnI@l~YY{lPv?y6^9TD0r+N+Ay)f56ziMev;laCn__4rSibae z6WUm{T32pgFjKd=x!zi^ZjS-B@83nMb3-%jVo!375_c$(9p;Ge7NrV$`PbJ)mOI9M zwufm7JwW`uTeOxlur(~Awl{#rd}Uff32=+ZV>kmF4C+Zq_P#R&f!xV>?BJ%x2=%{T zQydCSJk_F~OC9EJy8G(KT*5aTbJn3WK`w+blH^|>JrWQh)P_+qKriA9LDrl+E7@|b znBO$3S(PdGU7aFYC9jR=n_b>sI|-Ey54kv(%lqUA36Ae}_UXAx@{_m$u1EVbIocKD zUg^5k*8$F(Ub7b=!3X4vDtd3Tojiu{Y!Y)guW8Ndl??hI{_t}4wNB4PJ7l&Ag^k;` z1N@Ui-k&Gjw^RelbM~unx8@6m{mhV5pP%8=J}gh$uiwO{rMcMU+Qj#WJBR4(klyNA6?i?z|Um)1TTFq-)FCalpum zKfl$FSxaM)A0(Aifj`dXXg?T~k+@7=6YzCO*7z8C4phizLL!9yn zjR1j2z4HxkdlQdWUTs@AqIH%Wv_ia2wojP592^~X_zhR*J|;DQz!I$oN0Szeriu~v z`p+A`PmZxC)zK9Q@XnLm6oqnivA`O9CQ$Vo)p_d#lRBu_6zZsUt6f}Ti)c@Z^yvei z|0MCfD<&J_v)09Url4#%Ek5SEp%aOGH#4*FzVY~-I)y;x$H~6RpvF(5c7mD%{uQIF zrF#}mPy`&W^kahi7! z`Y4@K4%_kT%l6osdrTtB=4A@h79==#;3tFL$C-?+5P=V$w9VLbkjxAF%xCE_cC{qU zO!|7Kv_0nhF=6SMc~yV@sx1=mRgtH4s*3xE^D;dyN0?i*epu|Id2N!t(qjkVl7#k+ zs-W1SgA;i}&1D_M)`ijSph#A)2$#ilkY4wd&kQuV&i1KNThw3f#? zg60U?d+&}Bspkjj)AbH1jjjX=eg-Bb{ymM~zyAezChAYDS;At2oJw)mYfPUt5klf^ zb9nc{h4H7MT#tZd;mi9<#UJVMd&1TK>HY5-zOs&yI&i!h&=Y|VNHe}@YG zZgNq^m8$su;OU#*k6dCeZja=h8vS9tW3M2ffdHkiM-FkjY3ZVu*s(OAz(oA~*R9v@ zve`XPVF9=dtds`QCz0L?0<|Oz63;`6cIV9OX$ve?DAJFE8twpyQ@$iw|7rCvx->oY zIQA;>>-djI#s40FM&i;bd0;}9ko%6PMC=z25FboM*e7{8(62UT^(wEhJKCYVl*;utGy} z(J<(}!QX~9vKJ#Eng|?{t0+Jmz|_u)aZV$B*JuF}A)Q~4$BJ6Sg8pqiL9zITpi^n? z-Bk;i&dQVecfKql^Tctm*53=&wx z&TCa}+JOrYi3-T!)27yI<$JVEtH#og5||T~0+4~2>vi`~dd+LbDj!0Sg>3w3v2)8y zbw3|2{NN~eldLEpFc%cxfy-Fk!giKWhfSLQJBEDKx(fdxT9uxbUl?ETYUDM$Bq9Ma z@#s#!R9Iuntqz~&yaQc$&I!Mb=q1mk7H!_kYK`l-X@QJtqRYrzil0;9rW98<6694J1E#(;c+tM9Y9-@}DU$k{x)LkA-8 zlpfUrT9ddPhMplHhpG-bAFn>qw>KT6RY+^_yxWqoWhWjQ$HqB!fXuKHQANqxO9IA1 z0aqNUabJ17$;Te>G^x@0HklGUcc(DX=^$mwPV%~`)Q!wNnPu&$59XGQ)5*N1Cl?ki z@^_}-#HndG4RRIFw$I+f69g#8G0Xy|Txhw+#9F9|w6FQ0AZWtR)#q*tqT z;Lc@_?Z1M?wZG&Y6h$pB=n8?`d#ZoQKl?_2p^~P`4Bcqmgobdd6IgkpxGqdezj=IB zR}UajimW_H2+K!^74mj2+eQc{dVm& zU@WHsM*V9gdKJWSfJRz2^>A3cO4iOf_NTu;?`9KMLHsa(`3>trw#x z(K;zkkq5wK^{?FR6b&xlqnIGa{UThyJj>=OA02&zU^NR11Y^!GRd**aDJhYe5(Ng6D^|jp*X{7zv9mS{ zWJ`187A@c0d6K!xwzf~01Em|CCCP`Dd!F#z4uKsobj`7>#9Cn|a*H)$aU7vZQTNj% zsQ$5Nl&b)p49gh-h1zAGhkK^AD@C9lo?ZJmk6}tSxFz>V!`i{6Kfv-zSZ(ztGP2pz zd$lRX?TizC@{FX{S{7!R>tuTATWFV?Pl!)TQhgs=OClQQd@M9=G}p5LH^L4ksvK~WEUy{>M1u3WDs;i0xMH8rpd4fkom+~#|J~&$LX#0Ij9;?y{ z`f7+aUoLQ~od|)*T76N53T-af{UUe^1{38+X?oosEUN;d`+Ek=Y&(*VX$~%b z3Rf|!whaDg85gzA<%`4hCZu$4)CE*$rxxyL`D$sQ_!yun@Piyg{99qt)YrubWBs-O zueP?2$p{l%efiC=#$bA_HjLkwBOf+7P+Pnjm9}al6K&SQ(7_S7x>3`5DO3aJx_ zkK+6IwCl^!!hb{q##m_gYp9FfLuGP3DpEjAEj-nM6W;f#-^}cexY{gPn#!*kVw}(AS5}Zyuwz>Pl zNa_Wp=7hve^r`VGxxa$0`JCxmi3Rh1v)6G~V7i5z-0niKEFj18Rxx|Ggrp(N+(JDN zUVM0kKXco$tAccOSFJH2d9(L&`8!%NDY6{(Z=*>w8JD_abov;40rDS+X!uClcT}); zIIZI;1cWuD;r^dONfmCT)W$Yqc>P1qF)t6(L2roQS{);tsqQAn-N8sQ=BaJ@ad`+P znOaR|X=3UkI*6v~qaR~y@ciuzy!B4{yT8|+MVOen_qZCr40%qtP!mv+?XAzAjEJ*?SJT3j{Z*ooTEF@Yd1cjn0K9AKT z(C7i*Q27U4-R4)B_1fLkTu7ooQOAH0wlJBLnx)XccG>JFV}yiIs~B^&$>l!z7HY8C z8h89>=9Y!pSkB8mnQC=|7=&)KsKvYvcsm{@{EmzAKKFf=i57I`buM!X49Iqt>f)C! z;H$M*TYrqNY)?@Hio%SU&5ih<$xg*tBHv%MSp|f&QX$UtOM~<=bc=*WyVWhdsyk4+ zHGv=e;g6xpf}{6{@GI&*&v9v371YH7MoqAMH2RhV|8E43TKZ@16fXaaZqz}cvCl+o zY%Nx)k$2ONCBfknxKcyml?0|^HitfISc2ZC7BL$0{ySHt&4u9CK~LjBmKy=PwILmK zqvm&ft(nq%U#+YNfZkU&_HjDTh?>6=agnl_6st4f%Qm<@8oaeuOq}7o2RT>!@ZkT5 z#_|dw!PZp)23JV23)YK<&ge6%v!i3D6uf;PBUY_QC}vw!Fg$fPZ2ruBFt-ErW3n+l zMozjXnPjz>k8caGVFimnWg89lHi*1pIL;`%O!Zg^yq=cHE#IyDqXIexdPDkTa z=9xYbM!(z4gw59fh~%CpvAbBct$L;)FE3D6gztgOJL_7$=0gGf&US9x_hqT81Y2`j zQyMkz-CgpxR;mh!ia7%uS5c%?9>g+3C`~G$t!-@H*XW(NUNsWB4tUiByT|dH^Sps8R zTe^n|KE2{BU>IBZT4^<_{lMaWlc@5R09{OoIyZ~rzskM$x>U}vyn-9~i<*vbJAWEeHZ`p(u8pp=@olK_Au(~! zwYQ6)0%pn@J0d=BK>xuBV&iB?|B1+F`dM!jC-rak)~mlx^cGLIIci9 z#?1&Q9BYNRQ8I9NllUDV=giKgCVf@#&%I%X4ZcYI()mHJBiVMp zJM0>Y>)#;NKhy!~vti$PJ1Q(nicqJghZhPYWwK0D=XyH})q6KLdV;uxjT635cfbIg zk@Ys;$3K`cA>9N7I0u)CW|=fg667zQ2!fN~XH?1qv4Kt=jNd^p)_t8iwH$8=jJmo_ z#31#)3!<7zid`7Z-G1`LXclOL+G5>#Aw}B$1vKoxlcl*&uSUuDZURa$8Nm|Y3Z?Fxmueh*@?MHIh$-2B}_oo6#)bcg@d-ERWZAzb?_O(JN3 zr~9fBh1LEt(M{f`tTEw%K@ChpigN&^uWRYPXT`$2wLFuU3g=dP|7TmiZ+FsQGXmHq z=br3`H4S2WrkQiuUVU$TZ2T*Fo)0&mW~_v7Duen%9+@r6*mic-H0-{9^S_m8djF7f6ZL0!`{yfC!^1mY@6io{+U8_D?9H4GnIk#W;WJ^ViIafM5X&LBP$qZVxAA!2mXLu)e zvI)ft6V&~g$ia4EH%c!lwKc6r!P@t0iy#Flt9}q|X!Zt?AH!B2{r^>o8%z!w*9k;b z_`1@U1|3DDAyd=gj%kbS&)-SO%4TnrwyI?m2G?#L{_Db+y3fZ@Z{Yt%!Nn6yM4x&>hR z(v>hcd2@Ql7$WcqQ`{*FTX)|cLoSr$nMhj5_L zSK)%d=&kpkAl<#m4-CkN?|JWA(fIBCVH};L`q((|Lwx@@`Q`9#HuRH85l%q+y9=$= zo7f#;DTmtBp{r{Q2^4nUNwKP2uAlb)L(FeZ&upjd(|zlRe9MJh(Y_PyPa^uAKAMvG zM4T0g`biTZGgUO}>Q@IZm*gd$wGyzOwnoQ0Hoc;JbV)0u@C_g#2I;lq1bSn`i1rc$ z=!QOeekK=np7z6g=;8v_4I^{$MZ$A+uZs+B9fSUgEx@xeuUR%YGhizsxW{_~D{!fp ztv3rTqT^$J3(Y4hF*C>+SWQ1sH-YqmSR)2yH(2 zwdIv4lx6LD?3q+%9uIWVa&DG$23aq60Ji=GMO5!e%9bRYeOF0XCp#mZ=l>zO>igM? zBH&!1^#TT0vW1c@&f)zgg~4p22@Y&w+Fi^9x0DQ5wJiBwJ1wCQ?8asJZB0llHAqp9 zj0ul^?(ekr-aH$u-Cgcd?sAxzBOZj3D?V}V6rLq?>}_(Uj?Pb7UZy_zkVQmHzPi;B zNG)r!;AnQ7Yl>;uH}u-V!Dfg3_Kz4(7F7ZSF3)hPDlQ-YnA6yl$4nzC1S*jjdxoH_do>Agr_ zz}-fR8?C>+)rs_`g;HK+OhWcZc!eNaqN3qX70;ztV~~jU=TCD%Ue;^hqXlLA`G=lp zd1&x)(6|=`OpA(EsEr6&Spd1aN^l(Scds>0p7Cr=pLRur0P^~;P9>jJRK=ywUeLb{ z(?BSysQ!3prOtjvu(TFId&qu4peF6f3j@CAtwrJJPUb^&YVkAp*6$Vr0>w}lG~D?J zr)+?1Y;hM?ce_vr>~RfXd4)nBYKp|`OeAx2U4#p=sBVi<}RVV6wq^`e_1Ft z$|VouW3hevVW(IR)+Nzx{k_D#M^)REfO z(BFM+DVnV*sQ>%;e%!NVQwF}xZf1pgpf;%0srPJ(2YZwc9K6cy90~kt=a*nQPbzf>KOvZXhu6hUDmvLCy}nHwn67fQ z?>^njp`{fevr>g#T5^W=he$5s_BKqKnx}PoUd=YGpv0;w#Yjv{B^{)qiBf!}K#_HSB(q&Hv;mnY?-&c`*MoHpDb^4_7iE2!Soe?&O`|A->mRSWR1Zt@yv=*+8% zyBsjo0}}@I@n*uGz&bt)OBk?MP?@cPG|$(i;q5M|D)F}Kg^D%-Xrr#JXbFm^`}v=K zz&$^{X__72WHwFor<&c-jB2ATTql9%9HsPNe9s`Sq4?+YFO+-Nb6{lp(Mj!~mC6OD zEi6F<++k2_A5RQq%}C4Y%yaE9x;sihxtd8WAAMR}IuM>A&kL;87N zKBOa(veAXGe@QsIPA9W_gl*`UO(|pB4;JCPk^2||`k^LTVzJb^nU=>r(|J;fDP)c4 z_>NgbJ7#l~B#1p2RNj;Iw$3Z)mD?RHFtdp2>PQ)Ne&n!WaEGdyazkJm&3W6N7a5fb z_AXt~29=qbPq^|XYAqvatu#4tLZn&YM$IT~5o7i^LL-68z_1NKi3wnG(haA$k|s?5 zV1HIb)bCCP8;PcxD@&CBjH^WK*POTD`!mgH;>pi+ca)C_*`~FQ8U5_{sh!mf5CD|O#7lFoVTJFf{(7I4 zQR$qo-%~Dy4!-h4#@WrbQ33QN`<$=uAvNWRv{spnlwMY=Nz1hc66@>Dt<}3oh#DAi z@aU^eTqYx}1T&X}e8phV2|xyOk5mnr9wFt1%y@h|y5quEVd6ZfF>`+%7WH!`|LNkM zKB>K7yBeeM2$(44bI6fGHySvncOXDGSvW93ii+@?wA=eQig)c;;ez}{;j$`Rg~2S? z)eR;jK9TBLGHaJPG{EYlrtK_AceiGO_>u$nggeZsz6$o9%P0;ASZvZ54q8cc$;2;41z@;;Tc7}W4)F z>BXT;_}A^YLCj#U>_v1 zh8h!=^c;_v7VyG|POf-m{bZ4cdwd$PuL*)lF=2-swNdwf*gDTZw%-5!Q>%7Mty*o( z*4|sHilQiOZBkW~h)|n|RjW2dOHozSjGdaX_h_vUGqGwXM#TL5^Zh^mJvdL!!*kAk zpZk5iulMUZ)R}FTV?OEh2h$`R|3bP-p?5IiFrn%FHDY3kO>fYVjhnw2uq^h0xZS4t zTz3SGxZ1S>q!-ZO-@&~+XVMMhuP4qsfv}cPrxIWQ4AqTp)h`E1;~6tX@Ze0|syf~8 z(q^)?xAQ<}Ac_=>x3NGu!!k32F4eE;LfzZ?ox?U4D2uHhGh>@4Iu>S`FUlt2oKuMy z;bYjg{`|R3;bv$ej1PCP+mA;OU_=%8C9A#yFfnb5!~`B})h{EWUi`^Eu*%X`GCvpU z@sEYV#hV7R1p^MuFwwB&%eMZ%y+|9kjs9<)=sVFiVgSz@)M9>VVs;KQ|Q6yK%|5Un@6B_ zIieS~Tnod<(j#2rSn3v(7YPPwwm{S|I=wZs+YYIX-6AlZ|Ha04f?9#4q=pQk0e4;E z?NAu-(hLWW@p1KKRGd%&pV&+%X&B7T1Iy(KWd|h>Dabb-swl(tm?KLJq|FfWEJi}8 zMWmrm?b)ddomrxl$lp0@!d5VF6Algms9$pNC7rKK`dZztoZJi!N372ueM{-iYfb<5 z=|J7o!3E3vgqxrG?9|*k*!lWgDD72U+=sj7WX%rxrbnugd9A3?Mg;09e1C$r`vAI=EB`0?7Jq!=g`{@~2cST~N6V^1|BMeg->p+?jp-@FpM1km z4V5Bln-Mk=`6s7xlaUeeuJguiGuN(E!9ia>7PMSxO~IdssjZxg*RlJDy!A| zZvDwlwaLKA-k-QFf-#oW+i87a$VqlxTleFwB3(m|j{cy?-bjn=4f$!wlD`#&Vy%6B z(ktM_Z~L6e0toBA=;fzvO=0L^!Z3(May|e4lF7p+?&v#fe5;3dHko`u^XI@d7rL5+ zbl3T7I(gqO%iXF;IaL8lwoOwf$A?8AvmD;`$DIb{LyHR^a?6hm2?19n^2sc*>Oy$! z?kq*s{{0#5U%UH7R`(O$nrG@n2r{;zqTfDS^AtNm>0Nik^i&7rJkKap>@<5XdGn^C z*!_;@JS_c42m2GyYCf&}(Kb7(TCzZ>B5F;tU~i4SUi>M;FEwqRwastmo^PeoOKF7! z;b7Ro@bLv9PgT04LXcn`NE+oB4TS6vPW#|I;7<}g z<(^qM7o_T~d*%n&jtf^W%owWkN8J?zzoW#B?_J7_RKla4IMtKZ27Lv;Hc3iwu_wOHf-io z!Y}rYD4`{N_~Uon>*mMrE_7v^H$L!{i|y2B1(gf0-|sZjVmoB+ToibYYp=>D&ANnu zcrz2&Z2;6ZEQmTidRlV<%E%$XXi*u_^`O=43rB(_F)-Y3$63L!Qh=r^GF+ zc_=%cB^-}qNLF*bKM5$Q0?UGoHNJcGftBm`DpJX|Cu-rgEF8bE?HNgj5}Lr;p`q~K zPkA1tFTf)Cqe7_djM`uO)F165SNJ|>D9CM3#`{HyU** zgTq|e4MPb-!)Ee#hH4jfI-Kun6)GZhJOkDo&y&3E*EB`6{avuyytN852p+#UMLB_1 zj?_g(8-Hc=vnwzAhWE`MOo?r?J8Z>6J0}1OJ?ut=jk{f!H{*!YALeg3 zKOUxhR2^QV563?@3|f|rVipS1L}1qbIMVq;uQc@hN&erd3AQjL>&W$#1vRuAX{ zN-(5i3aTc%RCyig?FwQ3^0sT9c0JPu_A^${l{|&1E#N_Z!~8;KTY_Md4}>(*-Obs~ z_7~D{wpLRUP1*W8(W7utbxo+7<;zl#XNXu83dR^P+1X5UDR_R_xM_&|jd+$S629!+ z^7OZkS~ZV%c=!T}wlE+Xa&t#1%Wnqjl4DYD!*vJxr?0l|k*+=`-B)`e4X47+@*PcO z+kk_P>zlX{zfdQ3R{`MAS86NA_9KBKCc=W>nhyy~f@laG_>Zg{c!Id3R+HKQCZF+X z`$=G*nueLE-zLqv0PP!40me&|5)$oI?hSJ_d^zt1;7o-OslgC>nm0vg)>>%+Kk;st zQPjuQG^L|EVOEZ6!6_etyimU?L)5Hrz?fDs|FVGQdAr|u8bW)jD~4D5sp7KRgvb7Y z`E7OhhYy*i#(xY0-cp;?_4SgwTkvU2SH^r6MY<@W+QiT(3u~Jn9P+Mc%YF{}nupI_sCFjvi# zafphA2L1$IKADEgCq5x`sUi7xEYOLgBe4ko8rPu9)5G~EgBi}Aa6WGSQ0{8b+L7pL zk@1~sHisvTpNjMd^%e~cs1s6ZroIPu57xLfe}1G{aFwf&Pa0SzhJ;*bLanay$9n+e z@4XCvK_B6-+kUyJD#caQ8{WxStp>l@DtT!WctSrM=adK5j|g;~dW7BV{*Ua_xk#k1 zQLxruC=kDjF^3nKc)5BD=aVwsd5DwR)y;_9)ikjXWBhfeuPZ~WxmwCovtksFG`vpz zKF)C!wHFUtuIK1NCh>D?a$gGI4k8pRO}cFu-_jeY?(+zZXB1oYLezCd*eAbRd|?&b zRA&V;!20-a0zmM2)*gP|R{Eb%Zy@DXJ`>ag8w}bB<#eeW1Zh za{LlM1JsoWF1frx)Deljbi%@K&Hn>qm*bi@$|VTJ(cJM-nXBFHlAq4GX>(U)Wp^2V zeimVKB$$(;tm=A!^{C$EInoK#A3u{=Lagifu(S|x)aO6B6mPhwIBs}7F^#d>{c-fg zcI!a=jnOR{enn~{2iV`k?RE+x9Fxo6$!g;k%HdP#;3LHh%Hup@IBi#}Pg)%d=6W|L z(-iQuLbmKeU$}m_nrI;7-Tel4Tte@*_4BxH5}~`dv_6&hNPlq3co@9bP`_1Y@%}3L zs;Hei0Az$q(A30*e$0A4bwb*Y+NCuWW*T&}>Hn7NVYYsxp~p?ypU+zrO)h9t%-<~d z9j5o-Ve)(a-i};>77(Pa>FbFOwPojAZjSy?0-p-}-vOp19^jE{J=yPvY*b8M<>fZe zynz=ZKH_x{`P6MmlC%6r1yAX{1*5I*o4Vt^G)6fKZXol(+K@SPfP_&Q#RjdTT}c4v za-MGJSg^%0N5siC*83Uuk@4p{VvlT7nvF+6n;xf!nyj&_Hf&6KVrm|jl}BfiyW@%+ z=#MOxl?(a|>0;0Ry=Cd3EC?UC-|5b#p7dq2$lo8;{K?7{#@%>t-sZ;{3dO%8_$swo zzM#4MgvI+4wqC%E5tSuRuQ3qs)g&V8{&qa9%}z_4`Ed`6*iPsi_X;W^)b&5Igdjv0 zKWD(?OI+U9p8?!Ge3Erj;`;@W7Om;JibE-n4}0aEY3(u7;g5Size)1Ga_x~xvNKL{ zGOrggekA+(!PVX!k93&p_9a4Zcm?N~tMtUw3{qwdy*NE6I5LTox)k<#zguZ;+3;^I z)!x=X!1G3#CiV&M2oJtLwB+*+ei&3zfyjC>*1uoIc^W=QakDpWtKVz92sQ{Mb)X_# zuSbye)NyzzeWKTe{*Ds=Els{f+hTZ`Nu|{wCh_i)#A}~_5(?T(d5{Ol==Yn5W;(jS zQO=j2&bkQ+SCKHzODUq!Dv&dPe^mvapLose7GxiTr+C^t#j-tQIO>dEHEYc76RmuZ z;b^3}>?QXbJeoqc(F!DfveHmz_=oYFE{M$)&NY5775Ecgv_yhkAylL<#bVDFHmzUy zs4NQxTG#tG;&RD4HedPQUw$rx; z7*=QPpK14-X%L*Evqu-`yTl1`%T&vy>5dWk;ojNjN-NV@agcho_@c?QbqC7U18%vB z$1?8H>bJsBGVW2}Elv-1eZpy7%VCs>PVd;S6%}bHwn}yZk<+ zR0dbyd4DhvxPv@F&N`fdia?d@*QqBVCUxqD7eUt(s)$Z0rt2|ubV>2TB`+@0dft`f zXO{o>E{QO=FH}E8H`h^DHy=No!8G=m@eStV*&NMdsOU#b?O@trf!+2YQta#gLwBpKUl?C9;y+3J1uCO ze`=_ty^qLTXQu@h^zQdlW*MeO)vr=GRcR%7)h87W8>_lPIv zIUDENH>hJ7eexbHSUgi1yfPwv^Q*mZB0c51R4t~Di-0MW+H%{i`Xq7)a*xmUay_?O8I7=W68RjIFXzK5$|4YnZk{9*^_Od}|w+ zY@4dOB=}82`th2n6Hu><_s}<}V+nsfJfRRyVuEofQE1_=vkK?!|08qg%X!n#ViPR- zQ}p=@J*m+f(TDAL+w2{v!|K6&>a`Hj1smE6xkaqMG{Ch@@v-4f6HcU<7q*t1+Safn zFtSUhM1?tm!6R%ob3I<(>DAh8yOLcwd@!b@V>~_&fP&qJ+Q)P(@lN}+sZMnF-j)2B zX_2~Qspo^ZCDhv^#mO=-%<%o8nr)IC&>J=tijdlk!gph0y6J5o3D$k(zb?h`r!o95 zk&`Ehnl_^^jcYUa&o^I);~h3kRduVL{6fpBTI?)XWH|k)%$h1DC2KSmf?ux|9v%O| zo{tG+F4WG!%>4n#K~&`+)q_Z1B=dp^Rc!WlZ#_f- z9Q})4|Ndwm?hhdMNcbV?z)mubj3*-LVv=CoME*YJ|9__^W!#lFvjmgFJ}tgy-MMRy zRgscdLnapJ|4jExm45d2lEOag!j$y;@89cPh0p~=02pj-h@ehCYe)=?)6D{xE;O;F zm_KLcCacd=D`4XL^USQ}$sPF^K`Lclszt=^1unRogO3NL$r%vS2V}3hR4J7pAVOS9 zY+KD*8LGew!*{mXoWiPBOa_|zs2!8MS{1^FWt%OV72J&PxLSM`{aqxOHZdwTxLtLk z^3Svn)zft=`hJ(SN+F)Gbm%yDsp^u1If=h=x&N2;vEDalyp@4dMD#jl6N$ z#8-#$%n|AdrXYuA*v57Da<#?(v`tKL4wm#XjZ5C1x5GUryGwiD3N}u@i+*@N+`nIV z*3qvkA*FR?1F0_oSV;lkjMQjU%@N;+gMV({6s*e&4iWm!vbXT*XHVO^6u+Ht6nwx7 zn4r!TkEzhK$y#g5yW7Z~_OWcrbIs$S;H1Ho>g9M*2hrcWQJ8Z(qij^=p{iHuflotA zsJ#mgjDOkJ*u2+GjJE>W8SI~$1^RM=;jGXsriyWKuX)}+)()yyI(Zo)UG)DXVGoHK zncKIEMhVr8jc-*p!xMk=w_4VTsyLjUrfAES*iAsm2 zs4#?C(tVwK(P@vh-0^4EY%y5%I@zjiZONXdF<_rxeSR}MIPi@Bbv&lkk3GRnTe`?N z(lDLb6k-0*MjsG;bv&1!d6y8Sv3UGv>*%XvT!*K|_IhS@ z0veI6sah~{WfFADs~1f2KJw)PGPhA2GRab$gW!%8U%^#{3@@s`v7>i$fBE0+uUU`= zFfg5z6uHTc-VRRa0ap*^-4s|K=-e5+1ZlH|KC5n;%oHMTom1RD`w-X{?2XFDDg4X! zkFj`}<=|u(mNTnJ&2c|Cb?Nu)#*upb=jIO8mrCzaGbd zdhmW*R|Um9Uduasz)16;tC>P9=ibxwez$?Lp_{ZvB7(`VpP?r^r^xG@9FFWc7a-z< z@;h+^fLh&1F0}2cphQ@iZ+WwES{3>q*<(Osu>QwJyl$I0=YM3!qzT zJsY0=Aq2|2syB5YxjKdr0<^GXURjY zQdpy@ApdZv_Ae9fs2Jnl!9AR3uPr2g^Si^KGYTPvMZmPvwXJ{16%Vk^`alK`#e`N8tCeEUn&WMzS%N|3!1e%Ik~F`FDCn4Khi(!OK|DkV-= zL?vm{0tR0#2A=_ljxDXVGA!oY&s${PO8giLJO*wiWqg*`YjJ0bfnQ#f5FP&`o1SRh zW=7MmOn29(K}~RR`kbnvJsY#74BnmN0uznkYZa)-*Hw1@+pW9;a^FpeIrE3TVH9K+ z_;ZVaiO$W}k3#SM@Shv9c0VzhxH{F$ogBt4q<``!=?uu>H6&9(t7hy0w>(hTKPt|% z%_5~u=A1vM?>BBu;=^|tUlrw>uUKR*VRK_N@JbMo1h(k5tdx*A{$Dx#R^z3W7~w1U z*hu`Yl3QLj%wK4oB`Q~%|DvV2#4Z$i*Mwa?5 z1wePcZ={FK#GbpO`Mw`O_|d{iM&h=zEYD)UrwsY=eB(*T%fLgQD`+@sw# zjLr>FvW!qPIS(a>4l4Ka#jp{QvQ|PF1B9m)kW4^kwrwLYTTh;$;EL^Ui(u${#=X7~ zEn5~jTh1{L-_f?|izWOSpQ2)h4wbU~m}?-=5Sc-e^TSIbpk{dg1gClv=52QBuA%AP zk{*)u5*!f;OjceA z{5ZHH#ihbk=)=kA*KL__8?lgK2&qb=3?@l=QglTpQ;56Nr3&y^r)VwDVtp2o#MFdaQ4|pym2=Gl}5Hy$l3pqX@GvIdbF)&MO`Q>w;{DgX6|0uiq8g-}RWd z%>9py{x0V1KofKj0$IOyNw3iDH*F2;jE*YO7X9+9$!t}Ci!n`g6JNX)yq@N#!YR16 z=8~jmOTtD0g9<>N!@d$N6c=&MNn6SO=I?f{&+`phNUsNUbL>`LH^Ri^=+ntGv#Y+y zw1nawX$TnM_-k8TA*7_U60Kie`g;<*!R-5ne>nJGhx^ky@AX@=;CW-O1dB;cLDGa> zKk%;r?l?#iUgU~@TFRSPT;f;u?y*5;Q@DT?^@d>Sz?)~=Vr#;|@4m4oaoI+94OxC5 z#cpYYnrs5!UyqZ>_xXwK9QHft{j9e~Tj;2Y_ndMpoC})Nn=}>L$-j=-)@BOLKf>=! zGzUQ|!J4FOkjy$h*&^kYtx^S;t60c#vYmqF>$YrRQkqH<#>vCraauG(>O*dG-E>Ad zvcS&~Ham8wVWdD1lOAv2JX$AEA>(s)N>adtjbDyQ24^`VIVJ79mYb3zuKFX5W@U?@d7|Rua|vmSl;E6~!taUVkn5WXmp8IQ8~r6Ro=F*edYvf&!OA z^{eRe*q%W0` z5gc-G694Zl$SHH~^?Fkc-N(X%Sv!5+Bw4_1nEF!UOY6FsiYgA1`u654tgR(?v|V=) zgK9ZX-7i6A?|y}g#NZ20Sf47q3&|GXXn2(i1z_ynXb!B$KSzFgnu4w#kaMeDW#~?D zOm@4Jy!sBc`AIDA4U+kzM{rJYa=Cc)>shLL^sMyA8hKRz=oI-*{=70Q5!1gu zU`-n_2?KPuQH{;R>@`~h*q;d9)K|T!p0|=`mRp|pdz;GodTwVJ@;vaxb-3Sx<@tPG!Xu{@HvRtqK zKvvghishzTfz0vpU0O#pAK$19jD{@VDQoY_Udw3(wiOlr^q)D+970XooyrW@NjVed zTqoaGa`;Y?h^x%p#A$3OQDh2GZIV<$GK(&%SrZE;gQ)yVwMiHYNSTLWAt zSB_V80C4`?I3a>awG#RfK#O$N;K1~bN5btlyYpmfCr)hieP)pj0_{@|WXDSvZNC4O zDSOki7Io2G341fQHM5L152~txR>9rsOnmH~H8(H$8`#j%I&lh;Pb%-2L_eI#vwE%n z%GlU=B0V#;{_SeHX}qbKsd-&i>*pNZz=f?oSx;93yv4+o)X^C%ivP}g>#@jCC;y68 zIa|AKE`;T~xUT&;gBt?Q^kG9P6eU$4UU!KfH8TfNlALbTN3Jp6p3k||IF!XY08(71 zrRv&HUq-`GP$9vR`TU_E+kMzSnqp<{K!I~C$)B)rmi5Wx8_Yt0RHKf+-bpfP2+`G} ztKYP`7(y*wNq{BczC|rU8_<)xh#eH7xCO@V@93}H++K^4?`3BU0X-;Jv20x_9FR!6 zp~>vwwPlUYZJhwxg4kc^gKjq^Bx?%Cd3US~-1Z97h-r4Z}fmq424QJm;-AE-w2| z!T8SO@fpoK#FzLwLM*YMEI?!hRtdr^-%_Y50`sn&X3hvL+4!5Kj4F)go$=)UihKCB zhl&!_1GpjO#HU=-HX$D;e|2X;kUglj_krMtDncOJu=<-bqX=VN?th>Y8-hlCP0Lkz ztK9t=M;t0zT}J9sP<5tGywro#y>SZ3d7V->+$@j^5mkqCT>_FXoqDIszfF{wB7#!? zo*GF&&V0}EGGFUVuJUAPfsHfKVn^_dO4wp%a~?BkMG*y1d&reDpDTW>Qaq$V!+52t zw6x0?@r01rta9s_uRgh2|6~2td;V3Yoy$1g|H#l~VDd|dNUT)-*W*NOgUD{zP%KB5 zvHpRSK%>=j?`=c3HJK<}2T%Bb!WH}V)N-T9ZWErl@5S2-2O^cT44`I6^oc2c5BI!l7)pZ5(0hT z-qSw2vQNt$x>PWYyT88yZd>OHV|GP{7n558g+||{+3Yr23l*ha+3c214Xka?xYDbolIjEY;tG0wO%xA0~_bJLs=UDvy+y;r-bnwJ^5Tj zLz9NTLesN>cZ2PTnb!)8^7r(4A_As6W*2USP{CpYSg&ahE+n;Z#YSS-n7-S17i?8T zGIrGPS$p#Y1l&p$h>eZ{XHFObY8Sd5G+T*V>>2ck(=l1fzzZvTybIz!IvHkc1@A7d zu7|+ej#1i}YA#>8FO64a{+aQk9>@OH62OouXz7K>B|FJZr*uuHO^VCp*we;ucDE}u z<568mp2gxe^+u&;`~0$y!Y4J=?3syWKpWRXYMuAkr~>Er!`~OvLS+Ce-!fH)GfG06HZ1b9U}R_2ZObe{Tq9Y|Z2NdeJwE;o+||MWGzTUOY2l zrRgfYRRGWV9-SEln+OQ*Q=R#l8RYS`cs^GaQ@MAb(^~yw0D|?bWZjoeF{UB8qTS(< zdCXTi?ZP^^3{3%TJbl0U65E6?fFJ0J^2?6OxGwiOy}c~j6#l@~Wd6RSH_tnqNl~zJ zP)7NndEI*H!B*L6+7*DZdG_1$_g%jCx$R|LFDvS=kt1g=hIy`c1>0rCS}R^ffy-uZ7uZrR6R4mg*Ia+aC+o0+1IQ`pJl$yU6+r5|%)TQ@Z9WgRBJXY1z@zz+4X z;hkiulg^JXnL^HUDm9hwBR=h$dW-iyNsWHzn8$QephO_=KBonTXO-BoQT=g8S5V6iP|M{JPphh)$-^0mjl;&c zRlQ(WdBJ8b_Sb+m`iA&SihJI9(%wL|t@Dp{fit^REWDi`l+XOh=aZ<#OuAL46Wc4f zM?)pQZQY}Gl8JV|edzo=fzO1D=d^+``8Ba1M4`Rl#=^W#5qglvNvBY+X;>I*1t#Qm z9Bl`q!WP{)*iUN*P!_jsYW3H^X(o9Z<++`fA2?H^x%!Q%f@qRmCL6eSf-`2Ss=}WB zN0uk(`Gw!dr;2HVQ!cHB>#q3O}E(V9}%zk_zZZ<+NV&|>ca^rOga>6N5cFq%K8 z7y%uoirf`Px&bgzMLjwoTN_A*H(RE*}GD&^aFD6Y6RO{`aZ(S)(?2wKi%? zFBOoLNamdag++Zc&**Fkj*K{KD-U%&&BEewzfb|Ez9<#bsEa;(XMT@088|&Y`(VBY zvD~=aZNjRVJ4+UyF#6bAr=u^8nVGP0zM6+4F@tO_gvgP zPJ>o`sI^w`bzt-;C?G4B zAxYgU$j;-kPNNaXcBLQMXHa46d83XST4TSoA%?FL0E9e zTB#grPBeNREVQgnflgnTIxP`31fZw;W@ee3^#{yrP9NexwgF@wIrIh@xvFTG)_A| zkek;oi=Q5(Y17ZsM^!tw$lhvsZ06y&7NJV=zv0cSmIAXwMt4omoKIh7zIsg|(}#~> z9+E8-DD9vrg28kyT=l?@tZd#BCgpeIf*}INO#S!NM6EvPWm9Oytinj}GPHr0b9hE8ifLTCC zJZ(64sHYAD$l^ziL{f8Np7ftOtK35>)}jVl;M4q+&* zcda_zxFvIA!~6k6VxTrwMp{hi>&GL<`>&)``p8#v7v%`OHo=(*u37%*&v(5S7SQ^4 zay;aZJ%t*{dE_8ar^l2e-N>iPb-KuJZ?i2oH@BjB{=7ZL=e;?>G^kPn0rEYlnz3;Y znaa|g5rv}5ydE2^*JY!N98lBh^Gfi$QTYYzu^L(zXdv>OUFH!u^*5IwgUsHa z|HxE{swVS~hX|!gk&crUReYwrzmvA?Y3Q$;QrDG_Y&ZuyHz|so4M`7`gwOTHjLY6& zY%Lq~%17v@gMGtAv23gUTH`~(qBDiQ#o4|vYnx3_pxh@PF*}I!!B%6t%fH7>!2wv; z2SAW-?k+`OkBx}yypnl>NA4U(CpdB)P&DsRn9eZf`D{r91vg@a(fg0Gbo6BbDUCL>O2 zYs(uC*k)U}(1Hex|yKSVI2dCg(P}NOF}bDXzRt zq|@J=)@5^HTdv#XJyuH9RHJ9w_Q6IAcCi%qF}l|VHoTE%>HiVLtLT!rF+ zY4BVQ3%UYpS#%-RLn{^*>G}qg#ciF_Jyq9I+qihnMyJ4&rGP#@JHBrHdjP0Sj)Vyl zO|bqkP=Qq>gN-fm%@*Ev1fs6xSOIE&{_sOhmSId@m^I4 zO{oK2-#bk2R`^1gMwtpq&mz_<3mwQawMAcbC00C!N5cf6k0UW-U$L)o$9g^O0y#bC z%mQz$;UB#WP{j`OqnNzuOlcMsTb}-%Z%055Yxsd#&~_y<3qI^91>W8MC05>0xJRlS zHP8Qrz6h;DUb0yb-Vm)Wm|YdoJG>nI&HmvB^8b-llR}C&l&Q{CqkCJUXL=nnhTX3g zx+P;M?x8RTyC$p4H;9uY)5G^`(MxTTlq(f;&5mD6ztc=M3HBXlvf0i;-90&3Yd30( zpA#CcSGsNR@7JcwSoe(vk||%~@&Pd(SB~lL(SQ)ran3pNnSP{PyR0rXz^yH*U&OB! zlKapL75Tx+(cMvrTKXrcqpbY$WLhfl5>1Kgp=|&DN~tbAoyh~(O>3i{TZ)=w@kR|c z65QR=^N({b{pHVNo6?pJdhVJNT{048Dqgd5PO8Oxuep`PULtp)3T(?f0E0>6#Dr6U z=u)#go0O-gxp`8Swh4&i@P~0-eGheJgkY}A@+W5G^;n5l;kL}rpy+}!kGgkha`&BD{T_F)Q>K9S;PL#pXX8{*fj{*?w7^Q%o=zy9 z=2e6d;1xbJW?!mR{g61{o$V7xsxBZIO!>~vElD#&6WHDashd5Yl7@^i-Pf~7rW}i_ zuQ2+67EEIlrktN8AO~x=co3#;<)G0|fJgqw@2)j;C|GWCy;qZEobZf~BgsE;y<5#C zS&6Jj)z_9^uMB0xv2`X{Qn*`a5Wh+CFxj80f#()4$BRQ<0ddQm*Y~03O|3+du$X=4 znxCkR)v5U_4;od(_UZh_X>;X!e1;A6->hO9DR5j?zJB9^*UYaVJ~^D=7EIa}weshj zwrreG9=Z{z5qSOj!U4CbOB}@<(AWhaN!#xnKC^NKz&-2gmpxzapEhgto+HzF(@-~> zBaarGU^X=Ro6^atEBlf%%iJcwV2wKW!)!mEhv#^2@caryFroT~Elip?$5u7ZTOI=e zIeMLVil`z{>!F8s;1b~+pDlEb@jSp-R_PHbak~644q_)h`g8? zWHCQcFuy~>zmKHhmGtm){NvDM#GUq-+`0Gnk{8cmZ*+68a;&OD)c!u-EcDlHn)Tlwh=i8 zXFkfxFDXuT4dN|McV`gORc-ADFSlRemOB6x*JIVN@winaBhkOlZ%G|5*@lJ3T1(g0 zw9TkH{2Fu+ZeuDC&X-rpI)Bk#8z^3Xk<+wWc^C6D?4h{LFu)x$CxwM1hB`vxG*yV& z5R5KvGa<_uU(y3)opozwf@>B?Mfi+9nV3#6KWZ4ube_EbMWIF|H#{{Xb~Rzb2OfSG z(GytV3!K|rLBz@PI`-VX&ik{tL<~RK16V|;l}epZxG?=l75t#tc_*Pq#bPMpN4xt~ zDomQ#-F+=cQpmz#Bh7q8;s8nsDC??`jS24htJ-++mVZ!acbmcX5Vz$TbAw~{q4&{9 z|Gia(%ku74?fCwgPoLMF_sX|?L8r4il#sHlU80QJ^^9CAT-sHGjm5i15cuj2_MD^-R`nRBm1URzq zwb%D=d97{1_4SC=!=-xi2HxzKBnJ)Erz7}`^IXUI8Jk37X z?IrE^ol5E2$p(`UfGdP`r&;)iWX9go;j)1ZqwdTJpOnzg*fZ?hP<@$qWRf>91@zPM z>n^gM1SOg3L!^r4ynjbAW{&m>)9UC`=Gy@u^WkKBZzF;0YusGAmSh~X6ip(V{haBLuNG+>$D-f;;yyHWnU}-;h zL7#-Co^tF4((Lx~C$t8_p`Ndrh~7m37B)3F@V7K|e@1Lh8y8UfbKmU^pXAp`Mk9aS z$u398H;?A~g=bFt?Zw+CFqZYjGZ17A_9^FGm+Zc&u*68<4n{Exu@Jm_Zprsa>_MApBiBUX{1TV<$yblhKN}D+TER&IN^P}1dybiG=5=< zA@$h>$8OHj-}*pfKq?DyPgTv~tK6Z?ZnBBoI#W)x{uPS11_31}{dmbHE z(az}pkK~Fv-@uk`1B^P$j&^QuHZ}JP+ zlcm}=3Xh(6no$%XQ*#0;4SU&i)18U7jD#Z-+4a6)gsPL4W8U=`Keew^3<@pMWs(46 z36!6yy|A`&vlnQ_YcysR^-J_NWcU1d)-&|H5WT*vQi*NY{3wzID-wbk z^|vFkfVsP}ceA6854V=*vPR2ns=vNXd^@jRY14Mx~uWgk`snf;C?&9UsrE6y9TKvbFdI1zeFR*iIU-83^m8HEs;< zis#V#+rTSnM9cpoPq^jwXEAl0wL&{asNM}a_RRYL`0DyEKknthJg~#1zd17(3t+al z3)s<`Y~}T(+ddVawAN8ineS3WQ->r5z|3@2*GTc>Bv(U(^-gng_h9=&s1qrci~EwF zMEa2@nIPE_;l2QNS2V1oN>pxP@Qz5%u zj?NEh#3xquxeK5A{&|LqRPnPvdAKA`8e+AKkkT~O$Pi2S+ z;HC|YgMRsZQ8|3V-ZGePt7E? z9`CPMBHK$svAn)`ZbDU2wqf^gj?&3wh$=Xmlom@#ch%hL9RP0CsUmWdz|UVc(`}oc zGqBUhZhiC&@~vXJpC5G~{Hyc{A1ZZeaEZ{CH@-i89xoabd#79q^zf0z_H<>*4?p{S zjpSkFP>2*7f$1wKo4-^fBH=dgvn$dbSc6!%RY&_j6Cb>8YHM>9c>bVji8^o)E`?+6 z%a2ELwLf}4lYi&ZtBUwV@I2#qrq*tomVczubIDf1`w??X!h=-`f$wZ2$O}BQ6M<}; zoleRvxqOV%*{jnEuh4#CxJRd@$QalY& zRB^K7M;#;M=DH(1kexbxKkVg-5y|Y(hH?yd& zNDNx-KA-MrAcmIclxT4-K*aw>EreU7Kg!IM*0lEo#I;yd#@3k<6hprGHRjnjYPzWn zqc1IjmqWmzxrmAR6BW_b-_J(!tlm+Gw*~nQY$ljlxsI1E^$e)D_`dbH!{GE--S1l5 zPo&80echtImr#9E=TIXiA%*T6PIXh^kM&Pg=%hnLmPr2ow>95ABVZ{tb?(mvdwWBM z`>RQc_c+YyJoU&L$*+CqW{LhU0$1V(1xXeJt7m4?7V9DrChmNo7Tjmmr`LDeTBaeU z5P_7O7b8v1)JDI@R0O3A=Kd=Dv|LTw z^Pv`h+6CQREAx&z$FJ(G&o);fmuV)Xnt~v{oqsO)y0hqRRzr3jGA|zgY{<($A>F_E zcx!TE^K6z_(tXWM%p!fqimJuQULL~utk~3|qn9JERj2=v>GM1dD-1{RD#J@#c`s<7 zH>begRqM|$Cq}{(q(S~K$VO)=Ji1G_W`j`U*2cv%08Xg0H{UqXxYa0ZO?1nELshRznP~_K-XK$_z1Gx%yE&YbK@a zN3w)VVx~F+_({K@=n6|94@$0V$DIDY)ASxi#LY!@x~6R<8Fwm;qscrm{0JYohqY&P zT=<*go{%8MaIxWBLq6zQZwgzw{nE2Q&=2+}qhe%2krWvNMrX9!^PfFbSxB z_0+5I_a2uJEGYR4^XITK)x-r4`@9o8;1kjj1Z0HG@G%na`{LvKWCG-R?rOGGY{Twl z^|U_#IHo_DOgC$YMdlOomzxf8pS1e86X>p1YNn6l7lUY}T6Mnn;HpJDO5O*tsAici zs|Uf@&O|O=5tk;$357U9DahABp)xuS{^azJT_Kf~PftRrkDBf!TVG%=4Bk!r<}BQP zH%UOU+(6;c6S?$~{h#RR#pBTEl7Wp6-MUdOCb#VdU;0hA`7EED&DWfT;L~+bP#QcC z>lcTS`eZLTr7nTlxwy~}dCey@<7dS4faKQ^`fb%jxw=k+;$@x)tycQf>g#}CHm;s- zb*u`A*KMmoWKb8C0+)0cCag`wTO3<{r@K18sd&P$ng$}Z0r~8;v4FU1kv2q{(xlXh z%6hK3d*Q)h=eQt$R#L-h@~#8MFgQOk$ho9wn5v<&J>NN8y_b9~X~uGavFEUaa^(bI za77_M_)9n8>hqi2hFXKuz5hqoxi~WU{{LTZl_WWooDYR0=kwVrIVE%uIW9>K!*U*G zOG3^$hfpCo&S{q8at$MkjLmUu^ZDK1Kj8Ntm|ge1>$+ag=i@PD(cAw@tJ~(2 zF}wAX<&_7d=GF}S|CqkVhjS1}@>Uap>^Ed+UwKjqc5E0!*dH#Rb4$PZJ4&UN&(dth z#jUA^t1HVT`CN8q3 z-2Y(O+pqPTDfD2aQV@G%_E(&%{Lb}^T0WmGy{rc0^%+XSl+0&e?iFgtM5A}OH`M$Y zuxUQjo=}`ntS&ZhH23Qtt~JB#PjCN^=}MdWMw{-4cl{4lZ|#1*?5BTP>gt<5-tyX3 zzIDlzAH+c9b9gMbyUMlH_Uax17T+2pmt&5AFtJN-&od1ga&=tGe<;1mlCtHW zuc!2^C~Y9=bc1m8QbtT}`t*@c=H13LU2ZF~vFBv8fK{nuD7~TydTJ~w>u6#&ZNvq+ zUxjYSg&$y3wvenSxFe*3fO;<{aAHlX#JYLTj(am0H%-E2tw-ct9@ zELJRXYm~eHrK{umRl+SFR)^QE!PeudNS2K@4trbR)C)82uzRKAAhTA-3z$4SR91Rw zG5EyBuKfIib|(*;82y~}=}HA;)4*Rm+Vt*dJ@NzE5p9nEO%eo$L;f@O_hIF&nKcvn zak2JTr6{4IQS3iBc`YdONX*ac-|+2OzGr@ezxzakznjYS+M$qQIg7UAXx6GO8@ry; za2Kd#S&t!_v{W}E`|l#<(?Y;6?|yz!GJY5>j#3`-a&q zMH8zc>4HzDw-!uDqb(=LpEpLE-pe)2kye+HVDauh4kZ_its2p0#z9lZqO7MQZAuN4 z*Cq3n%J?4do5UX2C~kYnc{RcA&xZnEiRp>xMa)<}mK`yZGnkmQ^>ndP`Vu+5fD=Zk7`( z_V{yZXt+N(9gG=53uCvS#NQXV9n2S#VrRLGRU^XTcsU+;{Rt?j!^Rb0lKcY%t`g~qZLnXAbY!# z8bzCRfAsC(+jtn*7Q<5aQyE59m3RCdIRvwZneRIzTeTUY>F?o(!K7pO!8{fhzi1rg zAGk2g1Ge?}J$frnCa>8<0U zxCH0&!?p_pO85gr;c6biIhDfbsEH+IU z11(E^RSFx2mb??h--%RNg|2IDRnuPqwjsblvmGRQ_-s57gacd$uB}vFVylImEY%N3 zlxiZ+(Hs(QUy#s$kpyaRtZQ(tNn`?)dZ_lWfwhBghmcE?>VgTGYXGr)Dua{%@trhx ziOf4!@|D2Oa1ZJn?GfC9{Jo68(5Fn$ zJbJQ{u~olDXfB_Cct0q7l34OQlH>_d5QWWK+x3QHIFwBn4e)C?adbaQH=cIY&QLAMAuYQG9g=+j5pNwHJKoOA*3zQCk;sXYBK`uHovH#et?}1Y;vb z2)?aj$|v5qm;@?E;hr9PQZARyb4*Viru_w2cDh{NA%z+oM3;C)>tH`^9}YulL7*mT+7X8x`CZ;QtK z>GfFNg@wlJylh7Dw{0vO=DdSTULoc5wHZJn$^#r@9odb)NmfX#PrOWf1O;^V(LbQx z+gE!W)Wx&^oc$r!^rHAqd(T}|;*+Dhe|2rRH=V9e*?z+&nf;3{4V^sn@79F<>tQy| zNWZe{+Gg<$+l<744;!g06yy0n1uS%77rDdM#qwA=v`o0YiMh7IrGXHimmXq2ukf!;ww>={ z?LFnh>t~wY$WShyAtnr{#iMdxys58w^SRWohh4#yRgyo9;5kX(s+guh`TzEj>&u=F z_)fU8n42oN=d7kb+j)gBAy6lS|A}R8~ghSs_@b01v3Hg{BSU6Zt*J&PCP=I=? zBDWYA>+06luHJ}%Vd+>q!W$o^p+%Y!+3j$fDn%)-C%i9Qu#EKrx&M!e*Zl+$8Cbcl zy`AS$1p9Vm{?^P*9LQ}lmBs(uhDz`T|8X#_|JdnEhca^DXGA-bqYHTV!`1&VFpowL zfWyO_ol&EsKEX1M<>@usZ-4S0-x+3Uli5y*5nAKh*Q<1bkpLL`KM$e>gnOo${~cgoiOf z3)yhV_;Wd><^!)o3i#&fG@iMdsz(&Pyy)Nlv>derQPE>$2ne#e1SmvJxN72R%mss+}$iBqay_xC- zt@O=rwnf#MokpC?CEGpbo31_#uVy%UZ0wK%>t@lAl6JBIR!=aFbYK@!M=3XAeABgj zrQi)(cuY+-<$5(p9ZiUfgrwX~dHwv0sQ!}IB^yc6Ug(F98{C_63!wnYy?s;gW zT_|J`KG!@SnG~NNYIESd0K(DQn?Up{<%^;uu0YyNs*E{>qZ4_JD!Nb=$v&>#6+ER4 zjdvSYb$qgI;#R+RpDb5q@>U|^Q$iCn5b(VA7tSKJ#h}U1&B!J15Eo$P079I(vrUrn zJ)6SP)!@W~ZOVO`w7zX`SwH?I6EfFx>)qCFq_@u*r_k!-)Uv9j`a0_%QVBR0eXt#_ zF3xHZE%JFCe;{0-mJ_^;o8vht+D1EC5+Pl{{qbvb@vH%~glcA$@Amvvvx(|q)^FRl zFWjVk?rU1V#5+H^ptb&Jn6lG-#o&CQ>pa7PB4MdDh%UjUs?0VUTzRh_*CiyhICgS4 za>{l(ggqOu6QgbQKPF~4E9Htkqf*y-5zuDXZO%Da^2T`ACq9~C-EXY0GYd&KF4Kzm z&RHm{#QA0#)%<_w>Cd9ImRl}v932H0VfO89GL(X@V`AIL{;<&S`B>(SE7D_MN4Mmk zY;4#jRJ|>$cx|Lp9o@8;?eCS9+k~0(R^6L8yvQGZv8MTR*0Bd+r6qa(<<4Om#a6vx zcp;wZ_9^Ovu(GMm_d6lnay1`023x8K#FgT-!zhZ^6-Rq^?hTK9%4v>Vh0x4Bc#W8? zPpUe4mNU9N?Rz*o(i1O3Jx6Aqx9ll+53Xg21-T;6Qj>d-_129DF6&aT~tDav@(QPrDqxqBeg8HVs;;&}o`6WgjbW$^*bK z?6SHTc2mz9rs`Y6?l(o6j!ohOrN7s}QuUy|sitWj4R@>G`Ht3HuJC5l@WI|Jn4_-I zgbu3HJ^E*N%~1GCw{YlGUqO!p5{>+j5X(jlh5bq8Bi^`W``x!7Q}P*pRa9}eQ|Quu zr5Pa^p$UPERlr{UkBKI*a1}RK`7;hC;r=^X@_lJjx|wvll5q`e)(~-s=mwKb3V2}9 z#h4ycLIGN#Q_$RC9=t{JFNJ_ORHX-(Vu`NR6U8IMhMcSKdb|@$96NnalYRZVzVtGo z!$T_Fv9ndzgZAd4YJsKBGIF>STM=1`~t$f-$` z{dB-dr-q85Ny3;r@^6jGd%Yz0c3rPB`}WDa@+eleC$6FGeoWv0m~2$Ep!+{@dVRlV z&!DRG`4A(Rg1RG;5_#&BOUIBRnv9UEM{vY{*01wV*S{aX0~feZkxtt-wKjvNG>*d^qN5 zS1wyKXYXi~Qg0Ka*wl;ubSVmyix8oPEHVrh<+F%LAjorX9PU~qUo4mW;UL__qIxW# zoc1aC-+voyLJcE3dE$n0e9K16Hl0@O#2Q#RabfGLMR3u=lvUm_W(Lq54H5>$fwTLyp%^3Q))fg5WCT(*eMBW;+ z0T09REdP)SZyynm=1jE^hvFObaf#?wBt?9_1b`jdQf2JOJ5jQ5mU(Ig9O_IQ0Kylx zjvK*J-EDFn+xzyy_f4h_%}ct4g61=x^St`+dOa5y1jrG1={&J?x5Wz!)M4`I%;Oqr z22at+TWa#xK1gt7u4cZRooUhE1o=c}DF`z-=)>I{$!y2+4)D1qj zfn@ih^Dj(MgcDKm0gwTP6LHG^r-xzGXFJ!=n0U$ATWj8{=D*w1Uqqp53hya)`Z-P) zPw2;2;`<<&V-M@P!;2-i{gy2aU*XVmc}HQP2gV(Qy523-0<=_nK`h}Kg0J&@3;?5I zYIbiL$}TlNWEd@W@#Z-8e0?FOaD%4Z%iMW3chO|Y+RdTqp=8DUg)NSlmJ<-Jg}Xc)lCI9(a za>P82eEhj`=%Cq=*D@a`;wsxwP@7(E7-py?BUf46>I6(TE#Ll+2|}Ps1;_u7>1Cqj zf=zTwIMJSimr5Yc%*bb)kA?VuSI>p~*iaARIQ+RS)u`Mg|MgNzQ%l&h3y)YG5Qz{F z*`Rrjts|eSbp)Yei;WEgH0c5wU3th(4ej6$@?ay(cvb#f-nQL>SN5dq^Mp4_zIikE zmZp4ZMw_@7t&Hpg@XWO%V`?JJkl>-xefCsnypSRq6JXz2=21-z+zG5ytGHgr+0Dq4 z{SM*eG`{|Vs4h27_h!@pD1M+N-bhBq1aQ0$R&Ns_7q@n)m{ZsbbM2@>X`f{4sSnmt zRU@jBbE@xjC2&iK$E_WL2w8-+0B5D24@S}VN1G->a7X(SKxQTV) zdi?qXFxvy-4HTO=_(Ro!-(N<&TcnHoD%X8g%%wh`qd)pI)t3?(;F~0~$`MmgBb5Mr zy9yt2vN{3Xn43s5z~o%D!A`g|;4nd%{>DPpTeg)eNX216FE=j|t!ST-!N>uq4Wct< zL})hyyl~V7W`*;S^J7ZkpeFMNdq&g`Q%5r2rJ}xT$oR+yK#=N?c*k|w8-}-+dM^8d z#pvQdXbXFhZclCZrHRkNR66lGWPy#i0&)f{2gGhqjqV?}e_)L#Zs^@{=mh|(r-@h2 z-@3D8efixAf{qR&j4h9yY|aT8s}}S1$g`O^I!^l)9c;jMqLK3{NKTg#x<-X(o47Z$ zr%ifF*Za#H)k01O$TKN(F#p;!fC+>+{gK-!B<+Izy*pQ0j);V&GAo^v{z+cw3P4aN5R_aTx6?h8EIiEuqCglykQ zI2)kALV(NUK5oig@M`LfEvjye>`Gm8$JGsb2I#cELKR84OVI9rNvnIw*w~<-qgenu ziAOtdC>d)GjUimDxLiXtvxn$lsn0c_vM(JGIQ*$!9W2btucFFHvXA}kU8l}sYjbVO zY#E;unQ(?EzA9)zbW*Wxx?{JYpCju#$)l-xZ^}&cf+ONr5co3I-JJOlGzGmu&7~PY zaG&)BtwtroH7rH~S3*WA<+l#5<>(|!l8T=E#ml<=anN7^y`Y+%vQAURe&q{LcHSP8 zS8@gB@j8$jKIa7XM!V(Tn(CS&U2?KN-tigy&!o+zXH~-IoPP?2b_ZtM6KX@hs&jX| zMaB1vA?@+phV{`VB8RN*OKmXA?G$so-+N<8Gi_B}YgPaG`CKAu#`5$c+5-iPG#IZ3 z$4te$l&>p-2^_pEnUHw1%ADsxmh5jwRla@b+1l20?5*0bE<76js7!9+4+wzrcAZpLg*a)oVAW z1HB<;V_)+Ey#Ef3s#sq7?l{IO*730m4Qq%Zs}p);P=F~LO+v>+*3+^wd+!+ugl+bk zH>DKcy}1Wn_I|$nAM8PG!^Dtzm`w!8ePrpx9 zK)}N~X3XnF9@sUcz1-cd{w>>lh6Hd;wr4}4@rCH`^I)t9>~)0r*PjPX`GXlSm=(zj7b za3}7VH`>`bhC+86unHwtej6M91CdYQG_N@z>Puj>0d?|9Tg8m^bjuljlo_3q(DUPKz;BT1sH0 z9C~mZ6)69;q}yMv>%2_fx4RNPUoZNIi`kGcThA(C@e45t`l=gFmm0N=uuyX00wc4$ z%+7YksmYUzn$_PL=k9Yo2d_m8k=QfpPV?;y;5)oM|AVMlUuaQ8(DAgFkukzS)+gsw z^|NmGP6bS82dwuMq5iZKx?%R)7Pl;MabumLbyWa|^(yQpp%Q)Mfwbqjh!Uc@Xde&OAFaGwe}F z9h&KGyG34Vx{twCrGy23F?S7QXKcOs9mREMWc7WJo{$FSfZwO~Qg8~?+q@BQ*2>K$ zd@1?e)WTtFg~Uluyc^`3dL^`EO`{=Mc)pf1#=g;Qcf?0=@TZsNjkah;bekgGa}oqi z#-TcK*bitqn|V6uvdd(>t(xBL4$x(fwi^XKN(R1euBC#YTdL~UjSPRK^}l%NqNNel zuG^G$=yWi_I6RqFMO*Bku_~iI;ci?;4*iN__BS!h;i2{oxe6*1SRWA2G%TK|p7q5d z2OP7b3W_|{Oli@^Ju>U`Ic4?mTCHu2y(S1%mazSv0N>qi7mPv*s@rH=6npz#nsT!E zVij+4)AahDqUMFs+g~M?E+adz^$OHm%1TESb?nyQC4=$&IY(~%wfyrt62aV{~ zza&-a&D4_{wXxhdYnaQ$a&gZ0DPR!<9#kE(hp%j~qUW{HNY+eNPR^;1SFiUu|3bBrSCig2=;a!4BqoS!J$vT0Rqrj| zOc-mM)7Rinc}aO5qN&sVVCVq}KQLgp>4Vuq%0FsRulBq_J=S1@yh)MPdM#oVSK;DN zC$BiYW~{e)#I^wHp@Q5*sZwrR(~E>F>qkzKBgGVr_gjl&s<|Jw0DJVJ)s%pt@}HYY zH|5wk@J6h^b$mb5j}}4yN)8d#WQ)dNH;R2vR)Ii^6nXOwCA`Z9&p%oTmzG4u?yI%b zjgkVFvC@8riaVGWa+fylg%thXCw!>0T?aOFrV7(TI&1mt1~wG%`yHR9ThC3)49Z}c zIQ*pCs?YQ{Ly#DY9_ImSE$Q~~Pe?L3V3%%am;O~#V)<^*p{ES$>7Rb7Pvlc^oO9{e zk8zY|DSB*pxTN%;4Y&t9C(1}~;V1IZ154;0UiRHH0+s^5Fvq7Dv zR>^~qXlQFQ(|@Ky^g`NoSmsPGNC?>MAi35uNrh`|QdDmWo0Ey)r5+h@Ot9ov<5(B2 z?Q>~@cZPK=WCT0FHAn9bz%e+d8p~?VASxZeaMTthUEBOQM7e-NHDYl=5I??peXMFTRG+K!#o?y zS~7c=vSBcL6I+<=&0sFoH~p)TkvVijR|nQKmwd+*mztjmy&O-cC!=p#&AL2O&8a*9+8S-n<>3Z=dfLvG1Z}cc3eLTowhk^)CUd_YdJ(kpMk?MyIrCPUprT8_^ zCS@~Z)=&{S!-q}bet+EMt_gp*^>}+#5s_tiG%!BP=4@tLdV}BPw*`hH?>s-QyWUAI{v6kE+ zp8GNGObSew3M^q`Sa)!OlN!}>!7>6j0X*EOj+L3MoI6eItArUKf>bo<`Bxmu8m#>8 zrWf-swZ+h(l(Kb#`=n5a`t6=M5-YBQ&z`gC>m#7q=PHi*?&~liHttYZk=E2UIRbj> z_0X!=E!;kgUT{#lZ`m&T4?_$lNfuI1_I_zEmq~TZ-QIJgB&DbHC%cxcH#s!Tjn%)~ zxKKRf%x2o4mXQ<`C97VLzI2VSUK8RhS3kWx7Q5S@ThbsV*#1k*e4OQY_q+vU_LSpv z9DGgxf_t0R-!@+JB?tPwnx8ckakDp*JL-A~SH+^e5qx{GW?ee&@n5);T$!stGMld3*t__J-Cq~POyjjbnc z(COd0q0#ac6{gj}-hqUap+%=j+nDa5!eXP(uQrWS@T8)x?aEySyd~o{e8Sb*=eA;t z7pW=}oL^9S1n}m}*N|rrSLlklUDpIENxgAst$l{bpxW8<#E|0ps0T4ghL64z)sGJ; ze^*o1@%oIy76V|O(v#0k^}YC@O`JNl6z|AB_qwIto)%F|PmA77FE9JtGcW+yj0@^Z zq5-xrO3)KoJBaDbMRCniA-^2gnC0SX24Y1FE;+# z2PHdQXQYUpUgRO$EGEUlEfszx$K<@UXc&V9PComIo{~eoG)8O3*PfE3q!==q;s9i9 zys$ImkVV)?_032rF!LtPr8ipV`pq~(!wb?9iI}E+o0W-Vhhu5;9w8SUS0m0B|R9I_H9ThG4dzVBYzgm>Y z@rTLOND&MLvLMQTGuTutXb&O zR2F2zZ(qIjy54=H@I#3}+eo>UO>MmoDLi0ruMwDwdRk{n%`6?1z4UkjPwO0oPiUoC z=9q>jB_pt)v4Ut(vbCP^p~Q%B=kWB=f)`%=ulHl0?So1mJ%wlfWu`Uqm8p(Kf?-i6 z3Afsf9{C)b4u%T{1NT^Lr+;&jVxY)!nCSiL)>{HPXGa4}L=5?Uam#+wRHBjs?nz_U2!pT-E-eZ0PL<`GN;}w*6}om>l7c{U3f*v>(=SD_YrH2Svc0DNN>& z`Q#{o7%S#DEn5NC&gYrBYTLtXy0U5>XOEiwb_^6^L|}sm-vaU~>x&=SNT)6f@34`; z8x#9YJ6Ow3gAI2#UDMd2!l=#`$jF1ti`*HZ+7gU1&nZXv2(9=VvVFjAC{3!QH!eIcp5u$15D5Ci5r}vm_9GY(UmC*9ij=LKIK1b9pC~KMtWKuK*6{ODWTn7 z`gl42(qwLK|6}aYFBAXYRVDMmk!?3%Zi_5$(I`HcU^nhwZ*VZcm=rkwwZ!(1#--F~O3Gul>SIKT2(@4Llruo-*wkzFEU&L;Rarwx}NCmUeiq_9dFydF7Kx=5rvtJeId{r6ezOtCeZ{dJ{}n@A=e z|0CXbTmj7-2=Pm^56|)H=JPunVf#t+;*W;Z1drU;97zPtEQP$FpFH|c*&dA9>xFUC$! zLyu6F1skET*hjszOU4|-1uT{si`FvK8gm(%jz=?^KxeKPTf#JCYBZ(0ru+05KOTl2 zmLH9svQxu6kX``Iw*AG5fdcSm;4;~;u-L(@w9@XJ z2e)F$J}c=2@;@h?@zf`Vn2rK2dza)EsA`|Kn>d|fQDRxJX3D5tFSR?%2QiujcLSM+ zMK4gBo+I3sMtyqlN_%4S2g2H?Jo&c~y==GV8dH5H*O5*CV?ve|^U*xZQt_K+RSm$a z@gLwp2PcZwOp!nu-5mUzPG=kI!Y{9O;U>D+c`_Cs)DD!+4cz9}rB2;;;ArmA&RIy_ znxF;QpM~i@EnAP}`}O>CAt#?$f>*Pyi};DneqbeTmV*=Gm0H0i?DE9_LX==yn7XC7 z1O{xOGo^>TYGd#_>@%nO@{7Bh04b7`--FGkVnM|MwFx-CCqbK4nFQ}(aDnBRpV0Su zXMQ=J!df8Y-R9kvU$TcM)J>5F{Q9mIaM8{9#eAR*8xbMQUwB!V4|*%@L~F66SXIAx zY#i_@Kix>Fo;s;H*KnmiS@l3v9`qR8Jn$8RtKQ3N{;B_HIh46a>3H(lPV~r*px18j zZ?4Zm$#-T~vCCiu5y_$Jd}S&fw{e8OI%$NoMA{_7t-^X&d1%-Y_drNCEVIQ%COjH z-*(YrZ_5N&T>7^;2c7RZevhoiD=N`w=on=)T@!N7&Qq>b+D^{CH4XSCL&Pblb|7#( zXgcwFTsQ1Rtyy#dY#dXg**E;r2u2S#3?C#b94Z1&!=`o4EdILV^Lwt6a<6_GAE$K8 z4|6XHHg1lsK{g#VjKP}QjsMEmBR=wlYWSQ^jGK5b{&(T^o~<%ib6&)Tn(U;-v;W*j z;ZIHaF<7USzV89<-?1s*+lDDFcwty`j6C~Ct=G#MrYuiI%@34(xJcjJD~~diiz5GA zPwM*3jL~&V(qrLqthz+KKg0II_46x{X+B{@%f$4^(!3^6jN1y`KcLh0tmK_=g61)~ zt$zp#T2B)j+eyR1!|N+Hy)R3i=5n_7mNnb2LpxVnhl{%w$m7d=qaJ+*3vCVcVUXpQ zf4J%k8q<#pX(LCywAuM*wX*c#8~oXR=kN(Fry>i+o4|f$Nou(90W1e81>nc^k-m&_4ZQ*o6fP%LP&uUP14v(b*v$zx= z>Psd4aqu^dNL>{omWK*@J|VY7BJ@C9T|z&4Dpe#4&ss}sV^VirAMg*Hc_*la%4$2? zIiH(o7cNdT?`p^#t%!#Pa(oiDO=-cL*Z8n(CQY0E-D`K^@|=9s0X;+2=n=WzG^WPJ zP{#{?QU!BAgyKwn1^TWy=Z*W|x=!~Kl1kL}sEy$-(V*A(L_$^4KuIxSDU>fqdVu}g z^af^52G}+g&Vj`Dj=FdUN?|cwm2QE4f4eI@b)MK_W&~~8^1K$_>9V&yIA?vz{l%L( z4&|nLc!U>8mqpH~H=)zj2QcT2m3PkF)zf(KqFQS;Zg>|{fh+$lSK$MdmzTRDHsH(l z&^4j9VT!13ti_UQ{;V~Xmtq;AHUoKA!@=WDsn;u-^Lt+UBrHn2M6J?}M_3{)*i`bU zk`x|V_ZOJO2h=yjTc+9&mZ=4mCmNl}@yM&HB<0mEC!NTSlS|gud<|cL>R&WD3pqRV zN!)bL7E#WB{_A?JJwNIJ89Vl$-*$ZnRdI@Vp3Z|bzkrg`{U@Lu#9L}QM8)0(7Q*r4%-gi;%VTF z|1n_(XOBc{Z#K#*)#-vbPlfK@{>*)WBKtT?H#waow_)6h$U^)(0twm#gctgr6{6H8jeCLVha zJ71_R{{taQ7aZG`-*YR5i=Z)aiv16aat243-uiJ!yg1kd7fimHGd_!b)yRLvq$CLc zhT1D}(7u92!PUBmWec-cuRM^JQ%6^x5cb#Ub6s}Yr%yB54tD>&+lEBk`h47;`)ynD zu9yp58*r+=5m=^=Y#d%O_2+4M_fW?9-CGx2Fq6ejdOpk3;pXvQ!j+>~VVzW<>@aIbus4OORb)vEx1{Oxar@XBq_U}R zag8&D_pWxqZpx_-Udnok$q{=|!dwN)_+<17=N{Wm4z_Pb!w^h@(ETTW=!yg$dkHqvZz z-dxO@z93eeXmIAO_FK&%txd=6*08Fzo}Kn>ukDJDk*m>fw++t?+1?d8Jg#eB3arxi zh5EXlD{gt*bJ#EL%+LPwN6%hFk{=7Q67~-ajm_}*A!&%8907lC6+WV?y8SHCHB!#; zM)%{JZ6yxzq~@KnzeDFQ*s%)m+pRpgkimbi>JCUzH~+%==2Iv1=zv)2tE^PE7u#CQ zJ4*U_)E(=WTsp>Vi+}F?6k<+6n+Ve`UAh?aD9+{Zdy+VLC+GMN_zf?6{!O#Y_(=zF zbu@Z%FeA4`Prihbe6NM(*>hr4>=C9{{3`|T{%7!7_r>DSwuQ6=Y1DS)A%pR)J`V~I z&d7ug5R0y(OF5Nh+)S3Ms+(_RA-!DDNPASzD%{GcdBAtgL z5K@yUmR@#nS58oJkq7QG4jEnlNOd!pzy*HJCG{_L(%39p5)$&KTRiEtAnQyg7vmYS zU7haXT}IXD#Vb*cI^=Y0so9>iq{J#bVBNJovC@eDPAE*|!H>wLd43WMN>l zs~}7{FL=ee>KaxSbu%ZlDsBM0vAT7YJLxhT`}TNkU1DaFe7=1+aKG?)e)t@$4q(Rj z0Nj#xZ}Mz`CvQ?-Q2)Y+>^M(j1O1HylsqLTL=kwm~yyRQ(N zuUXJ8pz(puOjbYI61h&1M;99)gG*vj+W|jbY4|y^Uh&E_$9T!#VY&#I?FfuwcnHxO zObm{-2mS|X#6b?*@tBwZc5#cbi)%Rn4-zkN_<9I=b?|5ROc$PA;%51;?JA=HE=sW^ zigqf*t-DdKx`Qs$AG5diCaacKY+cvx9&9*^`ZtDSoOL zs92NWVKG|&1ijxj18;L1dRF@BL38IzsV7f@LL2tIL-*Ie`nT^=cYX;NM`GQr|DyBE z7IsMdL}8VVw#z?rAi-m50l<4t^B&fd zhdWWzot@tZhY=KL^gc-BAIxH9TK+ZqZ;NR$ely7C$xM4VgexhGr$wxC#Uwd{ubqB0 zMfWF?z=l*L`MV{T!z_R!)xjl4+udrg_x)~GG&>mPT-sM1>lzjoKM;`}|4#JWTPEvn zOb;@?p@2v3RKGxQ))RD1Y@`A%4j~@jw`g*TEV3Ie@tC|FmH#h1b!ayXUSr+KJ{tk{ zx0HhLv+o2R7iIQ=cQC1h@y-{gWsSHA2IJH_R5T3!lu?0&5^x4RcBG@^`ky}Ah$}kO zFss_X^~c_>H7%{NYI>upIq5aGdz|GrDoojXpE`xji+(7mUyX$uL%xAGl-4H)l$sl- zdH&dN+5O>Hl3n-f`)I`4C+s_JV?$%1hXYOdfC5}_J1~!MiwEF^jSt_%k(Sm zmN%%ZlzO2!%J6g_;tHroRD^0nOnx5#kmEa1?2eu%7KOn-YAr*`rl~>ZPJd7LT(Tv{ zUw}V8SW@cYm_x-O-FI+DX4C?r^w&{@h{q)E=I5Pn?idh``_8ubYj?aY{JpCnIMYo$ z>3hpo4o_K+OgTjz~Q6#7m0#{&Qs@nM1LQzq0 zHnPIKOu|!48ttiF)6}xYwaMjcTCbB#w~Al(H=D5C7QM$FcC~tM%!XioB01HXwVy1` z)+Li6?^-+Kl;Y?VA0~=~TLXV`F|2a|8yzsG<3OHFqqrPqS5F3#Z0=L5WN$QqW5|%- zr4Sdlo5j8&D0f_7p~E_M%}@E<8JC+%e?-q9=Zmpd)!6j(X^Si!42>?)tMxl9)JQ`z zp@(ENxQ*b z-Tx_ZVWCs#Eo1{bJ#~7~gXs8l@qA*X6Jp4Te+*dl+JE6@QtuH$voMGWZ)O%Qv1!9^ zLm*UcVQk@}XG(ZI=r_@n=h!RlII{S3%1%sLi{2zA=&M_K$tNMQGi0Z-(wy^sV$rmebv;_8*}7o7#j@l9vO5EsKU>I&Flxjk~97PW4ebJMb`7a2NoVGzGTrj zzJ;v>ezU1=!ilI#;fX3odTsO%%T$s_&Hpuy;kEb^n=`yA+jGAL6{hPJP9teH)Mb#X zdyC6L!Nm=PRAa7f6E$riSI*e9p}wIuXu^wBn5h#y&eiq8o?HADcq9Z>aF9G>_ON+e z4uuwd+jPFp?b}?Ur#&-~^|9;iOXgg=Bt8uL7(~>|20C9rmA(%&Z35kaf#TjF5U+{W zef*}bU8ERFw3UC2iF>6aEx82>reT(p_}Yab4HqjBrdEj!v@PtwDRU#*VMO25w7J(1 zV;>k!1NVuRgE+ABNuuY!QhF0kIbo5Dm=6kSxg6Kn&=iqk0Ixg)%RI$T@;#X{m$J}c z^Y>qQee>tP0&ySbZiF5f4|D4*-~+jXqhh*vMVKsE21}@j{+aG9?%8#b+vXfyHj~_{ z4Vhe~hXoDYuWlv}PiN)X{?g*vd5mm#JXL#cF1U%{8%wJ6F7K{vUE=kv$^Me;43sk} z+8>#UD)}Gz#~mAY5$c0G2_N*uC{l6oFtVFv>r~5KZGzx{0w+FJBGtZ8{^+;&jVH6e zP3JzRnpSP>Oh2h@o1B~ZhV@o(tLhBdNDtAfp9yTs*=emDXWXY60%V9^HPke+e;2YI zU%42r@C(6DAtdT*xGf-AJvM*XdT>48P`@($XUya9jl*3DQi!X>$Ns2i*Iu(nyF5Wm zi;^v~fr$=sI+v(HGFVK$V!X)C4TPOSjiXw$zPR7p#hnfjj3-o&=f|sFjXT@h%DG`$ zt)gDua7|%TKGzMenMYD@8z!t&mbTl6wnc5|1h=8z7)(VUwp-0uZc5yE~Gz> zp&?4X4^FbiYftWHQVJp3mXR&W`Ikpq%&OW7f83SK%!7%rm1jv<%9XRoJ~FC$zUqxI z`*%9ocJ;4r*mt-gxujiAqf^nTlDZx_$bQ!VeqfIacvs zv^c=KDt)k#S>yp2~LFCM1@DOmEH?~t_`n*JTkGO7v(j2`GfVT z@rPMdTMBb0UXZ*z^=q0W`YW_DA2qKfuHBsLeFLcI8Eu1QwmfT1a?-c0H7*bT6%ycX zHfyeFkWq}fKU-kg*$0`BoI4@Wq)LEiPrOZS9l=bMCW4~>$8;49<%IdlOHv~kiHD3Q z5X;Ndur6(;YeCi@ABZL4PbW;?5lsxb*1kUCl*t$c&FAAvk`8vF^M!$!=sA|i?dt_k zDCR45l?2GUje%$6o;u+ryJtmz?JKIk7b>elIoXAZ*tfsDZc~F&ZzFqWIM~;0GMmO= zPuue^rHGICjK0c!JpMgevmz<_M5v}$+RPnylP#7NKb>$+jlo3cWn>4SsL~2s$K>+G zWD<{C1zn4hJU!Q+|7d_I4+j-R1T*U-pqs7mj`u%>?|GaC)-a`|$ zR<(GjOU6W;@_XW-QSirQRW(KKZk8hldf}^0+KzuNsC*_|Oo2;UT+%7irKni;^ho zbl$e!jrP;8ydfTx+*^BJz%GBS$P6N%m(%WPHsi|6&o4df65PM!KTCdc+przRmY7NNNOy|`Oz2j z3kOyAK(-O2>!ie^-GwWRmmk2BWEwu)&a3IAXq~3%1N8E-DO7kF!b%*__!of{Y#tYW-!{H7&Hqd{gt6~u?T9+Fpm@7#uIBZtYT;O- z2AR4P2g7Eqt;a?<3%}IGn+>F1Av&uh@+19IiR!}sA(ig_q#e!Uqfiece?f`Id!xLe zINh)}R9%b2$FVszXxD7+My2Dx05gMa`4FYW_^HIU545*LR#l#Txhj@nd&%FMIvZzJ zU)=R9Q~>370eXU+c84ab+tCZ5Lo@zX?jk4Vf5I|u!sykF4BG5yek<<9jA7&QleYO8 zE-{NX?a-~NPVSic;~<;cN+yc}S(iomu9t-4?X1&=77~m+xkwkW^ey6cgo|c`BX=w? zLy8GkB(CUBO3`|1PP<9En_l!KSGc6jF5ZMU`GYY0pr;Soqxa}N4DbSXqOS$&5>

HwCV3{VbWFNs>)O-wVC) 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 uy=_`Os9 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įVg2;*C~@D*Wuqn_}ZM@$DV31hUvSjr$8) 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�*T;HTMo|-mL6VOHubK3DLYP@qW;5IHIDT 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�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 diff --git a/bsp/synopsys/emsk_em9d/openocd.log b/bsp/synopsys/emsk_em9d/openocd.log deleted file mode 100644 index 4ef893515e..0000000000 --- a/bsp/synopsys/emsk_em9d/openocd.log +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index d2fab1109a..0000000000 --- a/bsp/synopsys/emsk_em9d/rtconfig.h +++ /dev/null @@ -1,143 +0,0 @@ -/* 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_DEBUG_COLOR -// -// #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 deleted file mode 100644 index 7ba12867fd..0000000000 --- a/bsp/synopsys/emsk_em9d/rtconfig.py +++ /dev/null @@ -1,60 +0,0 @@ -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/em/SConscript b/libcpu/arc/em/SConscript index 49c32b689d..ff1d8c134d 100644 --- a/libcpu/arc/em/SConscript +++ b/libcpu/arc/em/SConscript @@ -8,9 +8,7 @@ cwd = GetCurrentDir() src = Glob('*.c') CPPPATH = [cwd] - -if rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') +src += Glob('*.S') group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) diff --git a/libcpu/arc/em/contex_gcc.S b/libcpu/arc/em/contex_gcc_mw.S similarity index 61% rename from libcpu/arc/em/contex_gcc.S rename to libcpu/arc/em/contex_gcc_mw.S index a8abe089bf..81b291c1c8 100644 --- a/libcpu/arc/em/contex_gcc.S +++ b/libcpu/arc/em/contex_gcc_mw.S @@ -4,20 +4,43 @@ * SPDX-License-Identifier: Apache-2.0 */ #define __ASSEMBLY__ -#include "inc/arc/arc.h" -#include "inc/arc/arc_asm_common.h" +#include "include/arc/arc.h" +#include "include/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 +.global rt_interrupt_enter; +.global rt_interrupt_leave; +.global context_switch_reqflg; +.global rt_interrupt_from_thread; +.global rt_interrupt_to_thread; +.global exc_nest_count; +.global set_hw_stack_check; .text .align 4 dispatcher: st sp, [r0] ld sp, [r1] +#if ARC_FEATURE_STACK_CHECK +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif + jl set_hw_stack_check +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bset r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif pop r0 j [r0] @@ -29,8 +52,8 @@ dispatch_r: /* * rt_base_t rt_hw_interrupt_disable(); */ -.global rt_hw_interrupt_disable -.type rt_hw_interrupt_disable, %function + .global rt_hw_interrupt_disable + .align 4 rt_hw_interrupt_disable: clri r0 j [blink] @@ -39,15 +62,15 @@ rt_hw_interrupt_disable: /* * void rt_hw_interrupt_enable(rt_base_t level); */ -.global rt_hw_interrupt_enable -.type rt_hw_interrupt_enable, %function + .global rt_hw_interrupt_enable + .align 4 rt_hw_interrupt_enable: seti r0 j [blink] -.global rt_hw_context_switch_interrupt -.type rt_hw_context_switch_interrupt, %function + .global rt_hw_context_switch_interrupt + .align 4 rt_hw_context_switch_interrupt: st r0, [rt_interrupt_from_thread] st r1, [rt_interrupt_to_thread] @@ -61,8 +84,8 @@ rt_hw_context_switch_interrupt: * r0 --> from * r1 --> to */ -.global rt_hw_context_switch -.type rt_hw_context_switch, %function + .global rt_hw_context_switch + .align 4 rt_hw_context_switch: SAVE_NONSCRATCH_REGS mov r2, dispatch_r @@ -74,15 +97,37 @@ rt_hw_context_switch: * void rt_hw_context_switch_to(rt_uint32 to); * r0 --> to */ -.global rt_hw_context_switch_to -.type rt_hw_context_switch_to, %function + .global rt_hw_context_switch_to + .align 4 rt_hw_context_switch_to: ld sp, [r0] +#if ARC_FEATURE_STACK_CHECK + mov r1, r0 +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif + jl set_hw_stack_check +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bset r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif pop r0 j [r0] -.global start_r -.type start_r, %function + .global start_r + .align 4 start_r: pop blink; pop r1 @@ -92,6 +137,19 @@ start_r: j_s.d [r1] kflag r2 +/* + * int __rt_ffs(int value); + * r0 --> value + */ + .global __rt_ffs + .align 4 +__rt_ffs: + breq r0, 0, __rt_ffs_return + ffs r1, r0 + add r0, r1, 1 +__rt_ffs_return: + j [blink] + /****** exceptions and interrupts handing ******/ /****** entry for exception handling ******/ .global exc_entry_cpu @@ -106,8 +164,7 @@ exc_entry_cpu: ld r0, [exc_nest_count] add r1, r0, 1 st r1, [exc_nest_count] - cmp r0, 0 - bne exc_handler_1 + brne r0, 0, exc_handler_1 /* change to exception stack if interrupt happened in task context */ mov sp, _e_stack exc_handler_1: @@ -127,13 +184,13 @@ ret_exc: mov r1, exc_nest_count ld r0, [r1] sub r0, r0, 1 - cmp r0, 0 - bne.d ret_exc_1 st r0, [r1] + brne r0, 0, ret_exc_1 /* nest exception case */ + lr r1, [AUX_IRQ_ACT] /* nest interrupt case */ + brne r1, 0, ret_exc_1 ld r0, [context_switch_reqflg] - cmp r0, 0 - bne ret_exc_2 + brne r0, 0, ret_exc_2 ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */ EXCEPTION_EPILOGUE rtie @@ -196,10 +253,20 @@ exc_entry_int: st r2, [exc_nest_count] seti /* enable higher priority interrupt */ - cmp r3, 0 - bne irq_handler_1 + brne r3, 0, irq_handler_1 /* change to exception stack if interrupt happened in task context */ mov sp, _e_stack +#if ARC_FEATURE_STACK_CHECK +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif irq_handler_1: PUSH blink @@ -228,13 +295,17 @@ ret_int: mov r1, exc_nest_count ld r0, [r1] sub r0, r0, 1 - cmp r0, 0 - bne.d ret_int_1 st r0, [r1] +/* if there are multi-bits set in IRQ_ACT, it's still in nest interrupt */ + lr r0, [AUX_IRQ_CAUSE] + sr r0, [AUX_IRQ_SELECT] + lr r3, [AUX_IRQ_PRIORITY] + lr r1, [AUX_IRQ_ACT] + bclr r2, r1, r3 + brne r2, 0, ret_int_1 ld r0, [context_switch_reqflg] - cmp r0, 0 - bne ret_int_2 + brne r0, 0, ret_int_2 ret_int_1: /* return from non-task context */ INTERRUPT_EPILOGUE rtie @@ -263,4 +334,31 @@ ret_int_r: /* recover AUX_IRQ_ACT to restore the interrup status */ POPAX AUX_IRQ_ACT INTERRUPT_EPILOGUE - rtie \ No newline at end of file + rtie + +/****** entry for fast irq exception handling ******/ + .global exc_entry_firq + .weak exc_entry_firq + .align 4 +exc_entry_firq: + SAVE_FIQ_EXC_REGS + + lr r0, [AUX_IRQ_CAUSE] + mov r1, exc_int_handler_table +/* r2 = _kernel_exc_tbl + irqno *4 */ + ld.as r2, [r1, r0] + +/* 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: +/* jump to interrupt handler */ + mov r0, sp + jl [r2] + +firq_return: + RESTORE_FIQ_EXC_REGS + rtie diff --git a/libcpu/arc/em/cpuport.c b/libcpu/arc/em/cpuport.c index 88c2e12f9b..34f538881f 100644 --- a/libcpu/arc/em/cpuport.c +++ b/libcpu/arc/em/cpuport.c @@ -5,11 +5,13 @@ */ #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)) +#include "arc/arc_exception.h" +#if ARC_FEATURE_STACK_CHECK +#define ARC_INIT_STATUS ((1 << AUX_STATUS_BIT_SC) | AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE) +#else +#define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE) +#endif extern void start_r(void); @@ -17,6 +19,7 @@ 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; +rt_uint32_t exc_nest_count; struct init_stack_frame { rt_uint32_t pc; @@ -66,4 +69,19 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) { exception_handle = exception_handle; -} \ No newline at end of file +} + +void set_hw_stack_check(rt_uint32_t *from, rt_uint32_t *to) +{ + struct rt_thread *rt_thread_to; + if (to != NULL) { + rt_thread_to = rt_container_of(to, struct rt_thread, sp); +#if ARC_FEATURE_SEC_PRESENT + arc_aux_write(AUX_S_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr)); + arc_aux_write(AUX_S_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size); +#else + arc_aux_write(AUX_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr)); + arc_aux_write(AUX_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size); +#endif + } +} -- GitLab