add synwit swm341 bsp (#6235)

华芯微特SWM341芯片的bsp支持包
* 修改dac.c函数名称错误
* delete swm320-lq100 bsp
* 修复sdio读写块的地址偏移问题
* add synwit swm341 bsp
* 修复gcc下启动文件错误
* 为测试用例添加说明
This commit is contained in:
woody 2022-08-14 10:29:05 +08:00 committed by GitHub
parent e4d6dd88c9
commit 0189987d91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
179 changed files with 82972 additions and 0 deletions

View File

@ -172,6 +172,7 @@ jobs:
- {RTT_BSP: "wch/arm/ch32f103c8-core", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "wch/arm/ch32f203r-evt", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "swm320", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "swm341", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "beaglebone", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "zynqmp-r5-axu4ev", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "frdm-k64f", RTT_TOOL_CHAIN: "sourcery-arm"}

702
bsp/swm341/.config Normal file
View File

@ -0,0 +1,702 @@
#
# Automatically generated file; DO NOT EDIT.
# RT-Thread Configuration
#
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=1000
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_HOOK_USING_FUNC_PTR=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=y
CONFIG_RT_TIMER_THREAD_PRIO=4
CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
#
# kservice optimization
#
# CONFIG_RT_KSERVICE_USING_STDLIB is not set
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
# CONFIG_RT_USING_TINY_FFS is not set
# CONFIG_RT_KPRINTF_USING_LONGLONG is not set
CONFIG_RT_DEBUG=y
CONFIG_RT_DEBUG_COLOR=y
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
# CONFIG_RT_DEBUG_IPC_CONFIG is not set
# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
# CONFIG_RT_DEBUG_MEM_CONFIG is not set
# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
# CONFIG_RT_USING_MEMPOOL is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
CONFIG_RT_USING_MEMHEAP=y
CONFIG_RT_MEMHEAP_FAST_MODE=y
# CONFIG_RT_MEMHEAP_BSET_MODE is not set
# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set
CONFIG_RT_USING_MEMHEAP_AS_HEAP=y
CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y
# CONFIG_RT_USING_SLAB_AS_HEAP is not set
# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
# CONFIG_RT_USING_HEAP_ISR is not set
CONFIG_RT_USING_HEAP=y
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
CONFIG_RT_VER_NUM=0x40101
CONFIG_ARCH_ARM=y
CONFIG_RT_USING_CPU_FFS=y
CONFIG_ARCH_ARM_CORTEX_M=y
CONFIG_ARCH_ARM_CORTEX_M33=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_PRIORITY=10
# CONFIG_RT_USING_LEGACY is not set
CONFIG_RT_USING_MSH=y
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_CMD_SIZE=80
CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_ARG_MAX=10
# CONFIG_RT_USING_DFS is not set
# CONFIG_RT_USING_FAL is not set
# CONFIG_RT_USING_LWP is not set
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_USING_SERIAL_V1=y
# CONFIG_RT_USING_SERIAL_V2 is not set
# CONFIG_RT_SERIAL_USING_DMA is not set
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC 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_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
# 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
#
# Using USB
#
# CONFIG_RT_USING_USB is not set
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
#
# C/C++ and POSIX layer
#
CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# POSIX (Portable Operating System Interface) layer
#
# CONFIG_RT_USING_POSIX_FS is not set
# CONFIG_RT_USING_POSIX_DELAY is not set
# CONFIG_RT_USING_POSIX_CLOCK is not set
# CONFIG_RT_USING_POSIX_TIMER is not set
# CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_USING_MODULE is not set
#
# Interprocess Communication (IPC)
#
# CONFIG_RT_USING_POSIX_PIPE is not set
# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
#
# Socket is in the 'Network' category
#
# CONFIG_RT_USING_CPLUSPLUS is not set
#
# Network
#
# CONFIG_RT_USING_SAL is not set
# CONFIG_RT_USING_NETDEV is not set
# CONFIG_RT_USING_LWIP is not set
# CONFIG_RT_USING_AT is not set
#
# Utilities
#
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
# CONFIG_RT_USING_VAR_EXPORT is not set
# CONFIG_RT_USING_RT_LINK is not set
# CONFIG_RT_USING_VBUS is not set
#
# RT-Thread Utestcases
#
# CONFIG_RT_USING_UTESTCASES is not set
#
# RT-Thread online packages
#
#
# IoT - internet of things
#
# CONFIG_PKG_USING_LWIP is not set
# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_UMQTT 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_KAWAII_MQTT is not set
# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_LIBMODBUS is not set
# CONFIG_PKG_USING_FREEMODBUS is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_CMUX is not set
# 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
# CONFIG_PKG_USING_ZB_COORDINATOR is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_EZ_IOT_OS is not set
# CONFIG_PKG_USING_IOTSHARP_SDK is not set
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER 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_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
# CONFIG_PKG_USING_AGILE_TELNET is not set
# CONFIG_PKG_USING_NMEALIB is not set
# CONFIG_PKG_USING_PDULIB is not set
# CONFIG_PKG_USING_BTSTACK is not set
# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
# CONFIG_PKG_USING_MAVLINK is not set
# CONFIG_PKG_USING_BSAL is not set
# CONFIG_PKG_USING_AGILE_MODBUS is not set
# CONFIG_PKG_USING_AGILE_FTP is not set
# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
# CONFIG_PKG_USING_RT_LINK_HW is not set
# CONFIG_PKG_USING_LORA_PKT_FWD is not set
# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
# CONFIG_PKG_USING_HM is not set
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_LIBSODIUM is not set
# CONFIG_PKG_USING_LIBHYDROGEN is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# CONFIG_PKG_USING_YD_CRYPTO is not set
#
# language packages
#
#
# JSON: JavaScript Object Notation, a lightweight data-interchange format
#
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_RAPIDJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
# CONFIG_PKG_USING_PARSON is not set
#
# XML: Extensible Markup Language
#
# CONFIG_PKG_USING_SIMPLE_XML is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_LUATOS_SOC is not set
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
# CONFIG_PKG_USING_PIKASCRIPT is not set
# CONFIG_PKG_USING_RTT_RUST is not set
#
# multimedia packages
#
#
# LVGL: powerful and easy-to-use embedded GUI library
#
# CONFIG_PKG_USING_LVGL is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
#
# u8g2: a monochrome graphic library
#
# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
# CONFIG_PKG_USING_U8G2 is not set
# 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
# CONFIG_PKG_USING_PDFGEN is not set
# CONFIG_PKG_USING_HELIX is not set
# CONFIG_PKG_USING_AZUREGUIX is not set
# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
# CONFIG_PKG_USING_NUEMWIN is not set
# CONFIG_PKG_USING_MP3PLAYER is not set
# CONFIG_PKG_USING_TINYJPEG is not set
# CONFIG_PKG_USING_UGUI is not set
#
# PainterEngine: A cross-platform graphics application framework written in C language
#
# CONFIG_PKG_USING_PAINTERENGINE is not set
# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
# CONFIG_PKG_USING_MCURSES is not set
# CONFIG_PKG_USING_TERMBOX is not set
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_GUIENGINE is not set
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR 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_MEMORYPERF 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
# CONFIG_PKG_USING_GPS_RMC is not set
# CONFIG_PKG_USING_URLENCODE is not set
# CONFIG_PKG_USING_UMCN is not set
# CONFIG_PKG_USING_LWRB2RTT is not set
# CONFIG_PKG_USING_CPU_USAGE is not set
# CONFIG_PKG_USING_GBK2UTF8 is not set
# CONFIG_PKG_USING_VCONSOLE is not set
# CONFIG_PKG_USING_KDB is not set
# CONFIG_PKG_USING_WAMR is not set
# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
# CONFIG_PKG_USING_LWLOG is not set
# CONFIG_PKG_USING_ANV_TRACE is not set
# CONFIG_PKG_USING_ANV_MEMLEAK is not set
# CONFIG_PKG_USING_ANV_TESTSUIT is not set
# CONFIG_PKG_USING_ANV_BENCH is not set
# CONFIG_PKG_USING_DEVMEM is not set
# CONFIG_PKG_USING_REGEX is not set
# CONFIG_PKG_USING_MEM_SANDBOX is not set
# CONFIG_PKG_USING_SOLAR_TERMS is not set
# CONFIG_PKG_USING_GAN_ZHI is not set
# CONFIG_PKG_USING_FDT is not set
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
#
# system packages
#
#
# enhanced kernel services
#
# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
#
# acceleration: Assembly language or algorithmic acceleration packages
#
# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
# CONFIG_PKG_USING_QFPLIB_M3 is not set
#
# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
#
# CONFIG_PKG_USING_CMSIS_5 is not set
# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
#
# Micrium: Micrium software products porting for RT-Thread
#
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
# CONFIG_PKG_USING_UC_CRC is not set
# CONFIG_PKG_USING_UC_CLK is not set
# CONFIG_PKG_USING_UC_COMMON is not set
# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_RTDUINO is not set
# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_PERF_COUNTER is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
# CONFIG_PKG_USING_DFS_JFFS2 is not set
# CONFIG_PKG_USING_DFS_UFFS is not set
# CONFIG_PKG_USING_LWEXT4 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_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
# CONFIG_PKG_USING_RAMDISK is not set
# CONFIG_PKG_USING_MININI is not set
# CONFIG_PKG_USING_QBOOT is not set
# CONFIG_PKG_USING_PPOOL is not set
# CONFIG_PKG_USING_OPENAMP is not set
# CONFIG_PKG_USING_LPM is not set
# CONFIG_PKG_USING_TLSF is not set
# CONFIG_PKG_USING_EVENT_RECORDER is not set
# CONFIG_PKG_USING_ARM_2D is not set
# CONFIG_PKG_USING_MCUBOOT is not set
# CONFIG_PKG_USING_TINYUSB is not set
# CONFIG_PKG_USING_CHERRYUSB is not set
# CONFIG_PKG_USING_KMULTI_RTIMER is not set
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
#
# peripheral libraries and drivers
#
# 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_SHT3X is not set
# CONFIG_PKG_USING_ADT74XX is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
# CONFIG_PKG_USING_ICM20608 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_LITTLED is not set
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
#
# Kendryte SDK
#
# CONFIG_PKG_USING_K210_SDK is not set
# CONFIG_PKG_USING_KENDRYTE_SDK is not set
# CONFIG_PKG_USING_INFRARED is not set
# CONFIG_PKG_USING_MULTI_INFRARED 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
# CONFIG_PKG_USING_WS2812B is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
# CONFIG_PKG_USING_MAX7219 is not set
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
# CONFIG_PKG_USING_CAN_YMODEM is not set
# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
# CONFIG_PKG_USING_QLED is not set
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_AGILE_CONSOLE is not set
# CONFIG_PKG_USING_LD3320 is not set
# CONFIG_PKG_USING_WK2124 is not set
# CONFIG_PKG_USING_LY68L6400 is not set
# CONFIG_PKG_USING_DM9051 is not set
# CONFIG_PKG_USING_SSD1306 is not set
# CONFIG_PKG_USING_QKEY is not set
# CONFIG_PKG_USING_RS485 is not set
# CONFIG_PKG_USING_RS232 is not set
# CONFIG_PKG_USING_NES is not set
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
# CONFIG_PKG_USING_VDEVICE is not set
# CONFIG_PKG_USING_SGM706 is not set
# CONFIG_PKG_USING_STM32WB55_SDK is not set
# CONFIG_PKG_USING_RDA58XX is not set
# CONFIG_PKG_USING_LIBNFC is not set
# CONFIG_PKG_USING_MFOC is not set
# CONFIG_PKG_USING_TMC51XX is not set
# CONFIG_PKG_USING_TCA9534 is not set
# CONFIG_PKG_USING_KOBUKI is not set
# CONFIG_PKG_USING_ROSSERIAL is not set
# CONFIG_PKG_USING_MICRO_ROS is not set
# CONFIG_PKG_USING_MCP23008 is not set
# CONFIG_PKG_USING_BLUETRUM_SDK is not set
# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
# CONFIG_PKG_USING_BL_MCU_SDK is not set
# CONFIG_PKG_USING_SOFT_SERIAL is not set
# CONFIG_PKG_USING_MB85RS16 is not set
# CONFIG_PKG_USING_CW2015 is not set
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
#
# AI packages
#
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_QUEST is not set
# CONFIG_PKG_USING_NAXOS is not set
#
# miscellaneous packages
#
#
# project laboratory
#
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
#
# entertainment: terminal games and other interesting software packages
#
# CONFIG_PKG_USING_CMATRIX is not set
# CONFIG_PKG_USING_SL is not set
# CONFIG_PKG_USING_CAL is not set
# CONFIG_PKG_USING_ACLOCK is not set
# CONFIG_PKG_USING_THREES is not set
# CONFIG_PKG_USING_2048 is not set
# CONFIG_PKG_USING_SNAKE is not set
# CONFIG_PKG_USING_TETRIS is not set
# CONFIG_PKG_USING_DONUT is not set
# CONFIG_PKG_USING_COWSAY is not set
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_LZMA 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_MINIZIP is not set
# CONFIG_PKG_USING_HEATSHRINK is not set
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
# CONFIG_PKG_USING_DESIGN_PATTERN is not set
# CONFIG_PKG_USING_CONTROLLER is not set
# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
# CONFIG_PKG_USING_MFBD is not set
# CONFIG_PKG_USING_SLCAN2RTT is not set
# CONFIG_PKG_USING_SOEM is not set
#
# Hardware Drivers Config
#
CONFIG_SOC_SWM341=y
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART=y
CONFIG_BSP_USING_UART0=y
# CONFIG_BSP_USING_UART1 is not set
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
CONFIG_BSP_USING_GPIO=y
# CONFIG_BSP_USING_ADC is not set
# CONFIG_BSP_USING_DAC is not set
# CONFIG_BSP_USING_CAN is not set
# CONFIG_BSP_USING_TIM is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_PWM is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_WDT is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set
# CONFIG_BSP_USING_SDIO is not set
# CONFIG_BSP_USING_SDRAM is not set
# CONFIG_BSP_USING_GT9147 is not set
# CONFIG_BSP_USING_RGB_LCD is not set
#
# Onboard Peripheral Drivers
#
#
# Offboard Peripheral Drivers
#

25
bsp/swm341/Kconfig Normal file
View File

@ -0,0 +1,25 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "drivers/Kconfig"
config SOC_SWM341
bool
select ARCH_ARM_CORTEX_M33
default y

156
bsp/swm341/README.md Normal file
View File

@ -0,0 +1,156 @@
# SWM341 BSP 说明
标签: SYNWIT、Cortex-M33、SWM341、国产MCU
---
## 简介
本文档为SWM341开发板提供的 BSP (板级支持包) 说明。
通过阅读快速上手章节开发者可以快速地上手该 BSP将 RT-Thread 运行在开发板上。
## 芯片介绍
- 内核
- 32位ARM® Cortex™-M33 内核
- 24位系统定时器
- 工作频率最高150MHz
- 硬件单周期乘法
- 集成嵌套向量中断控制器NVIC提供最多104个、8级可配置优先级的中断
- 通过SWD接口烧录
- 内置LDO
- 供电电压范围为2.0V至3.6V
- 片上SRAM存储器
- 64KB
- 片上FLASH存储器
- 512KB
- 支持用户定制ISP在系统编程更新用户程序
- 自带Cache
- SDRAMC模块
- 支持16Bit位宽的SDRAM
- 支持兼容PC133标准的SDRAM颗粒
- 支持2MB到32MB的外部SDRAM颗粒
- SFC模块
- 最大支持外置16MB大小的SPI NOR FLASH
- GPIO
- 多达7组共112个GPIO
- 每个IO均支持位带操作
- 灵活的中断配置
- 触发类型设置(边沿检测、电平检测)
- 触发电平设置(高电平、低电平)
- 触发边沿设置(上升沿、下降沿、双边沿)
- 串行接口
- 4路UART模块具有独立8字节FIFO
- 2路SPI模块具有8字节独立FIFO支持SPI、SSI协议支持Master/Slave模式
- 2路I2C模块支持7位、10位地址方式支持Master/Slave模式
- 2路CAN模块支持协议2.0A(11Bit标识符)和2.0B29Bit标识符
- 1路SDIO模块
- 1路USB OTG模块
- TFT-LCD驱动模块
- 支持SYNC接口和MPU接口的外部LCD扩展
- 支持最高分辨率1024*768实际分辨率可以配置
- RGB565和RGB888格式可选
- PWM控制模块
- 5组16位宽PWM发生器每组PWM支持4路PWM输出
- 提供新周期开始中断,高电平结束中断、刹车中断以及中心对称模式下的半周期中断
- 支持死区控制
- 支持硬件自动触发 ADC 采样
- 定时器模块
- 5路32位通用定时器
- 12路32位基本定时器
- 32位看门狗定时器溢出后可配置触发中断或复位芯片
- RTC模块
- 可自由设置日期(年、月、周、日)和时间(时、分、秒)
- 可自由设置闹钟(周、时、分、秒)
- 自动识别当前设置年份是否为闰年
- 支持RTC中断从Sleep模式下唤醒芯片
- DMA模块
- 4路DAM支持特定外设和存储器之间或存储器和存储器之间的数据搬运
- 模拟外设
- 2路12位高精度SAR ADC
- 1路12位高精度DAC
- 3路比较器
- 4路运算放大器
- 欠压检测BOD
- 支持欠压检测
- 支持欠压中断和复位选择
- 时钟源
- 20MHz/40MHz精度可达1%的片内时钟源
- 32K片内时钟源
- 232MHz片外晶振
芯片更多详细信息请参考[华芯微特技术支持](https://www.synwit.cn/)。
## 编译说明
本 BSP 为开发者提供 MDK5 工程。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。
双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
> 工程默认配置使用 Jlink 仿真器下载程序,在通过 Jlink 连接开发板到 PC 的基础上,点击下载按钮即可下载程序到开发板
推荐熟悉 RT_Thread 的用户使用[env工具](https://www.rt-thread.org/page/download.html)可以在console下进入到 `bsp/swm341` 目录中,运行以下命令:
`scons`
来编译这个板级支持包。如果编译正确无误会产生rtthread.elf、rtthread.bin文件。其中 rtthread.bin 可以烧写到设备中运行。
## 烧写及执行
### 硬件连接
- 使用 USB 数据线连接开发板到 PC注意需要下载安装串口驱动支持 CH340 芯片,使用 MDK5 需要安装 SWM341 相关的 pack
> USB 数据线用于串口通讯,同时供电
- 使用 Jlink 连接开发板到 PC (需要 Jlink 驱动)
将串口 0 引脚为:`[PM0/PM1]`和 USB 转串口模块 J8 相连串口配置方式为115200-N-8-1。
当使用 [env工具](https://www.rt-thread.org/page/download.html) 正确编译产生出rtthread.bin映像文件后可以使用 ISP 的方式来烧写到设备中。
**建议使用 keil 软件直接下载**。ISP 下载较复杂。
### 运行结果
如果编译 & 烧写无误当复位设备后会在串口上看到板子上的蓝色LED闪烁。串口打印RT-Thread的启动logo信息
```
\ | /
- RT - Thread Operating System
/ | \ 4.1.1 build May 13 2022 10:16:43
2006 - 2022 Copyright by RT-Thread team
msh >
```
## 外设支持
本 BSP 目前对外设的支持情况如下:
| **片上外设** | **支持情况** | **备注** |
| :---------- | :----------: | :---------------------------------------- |
| GPIO | 支持 | 共112个 |
| UART | 支持 | UART0/1/2/3 |
| ADC | 支持 | ADC0/1 |
| DAC | 支持 | DAC |
| CAN | 支持 | CAN0/1 |
| TIM | 支持 | TIM0/1/2/3/4,BTIM0/1/2/3/4/5/6/7/8/9/10/11 |
| I2C | 支持 | 软件 I2C0/1 |
| PWM | 支持 | PWM0/1/2/3/4 |
| RTC | 支持 | RTC |
| SPI | 支持 | SPI0/1 |
| WDT | 支持 | WDT |
| CRC/RNG | 支持 | CRC/RNG |
| SDIO | 支持 | SDIO |
| SDRAM | 支持 | SDRAM |
## 维护人信息
- [yanmowudi](https://github.com/yanmowudi)
- [邮箱](lik@synwit.cn)
## 参考资料
* [RT-Thread 文档中心](https://www.rt-thread.org/document/site/)
* [SWM341数据手册](https://www.synwit.cn/)

14
bsp/swm341/SConscript Normal file
View File

@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

41
bsp/swm341/SConstruct Normal file
View File

@ -0,0 +1,41 @@
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.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM in ['iccarm']:
env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map')
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,14 @@
from building import *
cwd = GetCurrentDir()
path = [cwd]
src = Glob('*.c') + Glob('*.cpp')
group = DefineGroup('Applications', src, depend = [''], CPPPATH = path)
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')

View File

@ -0,0 +1,16 @@
from building import *
import os
cwd = GetCurrentDir()
group = []
src = Glob('*.c')
CPPPATH = [cwd]
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
group = group + SConscript(os.path.join(d, 'SConscript'))
group = group + DefineGroup('LVGL-port', src, depend = ['BSP_USING_LVGL'], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-28 Rudy Lo The first version
*/
#ifndef LV_CONF_H
#define LV_CONF_H
#include <rtconfig.h>
#include "rgb_lcd_port.h"
#define LV_HOR_RES LCD_WIDTH
#define LV_VER_RES LCD_HEIGHT
#define LV_COLOR_DEPTH LCD_BITS_PER_PIXEL
#define LV_COLOR_16_SWAP 0
#define LV_USE_PERF_MONITOR 1
#define LV_USE_DEMO_WIDGETS 1
#define LV_USE_DEMO_BENCHMARK 0
#endif

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-01 Rudy Lo The first version
*/
#include <lvgl.h>
#include <rtthread.h>
#include "lv_conf.h"
#include "drv_rgb_lcd.h"
#define DRV_DEBUG
#define LOG_TAG "drv.lvgl"
#include <drv_log.h>
/*A static or global variable to store the buffers*/
static lv_disp_draw_buf_t disp_buf;
/*Descriptor of a display driver*/
static lv_disp_drv_t disp_drv;
static lv_color_t *lcdbuf_1;
static lv_color_t *lcdbuf_2;
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/* color_p is a buffer pointer; the buffer is provided by LVGL */
LCD->L[0].ADDR = (uint32_t)color_p;
LCD->CR |= (1 << LCD_CR_VBPRELOAD_Pos);
while(LCD->CR & LCD_CR_VBPRELOAD_Msk) __NOP();
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
void lv_port_disp_init(void)
{
struct swm_rgb_lcd_device *rgb_lcd;
rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
lcdbuf_1 = (lv_color_t *)rgb_lcd->lcd_info.framebuffer;
lcdbuf_2 = (lv_color_t *)rt_malloc_align(LCD_BUF_SIZE,4);
if(lcdbuf_2 == RT_NULL)
{
LOG_E("init lcd buffer failed!\n");
return;
}
/*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
lv_disp_draw_buf_init(&disp_buf, lcdbuf_1, lcdbuf_2, LV_HOR_RES * LV_VER_RES);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = LV_HOR_RES;
disp_drv.ver_res = LV_VER_RES;
/*Set a display buffer*/
disp_drv.draw_buf = &disp_buf;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Required for Example 3)*/
disp_drv.full_refresh = 1;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-01 Rudy Lo The first version
*/
#include <lvgl.h>
#include <stdbool.h>
#include <rtdevice.h>
#include <drv_gpio.h>
#include "gt9147.h"
#define TOUCH_DEVICE_NAME "gt9147" /* Touch device name */
#define TOUCH_DEVICE_I2C_BUS "i2c0" /* SCL -> PA1(1), SDA -> PA0(0) */
static rt_device_t ts; /* Touch device handle, Touchscreen */
static struct rt_touch_data *read_data;
static rt_int16_t last_x = 0;
static rt_int16_t last_y = 0;
static bool touchpad_is_pressed(void)
{
if (1 == rt_device_read(ts, 0, read_data, 1))
{
if ((read_data->event == RT_TOUCH_EVENT_DOWN) || (read_data->event == RT_TOUCH_EVENT_MOVE)) {
/* restore data */
last_x = read_data->x_coordinate;
last_y = read_data->y_coordinate;
// rt_kprintf("touch: x = %d, y = %d\n", last_x, last_y);
return true;
}
}
return false;
}
static void touchpad_get_xy(rt_int16_t *x, rt_int16_t *y)
{
*x = last_x;
*y = last_y;
}
static void touchpad_read(lv_indev_drv_t *indev, lv_indev_data_t *data)
{
/*`touchpad_is_pressed` and `touchpad_get_xy` needs to be implemented by you*/
if(touchpad_is_pressed()) {
data->state = LV_INDEV_STATE_PRESSED;
touchpad_get_xy(&data->point.x, &data->point.y);
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
rt_err_t rt_hw_gt9147_register(void)
{
struct rt_touch_config config;
rt_uint8_t rst;
rst = GT9147_RST_PIN;
config.dev_name = TOUCH_DEVICE_I2C_BUS;
config.irq_pin.pin = GT9147_IRQ_PIN;
config.irq_pin.mode = PIN_MODE_INPUT_PULLDOWN;
config.user_data = &rst;
rt_hw_gt9147_init(TOUCH_DEVICE_NAME, &config);
ts = rt_device_find(TOUCH_DEVICE_NAME);
if (!ts) {
return -RT_ERROR;
}
read_data = (struct rt_touch_data *)rt_calloc(1, sizeof(struct rt_touch_data));
if (!read_data) {
return -RT_ENOMEM;
}
if (!rt_device_open(ts, RT_DEVICE_FLAG_RDONLY)) {
struct rt_touch_info info;
rt_device_control(ts, RT_TOUCH_CTRL_GET_INFO, &info);
rt_kprintf("type :%d\n", info.type);
rt_kprintf("vendor :%s\n", info.vendor);
rt_kprintf("point_num :%d\n", info.point_num);
rt_kprintf("range_x :%d\n", info.range_x);
rt_kprintf("range_y :%d\n", info.range_y);
return RT_EOK;
} else {
rt_kprintf("open touch device failed.\n");
return -RT_ERROR;
}
}
lv_indev_t * touch_indev;
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv; /* Descriptor of a input device driver */
lv_indev_drv_init(&indev_drv); /* Basic initialization */
indev_drv.type = LV_INDEV_TYPE_POINTER; /* Touch pad is a pointer-like device */
indev_drv.read_cb = touchpad_read; /* Set your driver function */
/* Register the driver in LVGL and save the created input device object */
touch_indev = lv_indev_drv_register(&indev_drv);
/* Register touch device */
rt_hw_gt9147_register();
}

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-28 Rudy Lo The first version
*/
#include <lvgl.h>
void lv_user_gui_init(void)
{
extern void lv_demo_widgets(void);
lv_demo_widgets();
}

View File

@ -0,0 +1,867 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/***************************************************************
mmcsd_cmd.h中的ERASE重名
SWM341.h中 FMC_TpyeDef中ERASE寄存器为FMC_ERASE,
SWM341_flash.c中FLASH_Erase使用ERASE寄存器的位置
***************************************************************/
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#define LED_PIN GET_PIN(B,0)
int main(void)
{
int count = 1;
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
while (count++)
{
rt_pin_write(LED_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
return RT_EOK;
}
#ifdef BSP_USING_GPIO
#define KEY1_PIN GET_PIN(A,8)
void key1_cb(void *args)
{
rt_kprintf("key1 irq!\n");
}
static int pin_sample(int argc, char *argv[])
{
rt_pin_mode(KEY1_PIN, PIN_IRQ_MODE_FALLING);
rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING, key1_cb, RT_NULL);
rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);
return RT_EOK;
}
MSH_CMD_EXPORT(pin_sample, pin sample);
#endif
#ifdef BSP_USING_ADC
#define ADC_DEV_NAME "adc0"
#define ADC_DEV_CHANNEL 0
#define REFER_VOLTAGE 330
#define CONVERT_BITS (1 << 12)
static int adc_vol_sample(int argc, char *argv[])
{
rt_adc_device_t adc_dev;
rt_uint32_t value, vol;
rt_err_t ret = RT_EOK;
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
return RT_ERROR;
}
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is :%d,", value);
vol = value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
return ret;
}
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
#endif
#ifdef BSP_USING_DAC
#include <stdlib.h>
#define DAC_DEV_NAME "dac" /* DAC 设备名称 */
#define DAC_DEV_CHANNEL 0 /* DAC 通道 */
#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */
static int dac_vol_sample(int argc, char *argv[])
{
rt_dac_device_t dac_dev;
rt_uint32_t value, vol;
rt_err_t ret = RT_EOK;
/* 查找设备 */
dac_dev = (rt_dac_device_t)rt_device_find(DAC_DEV_NAME);
if (dac_dev == RT_NULL)
{
rt_kprintf("dac sample run failed! can't find %s device!\n", DAC_DEV_NAME);
return RT_ERROR;
}
/* 打开通道 */
ret = rt_dac_enable(dac_dev, DAC_DEV_CHANNEL);
/* 设置输出值 */
value = atoi(argv[1]);
rt_dac_write(dac_dev, DAC_DEV_CHANNEL, value);
rt_kprintf("the value is :%d \n", value);
/* 转换为对应电压值 */
vol = value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
rt_thread_mdelay(500);
/* 关闭通道 */
ret = rt_dac_disable(dac_dev, DAC_DEV_CHANNEL);
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(dac_vol_sample, dac voltage convert sample);
#endif
#ifdef BSP_USING_CAN
#define CAN_DEV_NAME "can0" /* CAN 设备名称 */
static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */
static rt_device_t can_dev; /* CAN 设备句柄 */
/* 接收数据回调函数 */
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
{
/* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void can_rx_thread(void *parameter)
{
int i;
rt_err_t res;
struct rt_can_msg rxmsg = {0};
/* 设置接收回调函数 */
rt_device_set_rx_indicate(can_dev, can_rx_call);
#ifdef RT_CAN_USING_HDR
struct rt_can_filter_item items[5] =
{
RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ffhdr 为 - 1设置默认过滤表 */
RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ffhdr 为 - 1 */
RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211hdr 为 - 1 */
RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486hdr 为 - 1 */
{0x555, 0, 0, 0, 0x7ff, 7,} /* std,match ID:0x555hdr 为 7指定设置 7 号过滤表 */
};
struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有 5 个过滤表 */
/* 设置硬件过滤表 */
res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
RT_ASSERT(res == RT_EOK);
#endif
while (1)
{
/* hdr 值为 - 1表示直接从 uselist 链表读取数据 */
rxmsg.hdr = -1;
/* 阻塞等待接收信号量 */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
/* 从 CAN 读取一帧数据 */
rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
/* 打印数据 ID 及内容 */
rt_kprintf("ID:%x", rxmsg.id);
for (i = 0; i < 8; i++)
{
rt_kprintf("%2x", rxmsg.data[i]);
}
rt_kprintf("\n");
}
}
int can_sample(int argc, char *argv[])
{
struct rt_can_msg msg = {0};
rt_err_t res;
rt_size_t size;
rt_thread_t thread;
char can_name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(can_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
}
/* 查找 CAN 设备 */
can_dev = rt_device_find(can_name);
if (!can_dev)
{
rt_kprintf("find %s failed!\n", can_name);
return RT_ERROR;
}
/* 初始化 CAN 接收信号量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 以中断接收及发送方式打开 CAN 设备 */
res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
RT_ASSERT(res == RT_EOK);
/* 创建数据接收线程 */
thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
rt_kprintf("create can_rx thread failed!\n");
}
msg.id = 0x78; /* ID 为 0x78 */
msg.ide = RT_CAN_STDID; /* 标准格式 */
msg.rtr = RT_CAN_DTR; /* 数据帧 */
msg.len = 8; /* 数据长度为 8 */
/* 待发送的 8 字节数据 */
msg.data[0] = 0x00;
msg.data[1] = 0x11;
msg.data[2] = 0x22;
msg.data[3] = 0x33;
msg.data[4] = 0x44;
msg.data[5] = 0x55;
msg.data[6] = 0x66;
msg.data[7] = 0x77;
/* 发送一帧 CAN 数据 */
size = rt_device_write(can_dev, 0, &msg, sizeof(msg));
if (size == 0)
{
rt_kprintf("can dev write data failed!\n");
}
return res;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(can_sample, can device sample);
#endif
#ifdef BSP_USING_TIM
#define HWTIMER_DEV_NAME "timer0"
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_kprintf("this is hwtimer timeout callback fucntion!\n");
rt_kprintf("tick is :%d !\n", rt_tick_get());
return 0;
}
static int hwtimer_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
rt_hwtimerval_t timeout_s;
rt_device_t hw_dev = RT_NULL;
rt_hwtimer_mode_t mode;
hw_dev = rt_device_find(HWTIMER_DEV_NAME);
if (hw_dev == RT_NULL)
{
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);
return RT_ERROR;
}
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
if (ret != RT_EOK)
{
rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME);
return ret;
}
rt_device_set_rx_indicate(hw_dev, timeout_cb);
mode = HWTIMER_MODE_PERIOD;
//mode = HWTIMER_MODE_ONESHOT;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
rt_kprintf("set mode failed! ret is :%d\n", ret);
return ret;
}
timeout_s.sec = 2;
timeout_s.usec = 0;
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
{
rt_kprintf("set timeout value failed\n");
return RT_ERROR;
}
rt_thread_mdelay(3500);
rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec);
return ret;
}
MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample);
#endif
#ifdef BSP_USING_PWM
#define PWM_DEV_NAME "pwm0" /* PWM设备名称 */
#define PWM_DEV_CHANNEL 0 /* PWM通道 */
struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */
static int pwm_sample(int argc, char *argv[])
{
rt_uint32_t period, pulse;
period = 500000; /* 周期为0.5ms单位为纳秒ns */
pulse = 100000; /* PWM脉冲宽度值单位为纳秒ns */
pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
if (pwm_dev == RT_NULL)
{
rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
return RT_ERROR;
}
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
return RT_EOK;
}
MSH_CMD_EXPORT(pwm_sample, pwm sample);
#endif
#ifdef RT_USING_RTC
#include "sys/time.h"
static int rtc_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
time_t now;
ret = set_date(2021, 7, 6);
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
ret = set_time(11, 15, 50);
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
rt_thread_mdelay(3000);
now = time(RT_NULL);
rt_kprintf("%s\n", ctime(&now));
return ret;
}
MSH_CMD_EXPORT(rtc_sample, rtc sample);
#endif
#ifdef RT_USING_WDT
#define WDT_DEVICE_NAME "wdt"
static rt_device_t wdg_dev;
static void idle_hook(void)
{
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, RT_NULL);
rt_kprintf("feed the dog!\n ");
}
static int wdt_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
rt_uint32_t timeout = 5;
char device_name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(device_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);
}
wdg_dev = rt_device_find(device_name);
if (!wdg_dev)
{
rt_kprintf("find %s failed!\n", device_name);
return RT_ERROR;
}
ret = rt_device_init(wdg_dev);
if (ret != RT_EOK)
{
rt_kprintf("initialize %s failed!\n", device_name);
return RT_ERROR;
}
ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
if (ret != RT_EOK)
{
rt_kprintf("set %s timeout failed!\n", device_name);
return RT_ERROR;
}
ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
if (ret != RT_EOK)
{
rt_kprintf("start %s failed!\n", device_name);
return -RT_ERROR;
}
// rt_thread_idle_sethook(idle_hook);
return ret;
}
MSH_CMD_EXPORT(wdt_sample, wdt sample);
#endif
#ifdef RT_USING_SPI
#define W25Q_SPI_DEVICE_NAME "spi00"
#define W25Q_FLASH_NAME "norflash0"
#include "drv_spi.h"
#ifdef RT_USING_SFUD
#include "spi_flash_sfud.h"
static int rt_hw_spi_flash_init(void)
{
rt_hw_spi_device_attach("spi0", "spi00", GPIOM, PIN3);
if (RT_NULL == rt_sfud_flash_probe(W25Q_FLASH_NAME, W25Q_SPI_DEVICE_NAME))
{
return -RT_ERROR;
};
return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
static void spi_w25q_sample(int argc, char *argv[])
{
struct rt_spi_device *spi_dev_w25q;
char name[RT_NAME_MAX];
rt_uint8_t w25x_read_id = 0x90;
rt_uint8_t id[5] = {0};
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
}
/* 查找 spi 设备获取设备句柄 */
spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
if (!spi_dev_w25q)
{
rt_kprintf("spi sample run failed! can't find %s device!\n", name);
}
else
{
/* 方式1使用 rt_spi_send_then_recv()发送命令读取ID */
rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);
/* 方式2使用 rt_spi_transfer_message()发送命令读取ID */
struct rt_spi_message msg1, msg2;
msg1.send_buf = &w25x_read_id;
msg1.recv_buf = RT_NULL;
msg1.length = 1;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = RT_NULL;
msg2.recv_buf = id;
msg2.length = 5;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(spi_dev_w25q, &msg1);
rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample);
#ifdef RT_USING_DFS_ELMFAT
#include <dfs_file.h>
#include <unistd.h>
static void elmfat_sample(void)
{
int fd, size;
struct statfs elm_stat;
char str[] = "elmfat mount to W25Q flash.\r\n", buf[80];
if (dfs_mkfs("elm", W25Q_FLASH_NAME) == 0)
rt_kprintf("make elmfat filesystem success.\n");
if (dfs_mount(W25Q_FLASH_NAME, "/", "elm", 0, 0) == 0)
rt_kprintf("elmfat filesystem mount success.\n");
if (statfs("/", &elm_stat) == 0)
rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n",
elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);
if (mkdir("/user", 0x777) == 0)
rt_kprintf("make a directory: '/user'.\n");
rt_kprintf("Write string '%s' to /user/test.txt.\n", str);
fd = open("/user/test.txt", O_WRONLY | O_CREAT);
if (fd >= 0)
{
if (write(fd, str, sizeof(str)) == sizeof(str))
rt_kprintf("Write data done.\n");
close(fd);
}
fd = open("/user/test.txt", O_RDONLY);
if (fd >= 0)
{
size = read(fd, buf, sizeof(buf));
close(fd);
if (size == sizeof(str))
rt_kprintf("Read data from file test.txt(size: %d): %s \n", size, buf);
}
}
MSH_CMD_EXPORT(elmfat_sample, elmfat sample);
#endif
#endif
#endif
#ifdef RT_USING_SPI
#ifdef RT_USING_SPI_MSD
#define SD_SPI_DEVICE_NAME "spi00"
#define SDCARD_NAME "sd0"
#include "drv_spi.h"
#include "spi_msd.h"
#include <dfs_file.h>
#include <unistd.h>
static int rt_hw_spi0_tfcard(void)
{
rt_hw_spi_device_attach("spi0", SD_SPI_DEVICE_NAME, GPION, PIN1);
return msd_init(SDCARD_NAME, SD_SPI_DEVICE_NAME);
}
INIT_DEVICE_EXPORT(rt_hw_spi0_tfcard);
static void elmfat_sample(void)
{
int fd, size;
struct statfs elm_stat;
char str[] = "elmfat mount to sdcard.\r\n", buf[80];
if (dfs_mkfs("elm", SDCARD_NAME) == 0)
rt_kprintf("make elmfat filesystem success.\n");
if (dfs_mount(SDCARD_NAME, "/", "elm", 0, 0) == 0)
rt_kprintf("elmfat filesystem mount success.\n");
if (statfs("/", &elm_stat) == 0)
rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n",
elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);
if (mkdir("/user", 0x777) == 0)
rt_kprintf("make a directory: '/user'.\n");
rt_kprintf("Write string '%s' to /user/test.txt.\n", str);
fd = open("/user/test.txt", O_WRONLY | O_CREAT);
if (fd >= 0)
{
if (write(fd, str, sizeof(str)) == sizeof(str))
rt_kprintf("Write data done.\n");
close(fd);
}
fd = open("/user/test.txt", O_RDONLY);
if (fd >= 0)
{
size = read(fd, buf, sizeof(buf));
close(fd);
if (size == sizeof(str))
rt_kprintf("Read data from file test.txt(size: %d): %s \n", size, buf);
}
}
MSH_CMD_EXPORT(elmfat_sample, elmfat sample);
#endif
#endif
#ifdef RT_USING_SDIO
#define SDCARD_NAME "sd0"
#include <dfs_file.h>
#include <unistd.h>
static void elmfat_sample(void)
{
int fd, size;
struct statfs elm_stat;
char str[] = "elmfat mount to sdcard.\n", buf[80];
if (dfs_mkfs("elm", SDCARD_NAME) == 0)
rt_kprintf("make elmfat filesystem success.\n");
if (dfs_mount(SDCARD_NAME, "/", "elm", 0, 0) == 0)
rt_kprintf("elmfat filesystem mount success.\n");
if (statfs("/", &elm_stat) == 0)
rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n",
elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);
if (mkdir("/user", 0x777) == 0)
rt_kprintf("make a directory: '/user'.\n");
rt_kprintf("Write string '%s' to /user/test.txt.\n", str);
fd = open("/user/test.txt", O_WRONLY | O_CREAT);
if (fd >= 0)
{
if (write(fd, str, sizeof(str)) == sizeof(str))
rt_kprintf("Write data done.\n");
close(fd);
}
fd = open("/user/test.txt", O_RDONLY);
if (fd >= 0)
{
size = read(fd, buf, sizeof(buf));
close(fd);
if (size == sizeof(str))
rt_kprintf("Read data from file test.txt(size: %d): %s \n", size, buf);
}
}
MSH_CMD_EXPORT(elmfat_sample, elmfat sample);
#endif
#ifdef RT_USING_HWCRYPTO
static void crypto_sample(void)
{
#ifdef BSP_USING_CRC
rt_uint8_t temp[] = {0, 1, 2, 3, 4, 5, 6, 7};
struct rt_hwcrypto_ctx *ctx;
rt_uint32_t result = 0;
struct hwcrypto_crc_cfg cfg =
{
.last_val = 0x00000000,
.poly = 0x04C11DB7,
.width = 8,
.xorout = 0x00000000, //不支持XOR
.flags = 0,
};
ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
rt_hwcrypto_crc_cfg(ctx, &cfg);
result = rt_hwcrypto_crc_update(ctx, temp, sizeof(temp));
rt_kprintf("result: 0x%08x \n", result);
rt_hwcrypto_crc_destroy(ctx);
#endif /* BSP_USING_CRC */
#ifdef BSP_USING_RNG
rt_uint32_t rng_result = 0;
int i;
for (i = 0; i < 20; i++)
{
rng_result = rt_hwcrypto_rng_update();
rt_kprintf("rng:0x%08x.\n", rng_result);
}
#endif /* BSP_USING_RNG */
}
MSH_CMD_EXPORT(crypto_sample, crypto sample);
#endif
#ifdef BSP_USING_SDRAM
#include <rtthread.h>
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
/* 线程入口 */
void thread1_entry(void *parameter)
{
int i;
char *ptr = RT_NULL; /* 内存块的指针 */
for (i = 0;; i++)
{
/* 每次分配 (1 << i) 大小字节数的内存空间 */
ptr = rt_malloc(1 << i);
/* 如果分配成功 */
if (ptr != RT_NULL)
{
rt_kprintf("get memory :%d byte\n", (1 << i));
/* 释放内存块 */
rt_free(ptr);
rt_kprintf("free memory :%d byte\n", (1 << i));
ptr = RT_NULL;
}
else
{
rt_kprintf("try to get %d byte memory failed!\n", (1 << i));
return;
}
}
}
int dynmem_sample(void)
{
rt_thread_t tid = RT_NULL;
/* 创建线程 1 */
tid = rt_thread_create("thread1",
thread1_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY,
THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(dynmem_sample, dynmem sample);
#endif
#ifdef RT_USING_TOUCH
#include "gt9147.h"
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
int rt_hw_gt9147_port(void)
{
struct rt_touch_config config;
rt_uint8_t rst;
rst = GT9147_RST_PIN;
config.dev_name = "i2c0";
config.irq_pin.pin = GT9147_IRQ_PIN;
config.irq_pin.mode = PIN_MODE_INPUT_PULLDOWN;
config.user_data = &rst;
rt_hw_gt9147_init("gt9147", &config);
return 0;
}
INIT_ENV_EXPORT(rt_hw_gt9147_port);
static rt_thread_t gt9147_thread = RT_NULL;
static rt_sem_t gt9147_sem = RT_NULL;
static rt_device_t dev = RT_NULL;
static struct rt_touch_data *read_data;
/* 读取数据线程入口函数 */
static void gt9147_entry(void *parameter)
{
struct rt_touch_data *read_data;
read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * 5);
while (1)
{
/* 请求信号量 */
rt_sem_take(gt9147_sem, RT_WAITING_FOREVER);
/* 读取五个点的触摸信息 */
if (rt_device_read(dev, 0, read_data, 5) == 5)
{
for (rt_uint8_t i = 0; i < 5; i++)
{
if (read_data[i].event == RT_TOUCH_EVENT_DOWN || read_data[i].event == RT_TOUCH_EVENT_MOVE)
{
rt_kprintf("%d %d %d %d %d\n",
read_data[i].track_id,
read_data[i].x_coordinate,
read_data[i].y_coordinate,
read_data[i].timestamp,
read_data[i].width);
}
}
}
/* 打开中断 */
rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL);
}
}
/* 接收回调函数 */
static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
{
/* 关闭中断 */
rt_device_control(dev, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL);
/* 释放信号量 */
rt_sem_release(gt9147_sem);
return 0;
}
static int gt9147_sample(void)
{
/* 查找 Touch 设备 */
dev = rt_device_find("gt9147");
if (dev == RT_NULL)
{
rt_kprintf("can't find device:%s\n", "touch");
return -1;
}
/* 以中断的方式打开设备 */
if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
{
rt_kprintf("open device failed!");
return -1;
}
/* 设置接收回调 */
rt_device_set_rx_indicate(dev, rx_callback);
/* 创建信号量 */
gt9147_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
if (gt9147_sem == RT_NULL)
{
rt_kprintf("create dynamic semaphore failed.\n");
return -1;
}
/* 创建读取数据线程 */
gt9147_thread = rt_thread_create("thread1",
gt9147_entry,
RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY,
THREAD_TIMESLICE);
/* 启动线程 */
if (gt9147_thread != RT_NULL)
rt_thread_startup(gt9147_thread);
return 0;
}
MSH_CMD_EXPORT(gt9147_sample, gt9147 sample);
#endif

View File

@ -0,0 +1,42 @@
#
# Automatically generated file; DO NOT EDIT.
# RootMenu
#
#
# Hardware Drivers Config
#
CONFIG_SOC_SWM341=y
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART=y
CONFIG_BSP_USING_UART0=y
# CONFIG_BSP_USING_UART1 is not set
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
CONFIG_BSP_USING_GPIO=y
# CONFIG_BSP_USING_ADC is not set
# CONFIG_BSP_USING_DAC is not set
# CONFIG_BSP_USING_CAN is not set
# CONFIG_BSP_USING_TIM is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_PWM is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_WDT is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set
# CONFIG_BSP_USING_SDIO is not set
# CONFIG_BSP_USING_SDRAM is not set
# CONFIG_BSP_USING_GT9147 is not set
# CONFIG_BSP_USING_RGB_LCD is not set
#
# Onboard Peripheral Drivers
#
#
# Offboard Peripheral Drivers
#

406
bsp/swm341/drivers/Kconfig Normal file
View File

@ -0,0 +1,406 @@
menu "Hardware Drivers Config"
config SOC_SWM341
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
menu "On-chip Peripheral Drivers"
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART0
bool "Enable UART0 (M0/RX,M1/TX)"
default y
config BSP_USING_UART1
bool "Enable UART1 (D4/RX,D3/TX)"
default n
config BSP_USING_UART2
bool "Enable UART2 (C1/RX,C0/TX)"
default n
config BSP_USING_UART3
bool "Enable UART3 (C2/RX,C3/TX)"
default n
endif
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
menuconfig BSP_USING_ADC
bool "Enable ADC"
default n
select RT_USING_ADC
if BSP_USING_ADC
config BSP_USING_ADC0
bool "Enable ADC0"
default n
if BSP_USING_ADC0
config BSP_USING_ADC0_CHN0
bool "Enable ADC0_CHN0(C6)"
default n
config BSP_USING_ADC0_CHN1
bool "Enable ADC0_CHN1(C5)"
default n
config BSP_USING_ADC0_CHN2
bool "Enable ADC0_CHN2(C4)"
default n
config BSP_USING_ADC0_CHN3
bool "Enable ADC0_CHN3(C3)"
default n
config BSP_USING_ADC0_CHN4
bool "Enable ADC0_CHN4(C2)"
default n
config BSP_USING_ADC0_CHN5
bool "Enable ADC0_CHN5(C1)"
default n
config BSP_USING_ADC0_CHN6
bool "Enable ADC0_CHN6(C0)"
default n
config BSP_USING_ADC0_CHN7
bool "Enable ADC0_CHN7(A15)"
default n
config BSP_USING_ADC0_CHN8
bool "Enable ADC0_CHN8(A14)"
default n
config BSP_USING_ADC0_CHN9
bool "Enable ADC0_CHN9(A13)"
default n
config BSP_USING_ADC0_CHN10
bool "Enable ADC0_CHN10(A12)"
default n
config BSP_USING_ADC0_CHN11
bool "Enable ADC0_CHN11(A10)"
default n
endif
config BSP_USING_ADC1
bool "Enable ADC1"
default n
if BSP_USING_ADC1
config BSP_USING_ADC1_CHN0
bool "Enable ADC1_CHN0(D1)"
default n
config BSP_USING_ADC1_CHN1
bool "Enable ADC1_CHN1(D0)"
default n
config BSP_USING_ADC1_CHN2
bool "Enable ADC1_CHN2(C13)"
default n
config BSP_USING_ADC1_CHN3
bool "Enable ADC1_CHN3(C12)"
default n
config BSP_USING_ADC1_CHN4
bool "Enable ADC1_CHN4(C11)"
default n
config BSP_USING_ADC1_CHN5
bool "Enable ADC1_CHN5(C10)"
default n
config BSP_USING_ADC1_CHN6
bool "Enable ADC1_CHN6(C9)"
default n
endif
endif
config BSP_USING_DAC
bool "Enable DAC"
select RT_USING_DAC
default n
menuconfig BSP_USING_CAN
bool "Enable CAN"
default n
select RT_USING_CAN
if BSP_USING_CAN
config BSP_USING_CAN0
bool "Enable CAN0(TX/B4,RX/B5)"
default n
config BSP_USING_CAN1
bool "Enable CAN1(TX/B2,RX/B3)"
default n
endif
menuconfig BSP_USING_TIM
bool "Enable HWTIMER"
default n
select RT_USING_HWTIMER
if BSP_USING_TIM
config BSP_USING_TIM0
bool "Enable TIM0"
default n
config BSP_USING_TIM1
bool "Enable TIM1"
default n
config BSP_USING_TIM2
bool "Enable TIM2"
default n
config BSP_USING_TIM3
bool "Enable TIM3"
default n
config BSP_USING_TIM4
bool "Enable TIM4"
default n
config BSP_USING_BTIM0
bool "Enable BTIM0"
default n
config BSP_USING_BTIM1
bool "Enable BTIM1"
default n
config BSP_USING_BTIM2
bool "Enable BTIM2"
default n
config BSP_USING_BTIM3
bool "Enable BTIM3"
default n
config BSP_USING_BTIM4
bool "Enable BTIM4"
default n
config BSP_USING_BTIM5
bool "Enable BTIM5"
default n
config BSP_USING_BTIM6
bool "Enable BTIM6"
default n
config BSP_USING_BTIM7
bool "Enable BTIM7"
default n
config BSP_USING_BTIM8
bool "Enable BTIM8"
default n
config BSP_USING_BTIM9
bool "Enable BTIM9"
default n
config BSP_USING_BTIM10
bool "Enable BTIM10"
default n
config BSP_USING_BTIM11
bool "Enable BTIM11"
default n
endif
menuconfig BSP_USING_I2C
bool "Enable I2C BUS (software simulation)"
default n
select RT_USING_I2C
select RT_USING_I2C_BITOPS
select RT_USING_PIN
if BSP_USING_I2C
config BSP_USING_I2C0
bool "Enable I2C0"
default n
if BSP_USING_I2C0
config BSP_I2C0_SCL_PIN
int "I2C0 scl pin number"
range 0 111
default 1
config BSP_I2C0_SDA_PIN
int "I2C0 sda pin number"
range 0 111
default 0
endif
config BSP_USING_I2C1
bool "Enable I2C1"
default n
if BSP_USING_I2C1
config BSP_I2C1_SCL_PIN
int "I2C1 scl pin number"
range 0 111
default 37
config BSP_I2C1_SDA_PIN
int "I2C1 sda pin number"
range 0 111
default 36
endif
endif
menuconfig BSP_USING_PWM
bool "Enable PWM"
default n
select RT_USING_PWM
if BSP_USING_PWM
comment "Notice: PWMA,PWMAN,PWMB,PWMBN are all channel0,the performance is the same"
config BSP_USING_PWM0
bool "Enable PWM0"
default n
if BSP_USING_PWM0
config BSP_USING_PWM0A
bool "Enable PWM0A (M1)"
default n
config BSP_USING_PWM0AN
bool "Enable PWM0AN (M4)"
default n
config BSP_USING_PWM0B
bool "Enable PWM0B (M2)"
default n
config BSP_USING_PWM0BN
bool "Enable PWM0BN (M5)"
default n
endif
config BSP_USING_PWM1
bool "Enable PWM1"
default n
if BSP_USING_PWM1
config BSP_USING_PWM1A
bool "Enable PWM1A (M3)"
default n
config BSP_USING_PWM1AN
bool "Enable PWM1AN (M6)"
default n
config BSP_USING_PWM1B
bool "Enable PWM1B (D9)"
default n
config BSP_USING_PWM1BN
bool "Enable PWM1BN (D8)"
default n
endif
config BSP_USING_PWM2
bool "Enable PWM2"
default n
if BSP_USING_PWM2
config BSP_USING_PWM2A
bool "Enable PWM2A (M12)"
default n
config BSP_USING_PWM2AN
bool "Enable PWM2AN (M9)"
default n
config BSP_USING_PWM2B
bool "Enable PWM2B (M11)"
default n
config BSP_USING_PWM2BN
bool "Enable PWM2BN (M8)"
default n
endif
config BSP_USING_PWM3
bool "Enable PWM3"
default n
if BSP_USING_PWM3
config BSP_USING_PWM3A
bool "Enable PWM3A (C2)"
default n
config BSP_USING_PWM3AN
bool "Enable PWM3AN (C3)"
default n
config BSP_USING_PWM3B
bool "Enable PWM3B (B1)"
default n
config BSP_USING_PWM3BN
bool "Enable PWM3BN (B0)"
default n
endif
config BSP_USING_PWM4
bool "Enable PWM4"
default n
if BSP_USING_PWM4
config BSP_USING_PWM4A
bool "Enable PWM4A (B15)"
default n
config BSP_USING_PWM4AN
bool "Enable PWM4AN (B14) NOTICE:SWDIO"
default n
config BSP_USING_PWM4B
bool "Enable PWM4B (B13)"
default n
config BSP_USING_PWM4BN
bool "Enable PWM4BN (B12) NOTICE:SWDCK"
default n
endif
endif
config BSP_USING_RTC
bool "Enable RTC"
select RT_USING_RTC
select RT_USING_LIBC
default n
menuconfig BSP_USING_SPI
bool "Enable SPI BUS"
default n
select RT_USING_SPI
if BSP_USING_SPI
config BSP_USING_SPI0
bool "Enable SPI0 BUS(CS/M3,MISO/M4,MOSI/M5,CLK/M2)"
default n
config BSP_USING_SPI1
bool "Enable SPI1 BUS(CS/B5,MISO/B3,MOSI/B4,CLK/B2)"
default n
endif
config BSP_USING_WDT
bool "Enable Watchdog Timer"
select RT_USING_WDT
default n
config BSP_USING_CRC
bool "Enable CRC"
select RT_USING_HWCRYPTO
select RT_HWCRYPTO_USING_CRC
default n
config BSP_USING_RNG
bool "Enable RNG (Random Number Generator)"
select RT_USING_HWCRYPTO
select RT_HWCRYPTO_USING_RNG
default n
config BSP_USING_SDIO
bool "Enable SDCARD (sdio)"
select RT_USING_SDIO
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
default n
menuconfig BSP_USING_SDRAM
bool "Enable SDRAM"
select RT_USING_MEMHEAP
select RT_USING_MEMHEAP_AS_HEAP
select RT_USING_MEMHEAP_AUTO_BINDING
default n
if BSP_USING_SDRAM
config BSP_SDRAM_SIZE
hex "SDRAM size"
default 0x800000
endif
menuconfig BSP_USING_GT9147
bool "Enable gt9147(use i2c0)"
select RT_USING_TOUCH
select RT_TOUCH_PIN_IRQ
select BSP_USING_I2C
select BSP_USING_I2C0
default n
if BSP_USING_GT9147
config GT9147_RST_PIN
int "GT9147 rst pin number"
range 0 111
default 39
config GT9147_IRQ_PIN
int "GT9147 irq pin number"
range 0 111
default 48
endif
menuconfig BSP_USING_RGB_LCD
bool "Enable RGB LCD"
select BSP_USING_SDRAM
default n
if BSP_USING_RGB_LCD
config BSP_USING_LVGL
bool "Enable LVGL for LCD"
select PKG_USING_LVGL
default n
endif
endmenu
menu "Onboard Peripheral Drivers"
endmenu
menu "Offboard Peripheral Drivers"
endmenu
endmenu

View File

@ -0,0 +1,58 @@
from building import *
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = Split('''
board.c
''')
if GetDepend(['RT_USING_SERIAL']):
src += ['drv_uart.c']
if GetDepend(['RT_USING_PIN']):
src += ['drv_gpio.c']
if GetDepend(['RT_USING_ADC']):
src += ['drv_adc.c']
if GetDepend(['RT_USING_DAC']):
src += ['drv_dac.c']
if GetDepend(['RT_USING_CAN']):
src += ['drv_can.c']
if GetDepend(['RT_USING_HWTIMER']):
src += ['drv_hwtimer.c']
if GetDepend(['RT_USING_I2C']):
src += ['drv_soft_i2c.c']
if GetDepend(['RT_USING_PWM']):
src += ['drv_pwm.c']
if GetDepend(['RT_USING_RTC']):
src += ['drv_rtc.c']
if GetDepend(['RT_USING_SPI']):
src += ['drv_spi.c']
if GetDepend(['RT_USING_WDT']):
src += ['drv_wdt.c']
if GetDepend(['RT_USING_HWCRYPTO']):
src += ['drv_crypto.c']
if GetDepend(['RT_USING_SDIO']):
src += ['drv_sdio.c']
if GetDepend(['BSP_USING_SDRAM']):
src += ['drv_sdram.c']
if GetDepend(['BSP_USING_RGB_LCD']):
src += ['drv_rgb_lcd.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "board.h"
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap system_heap;
#endif
static void bsp_clock_config(void)
{
SystemInit();
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
SysTick->CTRL |= 0x00000004UL;
}
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
void rt_hw_board_init()
{
bsp_clock_config();
/* Heap initialization */
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
#if defined(BSP_USING_SDRAM) && defined(RT_USING_MEMHEAP_AS_HEAP)
swm_sdram_init();
/* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
rt_memheap_init(&system_heap, "sdram", (void *)SDRAMM_BASE, BSP_SDRAM_SIZE);
#endif
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
swm_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
swm_uart_init();
#endif
/* Set the shell console output device */
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <string.h>
#include <SWM341.h>
#include "drv_gpio.h"
#include "drv_uart.h"
#include "drv_sdram.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define SRAM_BASE 0x20000000
#define SRAM_SIZE 0x10000
#define SRAM_END (SRAM_BASE + SRAM_SIZE)
#if defined(__ARMCC_VERSION)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section = "HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
#define HEAP_END SRAM_END
#define HEAP_SIZE (HEAP_END - (rt_uint32_t)HEAP_BEGIN)
extern void FPU_init(void);
void rt_hw_board_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_adc.h"
#ifdef RT_USING_ADC
#ifdef BSP_USING_ADC
//#define DRV_DEBUG
#define LOG_TAG "drv.adc"
#include <drv_log.h>
#if !defined(BSP_USING_ADC0) && !defined(BSP_USING_ADC1)
#error "Please define at least one BSP_USING_ADCx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_ADC0
#ifndef ADC0_CFG
#define ADC0_CFG \
{ \
.name = "adc0", \
.ADCx = ADC0, \
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
.ADC_initstruct.EOC_IEn = 0, \
.ADC_initstruct.HalfIEn = 0, \
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
.ADC_SEQ_initstruct.conv_cnt = 1, \
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
}
#endif /* ADC0_CFG */
#endif /* BSP_USING_ADC0 */
#ifdef BSP_USING_ADC1
#ifndef ADC1_CFG
#define ADC1_CFG \
{ \
.name = "adc1", \
.ADCx = ADC1, \
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
.ADC_initstruct.EOC_IEn = 0, \
.ADC_initstruct.HalfIEn = 0, \
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
.ADC_SEQ_initstruct.conv_cnt = 1, \
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
}
#endif /* ADC1_CFG */
#endif /* BSP_USING_ADC1 */
struct swm_adc_cfg
{
const char *name;
ADC_TypeDef *ADCx;
ADC_InitStructure ADC_initstruct;
ADC_SEQ_InitStructure ADC_SEQ_initstruct;
};
struct swm_adc_device
{
struct swm_adc_cfg *adc_cfg;
struct rt_adc_device adc_device;
};
static struct swm_adc_cfg swm_adc_cfg[] =
{
#ifdef BSP_USING_ADC0
ADC0_CFG,
#endif
#ifdef BSP_USING_ADC1
ADC1_CFG,
#endif
};
static struct swm_adc_device adc_obj[sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0])];
static rt_uint32_t swm_adc_get_channel(rt_uint32_t channel)
{
rt_uint32_t swm_channel = 0;
switch (channel)
{
case 0:
swm_channel = ADC_CH0;
break;
case 1:
swm_channel = ADC_CH1;
break;
case 2:
swm_channel = ADC_CH2;
break;
case 3:
swm_channel = ADC_CH3;
break;
case 4:
swm_channel = ADC_CH4;
break;
case 5:
swm_channel = ADC_CH5;
break;
case 6:
swm_channel = ADC_CH6;
break;
case 7:
swm_channel = ADC_CH7;
break;
case 8:
swm_channel = ADC_CH8;
break;
case 9:
swm_channel = ADC_CH9;
break;
case 10:
swm_channel = ADC_CH10;
break;
case 11:
swm_channel = ADC_CH11;
break;
}
return swm_channel;
}
static rt_err_t swm_adc_enabled(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_bool_t enabled)
{
uint32_t adc_chn;
struct swm_adc_cfg *adc_cfg;
RT_ASSERT(adc_device != RT_NULL);
adc_cfg = adc_device->parent.user_data;
if (channel < 12)
{
/* set swm ADC channel */
adc_chn = swm_adc_get_channel(channel);
}
else
{
LOG_E("ADC channel must be between 0 and 11.");
return -RT_ERROR;
}
if (enabled)
{
adc_cfg->ADCx->SEQCHN0 |= adc_chn;
}
else
{
adc_cfg->ADCx->SEQCHN0 &= ~adc_chn;
}
return RT_EOK;
}
static rt_err_t swm_adc_convert(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_uint32_t *value)
{
uint32_t i, chn, val, adc_chn;
struct swm_adc_cfg *adc_cfg;
RT_ASSERT(adc_device != RT_NULL);
RT_ASSERT(value != RT_NULL);
adc_cfg = adc_device->parent.user_data;
if (channel < 12)
{
/* set swm ADC channel */
adc_chn = swm_adc_get_channel(channel);
}
else
{
LOG_E("ADC channel must be between 0 and 11.");
return -RT_ERROR;
}
*value = 0xFFFFFFFF;
/* start ADC */
ADC_Start(adc_cfg->ADCx, ADC_SEQ0);
/* Wait for the ADC to convert */
while (adc_cfg->ADCx->GO & ADC_GO_BUSY_Msk)
__NOP();
while ((adc_cfg->ADCx->SEQ[0].SR & ADC_SR_EMPTY_Msk) == 0)
{
val = ADC_Read(adc_cfg->ADCx, ADC_SEQ0, &chn);
if (chn == adc_chn)
{
*value = val;
}
}
if (*value == 0xFFFFFFFF)
{
LOG_E("ADC channel can not find.");
return -RT_ERROR;
}
return RT_EOK;
}
static const struct rt_adc_ops swm_adc_ops =
{
.enabled = swm_adc_enabled,
.convert = swm_adc_convert,
};
int swm_adc_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0]); i++)
{
/* ADC init */
adc_obj[i].adc_cfg = &swm_adc_cfg[i];
if (adc_obj[i].adc_cfg->ADCx == ADC0)
{
#ifdef BSP_USING_ADC0_CHN0
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
PORT_Init(PORTC, PIN6, PORTC_PIN6_ADC0_CH0, 0); //PC.6 => ADC.CH0
#endif
#ifdef BSP_USING_ADC0_CHN1
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
PORT_Init(PORTC, PIN5, PORTC_PIN5_ADC0_CH1, 0); //PC.5 => ADC.CH1
#endif
#ifdef BSP_USING_ADC0_CHN2
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
PORT_Init(PORTC, PIN4, PORTC_PIN4_ADC0_CH2, 0); //PC.4 => ADC.CH2
#endif
#ifdef BSP_USING_ADC0_CHN3
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
PORT_Init(PORTC, PIN3, PORTC_PIN3_ADC0_CH3, 0); //PC.3 => ADC.CH3
#endif
#ifdef BSP_USING_ADC0_CHN4
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
PORT_Init(PORTC, PIN2, PORTC_PIN2_ADC0_CH4, 0); //PC.2 => ADC.CH4
#endif
#ifdef BSP_USING_ADC0_CHN5
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
PORT_Init(PORTC, PIN1, PORTC_PIN1_ADC0_CH5, 0); //PC.1 => ADC.CH5
#endif
#ifdef BSP_USING_ADC0_CHN6
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
PORT_Init(PORTC, PIN0, PORTC_PIN0_ADC0_CH6, 0); //PC.0 => ADC.CH6
#endif
#ifdef BSP_USING_ADC0_CHN7
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH7;
PORT_Init(PORTA, PIN15, PORTA_PIN15_ADC0_CH7, 0); //PA.15 => ADC.CH7
#endif
#ifdef BSP_USING_ADC0_CHN8
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH8;
PORT_Init(PORTA, PIN14, PORTA_PIN14_ADC0_CH8, 0); //PA.14 => ADC.CH8
#endif
#ifdef BSP_USING_ADC0_CHN9
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH9;
PORT_Init(PORTA, PIN13, PORTA_PIN13_ADC0_CH9, 0); //PA.13 => ADC.CH9
#endif
#ifdef BSP_USING_ADC0_CHN10
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH10;
PORT_Init(PORTA, PIN12, PORTA_PIN12_ADC0_CH10, 0); //PA.12 => ADC.CH10
#endif
#ifdef BSP_USING_ADC0_CHN11
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH11;
PORT_Init(PORTA, PIN10, PORTA_PIN10_ADC0_CH11, 0); //PA.10 => ADC.CH11
#endif
}
else if (adc_obj[i].adc_cfg->ADCx == ADC1)
{
#ifdef BSP_USING_ADC1_CHN0
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
PORT_Init(PORTD, PIN1, PORTD_PIN1_ADC1_CH0, 0); //PD.1 => ADC1.CH0
#endif
#ifdef BSP_USING_ADC1_CHN1
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
PORT_Init(PORTD, PIN0, PORTD_PIN0_ADC1_CH1, 0); //PD.0 => ADC1.CH1
#endif
#ifdef BSP_USING_ADC1_CHN2
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
PORT_Init(PORTC, PIN13, PORTC_PIN13_ADC1_CH2, 0); //PC.13 => ADC1.CH2
#endif
#ifdef BSP_USING_ADC1_CHN3
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
PORT_Init(PORTC, PIN12, PORTC_PIN12_ADC1_CH3, 0); //PC.12 => ADC1.CH3
#endif
#ifdef BSP_USING_ADC1_CHN4
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
PORT_Init(PORTC, PIN11, PORTC_PIN11_ADC1_CH4, 0); //PC.11 => ADC1.CH4
#endif
#ifdef BSP_USING_ADC1_CHN5
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
PORT_Init(PORTC, PIN10, PORTC_PIN10_ADC1_CH5, 0); //PC.10 => ADC1.CH5
#endif
#ifdef BSP_USING_ADC1_CHN6
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
PORT_Init(PORTC, PIN9, PORTC_PIN9_ADC1_CH6, 0); //PC.9 => ADC1.CH6
#endif
}
ADC_Init(adc_obj[i].adc_cfg->ADCx, &(adc_obj[i].adc_cfg->ADC_initstruct));
ADC_SEQ_Init(adc_obj[i].adc_cfg->ADCx, ADC_SEQ0, &(adc_obj[i].adc_cfg->ADC_SEQ_initstruct));
ADC_Open(adc_obj[i].adc_cfg->ADCx);
ADC_Calibrate(adc_obj[i].adc_cfg->ADCx);
result = rt_hw_adc_register(&adc_obj[i].adc_device, adc_obj[i].adc_cfg->name, &swm_adc_ops, adc_obj[i].adc_cfg);
if(result != RT_EOK)
{
LOG_E("%s register fail.", adc_obj[i].adc_cfg->name);
}
else
{
LOG_D("%s register success.", adc_obj[i].adc_cfg->name);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_adc_init);
#endif /* BSP_USING_ADC */
#endif /* RT_USING_ADC */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_ADC_H__
#define __DRV_ADC_H__
#include "board.h"
int swm_adc_init(void);
#endif /* __DRV_ADC_H__ */

View File

@ -0,0 +1,565 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-16 lik first version
*/
#include "drv_can.h"
#ifdef RT_USING_CAN
#ifdef BSP_USING_CAN
//#define DRV_DEBUG
#define LOG_TAG "drv.can"
#include <drv_log.h>
#if !defined(BSP_USING_CAN0) && !defined(BSP_USING_CAN1)
#error "Please define at least one BSP_USING_CANx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_CAN0
#ifndef CAN0_CFG
#define CAN0_CFG \
{ \
.name = "can0", \
.CANx = CAN0, \
}
#endif /* CAN0_CFG */
#endif /* BSP_USING_CAN0 */
#ifdef BSP_USING_CAN1
#ifndef CAN1_CFG
#define CAN1_CFG \
{ \
.name = "can1", \
.CANx = CAN1, \
}
#endif /* CAN1_CFG */
#endif /* BSP_USING_CAN1 */
#define PRESCL_Pos 0
#define BS1_Pos 16
#define BS2_Pos 20
#define SJW_Pos 24
#define PRESCL_Msk (0x3FF << PRESCL_Pos)
#define BS1_Msk ((0x0F) << BS1_Pos)
#define BS2_Msk ((0x07) << BS2_Pos)
#define SJW_Msk (0x3 << SJW_Pos)
struct swm_baud_rate_tab
{
rt_uint32_t baud_rate;
rt_uint32_t config_data;
};
#define BAUD_DATA(TYPE, NO) ((can_baud_rate_tab[NO].config_data & TYPE##_Msk) >> TYPE##_Pos)
struct swm_can_cfg
{
const char *name;
CAN_TypeDef *CANx;
CAN_InitStructure CAN_initstruct;
};
struct swm_can_device
{
struct swm_can_cfg *can_cfg;
struct rt_can_device can_device;
};
/* SystemCoreClock 152MHz(max) 150MHz不能生成CAN1MBaud */
static const struct swm_baud_rate_tab can_baud_rate_tab[] =
{
{CAN1MBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (1 << PRESCL_Pos))},
{CAN500kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (3 << PRESCL_Pos))},
{CAN250kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (7 << PRESCL_Pos))},
{CAN125kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (15 << PRESCL_Pos))},
{CAN100kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (19 << PRESCL_Pos))},
{CAN50kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (39 << PRESCL_Pos))},
{CAN20kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (99 << PRESCL_Pos))},
{CAN10kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (199 << PRESCL_Pos))}};
enum
{
#ifdef BSP_USING_CAN0
CAN0_INDEX,
#endif
#ifdef BSP_USING_CAN1
CAN1_INDEX,
#endif
};
static struct swm_can_cfg swm_can_cfg[] =
{
#ifdef BSP_USING_CAN0
CAN0_CFG,
#endif
#ifdef BSP_USING_CAN1
CAN1_CFG,
#endif
};
static struct swm_can_device can_obj[sizeof(swm_can_cfg) / sizeof(swm_can_cfg[0])];
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
{
rt_uint32_t len, index;
len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
for (index = 0; index < len; index++)
{
if (can_baud_rate_tab[index].baud_rate == baud)
return index;
}
return 0; /* default baud is CAN1MBaud */
}
static rt_err_t swm_can_config(struct rt_can_device *can_device, struct can_configure *cfg)
{
struct swm_can_device *can_dev;
rt_uint32_t baud_index;
rt_uint32_t can_mode;
RT_ASSERT(can_device);
RT_ASSERT(cfg);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
RT_ASSERT(can_dev);
switch (cfg->mode)
{
case RT_CAN_MODE_NORMAL:
can_mode = CAN_MODE_NORMAL;
break;
case RT_CAN_MODE_LISEN:
can_mode = CAN_MODE_LISTEN;
break;
case RT_CAN_MODE_LOOPBACK:
can_mode = CAN_MODE_SELFTEST;
break;
case RT_CAN_MODE_LOOPBACKANLISEN:
can_mode = CAN_MODE_SELFTEST;
break;
}
baud_index = get_can_baud_index(cfg->baud_rate);
CAN_Close(can_dev->can_cfg->CANx); //一些关键寄存器只能在CAN关闭时设置
can_dev->can_cfg->CANx->CR &= ~(CAN_CR_LOM_Msk | CAN_CR_STM_Msk);
can_dev->can_cfg->CANx->CR |= (can_mode << CAN_CR_LOM_Pos);
can_dev->can_cfg->CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
(BAUD_DATA(BS1, baud_index) << CAN_BT1_TSEG1_Pos) |
(BAUD_DATA(BS2, baud_index) << CAN_BT1_TSEG2_Pos);
can_dev->can_cfg->CANx->BT0 = (BAUD_DATA(SJW, baud_index) << CAN_BT0_SJW_Pos) |
((BAUD_DATA(PRESCL, baud_index) & 0x3F) << CAN_BT0_BRP_Pos);
can_dev->can_cfg->CANx->BT2 = ((BAUD_DATA(PRESCL, baud_index) >> 6) << CAN_BT2_BRP_Pos);
can_dev->can_cfg->CANx->RXERR = 0; //只能在复位模式下清除
can_dev->can_cfg->CANx->TXERR = 0;
/* can start */
CAN_Open(can_dev->can_cfg->CANx);
return RT_EOK;
}
static rt_err_t swm_can_control(struct rt_can_device *can_device, int cmd, void *arg)
{
rt_uint32_t argval;
struct swm_can_device *can_dev;
struct rt_can_filter_config *filter_cfg;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
RT_ASSERT(can_dev != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
can_dev->can_cfg->CANx->IE &= ~(CAN_IE_RXDA_Msk | CAN_IE_RXOV_Msk);
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{
can_dev->can_cfg->CANx->IE &= ~CAN_IE_TXBR_Msk;
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{
can_dev->can_cfg->CANx->IE &= ~(CAN_IE_ARBLOST_Msk | CAN_IE_BUSERR_Msk | CAN_IE_ERRWARN_Msk | CAN_IE_ERRPASS_Msk);
}
break;
case RT_DEVICE_CTRL_SET_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
can_dev->can_cfg->CANx->IE |= (CAN_IE_RXDA_Msk | CAN_IE_RXOV_Msk);
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{
can_dev->can_cfg->CANx->IE |= CAN_IE_TXBR_Msk;
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{
can_dev->can_cfg->CANx->IE |= (CAN_IE_ARBLOST_Msk | CAN_IE_BUSERR_Msk | CAN_IE_ERRWARN_Msk | CAN_IE_ERRPASS_Msk);
}
break;
case RT_CAN_CMD_SET_FILTER:
{
rt_uint32_t filter_idx = 0;
if (RT_NULL == arg)
{
/* default filter config */
}
else
{
filter_cfg = (struct rt_can_filter_config *)arg;
/* get default filter */
for (int i = 0; i < filter_cfg->count; i++)
{
if (filter_cfg->items[i].hdr == -1)
{
filter_idx = i;
}
else
{
filter_idx = filter_cfg->items[i].hdr;
}
if (filter_cfg->items[i].ide == RT_CAN_STDID)
{
can_dev->can_cfg->CANx->AFM &= ~(1 << filter_idx);
can_dev->can_cfg->CANx->ACR[filter_idx] = __REV(filter_cfg->items[i].id << 5);
can_dev->can_cfg->CANx->AMR[filter_idx] = __REV(~(filter_cfg->items[i].mask << 5));
can_dev->can_cfg->CANx->AFE |= (1 << filter_idx);
}
else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
{
can_dev->can_cfg->CANx->AFM |= (1 << filter_idx);
can_dev->can_cfg->CANx->ACR[filter_idx] = __REV(filter_cfg->items[i].id << 3);
can_dev->can_cfg->CANx->AMR[filter_idx] = __REV(~(filter_cfg->items[i].mask << 3));
can_dev->can_cfg->CANx->AFE |= (1 << filter_idx);
}
}
}
break;
}
case RT_CAN_CMD_SET_MODE:
argval = (rt_uint32_t)arg;
if (argval != RT_CAN_MODE_NORMAL &&
argval != RT_CAN_MODE_LISEN &&
argval != RT_CAN_MODE_LOOPBACK &&
argval != RT_CAN_MODE_LOOPBACKANLISEN)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.mode)
{
can_dev->can_device.config.mode = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_SET_BAUD:
argval = (rt_uint32_t)arg;
if (argval != CAN1MBaud &&
argval != CAN800kBaud &&
argval != CAN500kBaud &&
argval != CAN250kBaud &&
argval != CAN125kBaud &&
argval != CAN100kBaud &&
argval != CAN50kBaud &&
argval != CAN20kBaud &&
argval != CAN10kBaud)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.baud_rate)
{
can_dev->can_device.config.baud_rate = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_SET_PRIV:
argval = (rt_uint32_t)arg;
if (argval != RT_CAN_MODE_PRIV &&
argval != RT_CAN_MODE_NOPRIV)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.privmode)
{
can_dev->can_device.config.privmode = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_GET_STATUS:
{
can_dev->can_device.status.rcverrcnt = can_dev->can_cfg->CANx->RXERR;
can_dev->can_device.status.snderrcnt = can_dev->can_cfg->CANx->TXERR;
can_dev->can_device.status.lasterrtype = (can_dev->can_cfg->CANx->ECC >> 6) & 0x03;
can_dev->can_device.status.errcode = can_dev->can_cfg->CANx->ECC & 0x1F;
rt_memcpy(arg, &can_dev->can_device.status, sizeof(can_dev->can_device.status));
}
break;
}
return RT_EOK;
}
static int swm_can_sendmsg(struct rt_can_device *can_device, const void *buf, rt_uint32_t box_num)
{
uint32_t i;
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
if (RT_CAN_STDID == pmsg->ide)
{
can_dev->can_cfg->CANx->FRAME.DATA[0] = pmsg->id >> 3;
can_dev->can_cfg->CANx->FRAME.DATA[1] = pmsg->id << 5;
if (RT_CAN_DTR == pmsg->rtr)
{
can_dev->can_cfg->CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(pmsg->len << CAN_INFO_DLC_Pos);
for(i = 0; i < pmsg->len; i++)
{
can_dev->can_cfg->CANx->FRAME.DATA[i+2] = pmsg->data[i];
}
if(can_dev->can_cfg->CANx->CR & CAN_CR_STM_Msk)
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_SRR_Pos);
}
else
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.DATA[0] = pmsg->id >> 21;
can_dev->can_cfg->CANx->FRAME.DATA[1] = pmsg->id >> 13;
can_dev->can_cfg->CANx->FRAME.DATA[2] = pmsg->id >> 5;
can_dev->can_cfg->CANx->FRAME.DATA[3] = pmsg->id << 3;
if (RT_CAN_DTR == pmsg->rtr)
{
can_dev->can_cfg->CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(pmsg->len << CAN_INFO_DLC_Pos);
for(i = 0; i < pmsg->len; i++)
{
can_dev->can_cfg->CANx->FRAME.DATA[i+4] = pmsg->data[i];
}
if(can_dev->can_cfg->CANx->CR & CAN_CR_STM_Msk)
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_SRR_Pos);
}
else
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
return RT_EOK;
}
static int swm_can_recvmsg(struct rt_can_device *can_device, void *buf, rt_uint32_t fifo)
{
uint32_t i;
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
CAN_RXMessage CAN_RXMsg;
/* get data */
CAN_Receive(can_dev->can_cfg->CANx, &CAN_RXMsg);
/* get id */
if (CAN_RXMsg.format == CAN_FRAME_STD)
{
pmsg->ide = RT_CAN_STDID;
}
else
{
pmsg->ide = RT_CAN_EXTID;
}
pmsg->id = CAN_RXMsg.id;
/* get type */
if (CAN_RXMsg.remote == 0)
{
pmsg->rtr = RT_CAN_DTR;
}
else
{
pmsg->rtr = RT_CAN_RTR;
}
/* get len */
pmsg->len = CAN_RXMsg.size;
for(i = 0; i < pmsg->len; i++)
{
pmsg->data[i] = CAN_RXMsg.data[i];
}
return RT_EOK;
}
static const struct rt_can_ops swm_can_ops =
{
.configure = swm_can_config,
.control = swm_can_control,
.sendmsg = swm_can_sendmsg,
.recvmsg = swm_can_recvmsg,
};
static void swm_can_isr(struct rt_can_device *can_device)
{
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
uint32_t int_sr = CAN_INTStat(can_dev->can_cfg->CANx);
if(int_sr & CAN_IF_RXDA_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_RX_IND);
}
else if (int_sr & CAN_IF_RXOV_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_RXOF_IND);
}
else if (int_sr & CAN_IF_TXBR_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_TX_DONE);
}
else if (int_sr & CAN_IE_ERRWARN_Msk)
{
}
else if (int_sr & CAN_IE_ERRPASS_Msk)
{
}
else if (int_sr & CAN_IE_ARBLOST_Msk)
{
}
else if (int_sr & CAN_IE_BUSERR_Msk)
{
}
}
#ifdef BSP_USING_CAN0
/**
* @brief This function handles CAN0 interrupts.
*/
void CAN0_Handler(void)
{
rt_interrupt_enter();
swm_can_isr(&(can_obj[CAN0_INDEX].can_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN0 */
#ifdef BSP_USING_CAN1
/**
* @brief This function handles CAN1 interrupts.
*/
void CAN1_Handler(void)
{
rt_interrupt_enter();
swm_can_isr(&(can_obj[CAN0_INDEX].can_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN1 */
int swm_can_init(void)
{
int i = 0;
int result = RT_EOK;
struct can_configure config = CANDEFAULTCONFIG;
config.privmode = RT_CAN_MODE_NOPRIV;
config.ticks = 50;
#ifdef RT_CAN_USING_HDR
config.maxhdr = 16;
#endif
#ifdef BSP_USING_CAN0
PORT_Init(PORTB, PIN5, PORTB_PIN5_CAN0_RX, 1);
PORT_Init(PORTB, PIN4, PORTB_PIN4_CAN0_TX, 0);
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CAN0_Pos);
NVIC_EnableIRQ(CAN0_IRQn);
#endif
#ifdef BSP_USING_CAN1
PORT_Init(PORTB, PIN3, PORTB_PIN3_CAN1_RX, 1);
PORT_Init(PORTB, PIN2, PORTB_PIN2_CAN1_TX, 0);
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_CAN1_Pos);
NVIC_EnableIRQ(CAN1_IRQn);
#endif
for (i = 0; i < sizeof(swm_can_cfg) / sizeof(swm_can_cfg[0]); i++)
{
can_obj[i].can_device.config = config;
can_obj[i].can_cfg = &swm_can_cfg[i];
result = rt_hw_can_register(&can_obj[i].can_device,
can_obj[i].can_cfg->name,
&swm_can_ops,
&can_obj[i]);
if (result != RT_EOK)
{
LOG_E("%s register fail.", can_obj[i].can_cfg->name);
}
else
{
LOG_D("%s register success.", can_obj[i].can_cfg->name);
}
}
return result;
return 0;
}
INIT_BOARD_EXPORT(swm_can_init);
#endif /* BSP_USING_CAN */
#endif /* RT_USING_CAN */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-16 lik first version
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#include "board.h"
int swm_can_init(void);
#endif /* __DRV_CAN_H__ */

View File

@ -0,0 +1,316 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_crypto.h"
#include <string.h>
#ifdef RT_USING_HWCRYPTO
//#define DRV_DEBUG
#define LOG_TAG "drv.crypto"
#include <drv_log.h>
struct swm_hwcrypto_device
{
struct rt_hwcrypto_device dev;
struct rt_mutex mutex;
};
static struct swm_hwcrypto_device hwcrypto_obj;
#ifdef BSP_USING_CRC
struct swm_crc_cfg
{
CRC_TypeDef *CRCx;
CRC_InitStructure CRC_initstruct;
};
static struct hwcrypto_crc_cfg swm_crc_cfg;
static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
{
rt_uint32_t result = 0;
struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
{
crc_cfg->CRCx = CRC;
crc_cfg->CRC_initstruct.init_crc = ctx->crc_cfg.last_val;
switch (ctx->crc_cfg.poly)
{
case 0x07:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_107;
break;
case 0x1021:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_11021;
break;
case 0x8005:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_18005;
break;
case 0x04C11DB7:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_104C11DB7;
break;
default:
goto _exit;
}
switch (ctx->crc_cfg.width)
{
case 8:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_8;
break;
case 16:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_16;
break;
case 32:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_32;
break;
default:
goto _exit;
}
switch (ctx->crc_cfg.flags)
{
case 0:
crc_cfg->CRC_initstruct.in_not = false;
crc_cfg->CRC_initstruct.out_not = false;
break;
case CRC_FLAG_REFIN:
crc_cfg->CRC_initstruct.in_not = true;
crc_cfg->CRC_initstruct.out_not = false;
break;
case CRC_FLAG_REFOUT:
crc_cfg->CRC_initstruct.in_not = false;
crc_cfg->CRC_initstruct.out_not = true;
break;
case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
crc_cfg->CRC_initstruct.in_not = true;
crc_cfg->CRC_initstruct.out_not = true;
break;
default:
goto _exit;
}
crc_cfg->CRC_initstruct.in_rev = CRC_REV_NOT;
crc_cfg->CRC_initstruct.out_rev = CRC_REV_NOT;
CRC_Init(crc_cfg->CRCx, &(crc_cfg->CRC_initstruct));
memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
}
for (uint32_t i = 0; i < length; i++)
CRC_Write((uint32_t)in[i]);
result = CRC_Result();
ctx->crc_cfg.last_val = result;
swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
_exit:
rt_mutex_release(&hwcrypto_dev->mutex);
return result;
}
static const struct hwcrypto_crc_ops swm_crc_ops =
{
.update = swm_crc_update,
};
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
struct swm_rng_cfg
{
SYS_TypeDef *SYSx;
};
static rt_uint32_t swm_rng_update(struct hwcrypto_rng *ctx)
{
rt_uint32_t gen_randoml = 0, gen_randomh = 0;
struct swm_rng_cfg *rng_cfg = (struct swm_rng_cfg *)(ctx->parent.contex);
while ((rng_cfg->SYSx->PRNGCR & SYS_PRNGCR_RDY_Msk) == 0)
__NOP();
gen_randoml = rng_cfg->SYSx->PRNGDL;
gen_randomh = rng_cfg->SYSx->PRNGDH;
return gen_randoml;
}
static const struct hwcrypto_rng_ops swm_rng_ops =
{
.update = swm_rng_update,
};
#endif /* BSP_USING_RNG */
static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
{
struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
if (RT_NULL == crc_cfg)
{
res = -RT_ERROR;
break;
}
ctx->contex = crc_cfg;
((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
break;
}
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
{
struct swm_rng_cfg *rng_cfg = rt_calloc(1, sizeof(struct swm_rng_cfg));
if (RT_NULL == rng_cfg)
{
res = -RT_ERROR;
break;
}
rng_cfg->SYSx = SYS;
rng_cfg->SYSx->HRCCR |= (1 << SYS_HRCCR_ON_Pos);
rng_cfg->SYSx->LRCCR |= (1 << SYS_LRCCR_ON_Pos);
rng_cfg->SYSx->PRNGCR = (0 << SYS_PRNGCR_CLR_Pos) |
(3 << SYS_PRNGCR_MODE_Pos);
ctx->contex = rng_cfg;
((struct hwcrypto_rng *)ctx)->ops = &swm_rng_ops;
break;
}
#endif /* BSP_USING_RNG */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
{
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
default:
break;
}
rt_free(ctx->contex);
}
static rt_err_t swm_crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
{
rt_err_t res = RT_EOK;
switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
}
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(struct swm_rng_cfg));
}
break;
#endif /* BSP_USING_RNG */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
{
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
default:
break;
}
}
static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
{
.create = swm_crypto_create,
.destroy = swm_crypto_destroy,
.copy = swm_crypto_clone,
.reset = swm_crypto_reset,
};
int swm_crypto_init(void)
{
rt_uint32_t cpuid[2] = {0};
hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
cpuid[0] = SCB->CPUID;
hwcrypto_obj.dev.id = 0;
rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
hwcrypto_obj.dev.user_data = &hwcrypto_obj;
if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
{
return -1;
}
rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO);
return 0;
}
INIT_BOARD_EXPORT(swm_crypto_init);
#endif /* RT_USING_HWCRYPTO */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_CRYPTO_H__
#define __DRV_CRYPTO_H__
#include "board.h"
int swm_crypto_init(void);
#endif /* __DRV_CRYPTO_H__ */

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 lik first version
*/
#include "drv_dac.h"
#ifdef BSP_USING_DAC
//#define DRV_DEBUG
#define LOG_TAG "drv.dac"
#include <drv_log.h>
static struct rt_dac_device swm_dac_device;
static rt_err_t swm_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
{
RT_ASSERT(device != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC_Open(DAC);
return RT_EOK;
}
static rt_err_t swm_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
{
RT_ASSERT(device != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC_Close(DAC);
return RT_EOK;
}
static rt_err_t swm_dac_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(value != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC->DHR = *value;
while(DAC->SR & DAC_SR_DHRFULL_Msk) __NOP();
return RT_EOK;
}
static const struct rt_dac_ops swm_dac_ops =
{
.disabled = swm_dac_disabled,
.enabled = swm_dac_enabled,
.convert = swm_dac_convert,
};
int swm_dac_init(void)
{
int result = RT_EOK;
PORT_Init(PORTD, PIN2, PORTD_PIN2_DAC_OUT, 0);
DAC_Init(DAC, DAC_FORMAT_LSB12B);
SYS->DACCR &= ~SYS_DACCR_VRADJ_Msk;
SYS->DACCR |= (17 << SYS_DACCR_VRADJ_Pos);
/* register dac device */
result = rt_hw_dac_register(&swm_dac_device, "dac", &swm_dac_ops, RT_NULL);
if(result != RT_EOK)
{
LOG_E("dac register fail.");
}
else
{
LOG_D("dac register success.");
}
return result;
}
INIT_DEVICE_EXPORT(swm_dac_init);
#endif /* BSP_USING_DAC */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 lik first version
*/
#ifndef __DRV_DAC_H__
#define __DRV_DAC_H__
#include "board.h"
int swm_dac_init(void);
#endif /* __DRV_DAC_H__ */

View File

@ -0,0 +1,621 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_gpio.h"
#ifdef RT_USING_PIN
#ifdef BSP_USING_GPIO
//#define DRV_DEBUG
#define LOG_TAG "drv.gpio"
#include <drv_log.h>
#define __SWM_PIN(index, gpio, pin_index) \
{ \
index, GPIO##gpio, PIN##pin_index, GPIO##gpio##_IRQn \
}
struct swm_pin_device
{
uint32_t index;
GPIO_TypeDef *gpio;
uint32_t pin;
IRQn_Type irq;
};
static const struct swm_pin_device pin_obj[] =
{
__SWM_PIN(0, A, 0),
__SWM_PIN(1, A, 1),
__SWM_PIN(2, A, 2),
__SWM_PIN(3, A, 3),
__SWM_PIN(4, A, 4),
__SWM_PIN(5, A, 5),
__SWM_PIN(6, A, 6),
__SWM_PIN(7, A, 7),
__SWM_PIN(8, A, 8),
__SWM_PIN(9, A, 9),
__SWM_PIN(10, A, 10),
__SWM_PIN(11, A, 11),
__SWM_PIN(12, A, 12),
__SWM_PIN(13, A, 13),
__SWM_PIN(14, A, 14),
__SWM_PIN(15, A, 15),
__SWM_PIN(16, B, 0),
__SWM_PIN(17, B, 1),
__SWM_PIN(18, B, 2),
__SWM_PIN(19, B, 3),
__SWM_PIN(20, B, 4),
__SWM_PIN(21, B, 5),
__SWM_PIN(22, B, 6),
__SWM_PIN(23, B, 7),
__SWM_PIN(24, B, 8),
__SWM_PIN(25, B, 9),
__SWM_PIN(26, B, 10),
__SWM_PIN(27, B, 11),
__SWM_PIN(28, B, 12),
__SWM_PIN(29, B, 13),
__SWM_PIN(30, B, 14),
__SWM_PIN(31, B, 15),
__SWM_PIN(32, C, 0),
__SWM_PIN(33, C, 1),
__SWM_PIN(34, C, 2),
__SWM_PIN(35, C, 3),
__SWM_PIN(36, C, 4),
__SWM_PIN(37, C, 5),
__SWM_PIN(38, C, 6),
__SWM_PIN(39, C, 7),
__SWM_PIN(40, C, 8),
__SWM_PIN(41, C, 9),
__SWM_PIN(42, C, 10),
__SWM_PIN(43, C, 11),
__SWM_PIN(44, C, 12),
__SWM_PIN(45, C, 13),
__SWM_PIN(46, C, 14),
__SWM_PIN(47, C, 15),
__SWM_PIN(48, D, 0),
__SWM_PIN(49, D, 1),
__SWM_PIN(50, D, 2),
__SWM_PIN(51, D, 3),
__SWM_PIN(52, D, 4),
__SWM_PIN(53, D, 5),
__SWM_PIN(54, D, 6),
__SWM_PIN(55, D, 7),
__SWM_PIN(56, D, 8),
__SWM_PIN(57, D, 9),
__SWM_PIN(58, D, 10),
__SWM_PIN(59, D, 11),
__SWM_PIN(60, D, 12),
__SWM_PIN(61, D, 13),
__SWM_PIN(62, D, 14),
__SWM_PIN(63, D, 15),
__SWM_PIN(64, E, 0),
__SWM_PIN(65, E, 1),
__SWM_PIN(66, E, 2),
__SWM_PIN(67, E, 3),
__SWM_PIN(68, E, 4),
__SWM_PIN(69, E, 5),
__SWM_PIN(70, E, 6),
__SWM_PIN(71, E, 7),
__SWM_PIN(72, E, 8),
__SWM_PIN(73, E, 9),
__SWM_PIN(74, E, 10),
__SWM_PIN(75, E, 11),
__SWM_PIN(76, E, 12),
__SWM_PIN(77, E, 13),
__SWM_PIN(78, E, 14),
__SWM_PIN(79, E, 15),
__SWM_PIN(80, M, 0),
__SWM_PIN(81, M, 1),
__SWM_PIN(82, M, 2),
__SWM_PIN(83, M, 3),
__SWM_PIN(84, M, 4),
__SWM_PIN(85, M, 5),
__SWM_PIN(86, M, 6),
__SWM_PIN(87, M, 7),
__SWM_PIN(88, M, 8),
__SWM_PIN(89, M, 9),
__SWM_PIN(90, M, 10),
__SWM_PIN(91, M, 11),
__SWM_PIN(92, M, 12),
__SWM_PIN(93, M, 13),
__SWM_PIN(94, M, 14),
__SWM_PIN(95, M, 15),
__SWM_PIN(96, N, 0),
__SWM_PIN(97, N, 1),
__SWM_PIN(98, N, 2),
__SWM_PIN(99, N, 3),
__SWM_PIN(100, N, 4),
__SWM_PIN(101, N, 5),
__SWM_PIN(102, N, 6),
__SWM_PIN(103, N, 7),
__SWM_PIN(104, N, 8),
__SWM_PIN(105, N, 9),
__SWM_PIN(106, N, 10),
__SWM_PIN(107, N, 11),
__SWM_PIN(108, N, 12),
__SWM_PIN(109, N, 13),
__SWM_PIN(110, N, 14),
__SWM_PIN(111, N, 15)};
static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
{
{0, 0, RT_NULL, RT_NULL},
{1, 0, RT_NULL, RT_NULL},
{2, 0, RT_NULL, RT_NULL},
{3, 0, RT_NULL, RT_NULL},
{4, 0, RT_NULL, RT_NULL},
{5, 0, RT_NULL, RT_NULL},
{6, 0, RT_NULL, RT_NULL},
{7, 0, RT_NULL, RT_NULL},
{8, 0, RT_NULL, RT_NULL},
{9, 0, RT_NULL, RT_NULL},
{10, 0, RT_NULL, RT_NULL},
{11, 0, RT_NULL, RT_NULL},
{12, 0, RT_NULL, RT_NULL},
{13, 0, RT_NULL, RT_NULL},
{14, 0, RT_NULL, RT_NULL},
{15, 0, RT_NULL, RT_NULL},
{16, 0, RT_NULL, RT_NULL},
{17, 0, RT_NULL, RT_NULL},
{18, 0, RT_NULL, RT_NULL},
{19, 0, RT_NULL, RT_NULL},
{20, 0, RT_NULL, RT_NULL},
{21, 0, RT_NULL, RT_NULL},
{22, 0, RT_NULL, RT_NULL},
{23, 0, RT_NULL, RT_NULL},
{24, 0, RT_NULL, RT_NULL},
{25, 0, RT_NULL, RT_NULL},
{26, 0, RT_NULL, RT_NULL},
{27, 0, RT_NULL, RT_NULL},
{28, 0, RT_NULL, RT_NULL},
{29, 0, RT_NULL, RT_NULL},
{30, 0, RT_NULL, RT_NULL},
{31, 0, RT_NULL, RT_NULL},
{32, 0, RT_NULL, RT_NULL},
{33, 0, RT_NULL, RT_NULL},
{34, 0, RT_NULL, RT_NULL},
{35, 0, RT_NULL, RT_NULL},
{36, 0, RT_NULL, RT_NULL},
{37, 0, RT_NULL, RT_NULL},
{38, 0, RT_NULL, RT_NULL},
{39, 0, RT_NULL, RT_NULL},
{40, 0, RT_NULL, RT_NULL},
{41, 0, RT_NULL, RT_NULL},
{42, 0, RT_NULL, RT_NULL},
{43, 0, RT_NULL, RT_NULL},
{44, 0, RT_NULL, RT_NULL},
{45, 0, RT_NULL, RT_NULL},
{46, 0, RT_NULL, RT_NULL},
{47, 0, RT_NULL, RT_NULL},
{48, 0, RT_NULL, RT_NULL},
{49, 0, RT_NULL, RT_NULL},
{50, 0, RT_NULL, RT_NULL},
{51, 0, RT_NULL, RT_NULL},
{52, 0, RT_NULL, RT_NULL},
{53, 0, RT_NULL, RT_NULL},
{54, 0, RT_NULL, RT_NULL},
{55, 0, RT_NULL, RT_NULL},
{56, 0, RT_NULL, RT_NULL},
{57, 0, RT_NULL, RT_NULL},
{58, 0, RT_NULL, RT_NULL},
{59, 0, RT_NULL, RT_NULL},
{60, 0, RT_NULL, RT_NULL},
{61, 0, RT_NULL, RT_NULL},
{62, 0, RT_NULL, RT_NULL},
{63, 0, RT_NULL, RT_NULL},
{64, 0, RT_NULL, RT_NULL},
{65, 0, RT_NULL, RT_NULL},
{66, 0, RT_NULL, RT_NULL},
{67, 0, RT_NULL, RT_NULL},
{68, 0, RT_NULL, RT_NULL},
{69, 0, RT_NULL, RT_NULL},
{70, 0, RT_NULL, RT_NULL},
{71, 0, RT_NULL, RT_NULL},
{72, 0, RT_NULL, RT_NULL},
{73, 0, RT_NULL, RT_NULL},
{74, 0, RT_NULL, RT_NULL},
{75, 0, RT_NULL, RT_NULL},
{76, 0, RT_NULL, RT_NULL},
{77, 0, RT_NULL, RT_NULL},
{78, 0, RT_NULL, RT_NULL},
{79, 0, RT_NULL, RT_NULL},
{80, 0, RT_NULL, RT_NULL},
{81, 0, RT_NULL, RT_NULL},
{82, 0, RT_NULL, RT_NULL},
{83, 0, RT_NULL, RT_NULL},
{84, 0, RT_NULL, RT_NULL},
{85, 0, RT_NULL, RT_NULL},
{86, 0, RT_NULL, RT_NULL},
{87, 0, RT_NULL, RT_NULL},
{88, 0, RT_NULL, RT_NULL},
{89, 0, RT_NULL, RT_NULL},
{90, 0, RT_NULL, RT_NULL},
{91, 0, RT_NULL, RT_NULL},
{92, 0, RT_NULL, RT_NULL},
{93, 0, RT_NULL, RT_NULL},
{94, 0, RT_NULL, RT_NULL},
{95, 0, RT_NULL, RT_NULL},
{96, 0, RT_NULL, RT_NULL},
{97, 0, RT_NULL, RT_NULL},
{98, 0, RT_NULL, RT_NULL},
{99, 0, RT_NULL, RT_NULL},
{100, 0, RT_NULL, RT_NULL},
{101, 0, RT_NULL, RT_NULL},
{102, 0, RT_NULL, RT_NULL},
{103, 0, RT_NULL, RT_NULL},
{104, 0, RT_NULL, RT_NULL},
{105, 0, RT_NULL, RT_NULL},
{106, 0, RT_NULL, RT_NULL},
{107, 0, RT_NULL, RT_NULL},
{108, 0, RT_NULL, RT_NULL},
{109, 0, RT_NULL, RT_NULL},
{110, 0, RT_NULL, RT_NULL},
{111, 0, RT_NULL, RT_NULL}};
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
static const struct swm_pin_device *_pin2struct(uint8_t pin)
{
const struct swm_pin_device *gpio_obj;
if (pin < ITEM_NUM(pin_obj))
{
gpio_obj = &pin_obj[pin];
}
else
{
gpio_obj = RT_NULL;
}
return gpio_obj;
}
static void swm_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
const struct swm_pin_device *gpio_obj;
int dir = 0;
int pull_up = 0;
int pull_down = 0;
int open_drain = 0;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return;
}
/* Configure GPIO_InitStructure */
switch (mode)
{
case PIN_MODE_OUTPUT:
/* output setting */
dir = 1;
break;
case PIN_MODE_INPUT:
/* input setting: not pull. */
dir = 0;
break;
case PIN_MODE_INPUT_PULLUP:
/* input setting: pull up. */
dir = 0;
pull_up = 1;
break;
case PIN_MODE_INPUT_PULLDOWN:
/* input setting: pull down. */
dir = 0;
pull_down = 1;
break;
case PIN_MODE_OUTPUT_OD:
/* output setting: od. */
dir = 1;
open_drain = 1;
break;
}
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, dir, pull_up, pull_down, open_drain);
}
static void swm_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
const struct swm_pin_device *gpio_obj;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return;
}
if (value)
{
GPIO_AtomicSetBit(gpio_obj->gpio, gpio_obj->pin);
}
else
{
GPIO_AtomicClrBit(gpio_obj->gpio, gpio_obj->pin);
}
}
static int swm_pin_read(rt_device_t dev, rt_base_t pin)
{
const struct swm_pin_device *gpio_obj;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return PIN_LOW;
}
return (int)GPIO_GetBit(gpio_obj->gpio, gpio_obj->pin);
}
static rt_err_t swm_pin_attach_irq(struct rt_device *device,
rt_int32_t pin,
rt_uint32_t mode,
void (*hdr)(void *args),
void *args)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[pin].pin == pin &&
pin_irq_hdr_tab[pin].mode == mode &&
pin_irq_hdr_tab[pin].hdr == hdr &&
pin_irq_hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_tab[pin].pin = pin;
pin_irq_hdr_tab[pin].mode = mode;
pin_irq_hdr_tab[pin].hdr = hdr;
pin_irq_hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t swm_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
pin_irq_hdr_tab[pin].mode = 0;
pin_irq_hdr_tab[pin].hdr = RT_NULL;
pin_irq_hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t swm_pin_irq_enable(struct rt_device *device,
rt_base_t pin,
rt_uint32_t enabled)
{
const struct swm_pin_device *gpio_obj;
rt_base_t level = 0;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
switch (pin_irq_hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 0, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_RISE_EDGE);
break;
case PIN_IRQ_MODE_FALLING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 0, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_FALL_EDGE);
break;
case PIN_IRQ_MODE_RISING_FALLING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_BOTH_EDGE);
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 0, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_HIGH_LEVEL);
break;
case PIN_IRQ_MODE_LOW_LEVEL:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 0, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_LOW_LEVEL);
break;
default:
return RT_EINVAL;
}
level = rt_hw_interrupt_disable();
NVIC_EnableIRQ(gpio_obj->irq);
EXTI_Open(gpio_obj->gpio, gpio_obj->pin);
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
level = rt_hw_interrupt_disable();
// NVIC_DisableIRQ(gpio_obj->irq);
EXTI_Close(gpio_obj->gpio, gpio_obj->pin);
rt_hw_interrupt_enable(level);
}
else
{
return -RT_ENOSYS;
}
return RT_EOK;
}
static rt_base_t swm_pin_get(const char *name)
{
rt_base_t pin = 0;
int pin_num = 0;
int i, name_len;
name_len = rt_strlen(name);
if ((name_len < 4) || (name_len >= 6))
{
return -RT_EINVAL;
}
if ((name[0] != 'P') || (name[2] != '.'))
{
return -RT_EINVAL;
}
switch(name[1])
{
case 'A':
pin = 0;
break;
case 'B':
pin = 16;
break;
case 'C':
pin = 32;
break;
case 'D':
pin = 48;
break;
case 'E':
pin = 64;
break;
case 'M':
pin = 80;
break;
case 'N':
pin = 96;
break;
default:
return -RT_EINVAL;
}
for (i = 3; i < name_len; i++)
{
pin_num *= 10;
pin_num += name[i] - '0';
}
if(pin_num < 16)
{
pin += pin_num;
}
else
{
return -RT_EINVAL;
}
return pin;
}
const static struct rt_pin_ops swm_pin_ops =
{
.pin_mode = swm_pin_mode,
.pin_write = swm_pin_write,
.pin_read = swm_pin_read,
.pin_attach_irq = swm_pin_attach_irq,
.pin_detach_irq = swm_pin_detach_irq,
.pin_irq_enable = swm_pin_irq_enable,
.pin_get = swm_pin_get};
static void swm_pin_isr(GPIO_TypeDef *GPIOx)
{
static int gpio[16];
int index = 0;
static int init = 0;
const struct swm_pin_device *gpio_obj;
if (init == 0)
{
init = 1;
for (gpio_obj = &pin_obj[0];
gpio_obj->index < ITEM_NUM(pin_obj);
gpio_obj++)
{
if (gpio_obj->gpio == GPIOx)
{
gpio[index] = gpio_obj->index;
index++;
RT_ASSERT(index <= 16)
}
}
}
for (index = 0; index < 16; index++)
{
gpio_obj = _pin2struct(gpio[index]);
if (EXTI_State(gpio_obj->gpio, gpio_obj->pin))
{
EXTI_Clear(gpio_obj->gpio, gpio_obj->pin);
if (pin_irq_hdr_tab[gpio_obj->index].hdr)
{
pin_irq_hdr_tab[gpio_obj->index].hdr(pin_irq_hdr_tab[gpio_obj->index].args);
}
}
}
}
void GPIOA_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOA);
rt_interrupt_leave();
}
void GPIOB_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOB);
rt_interrupt_leave();
}
void GPIOC_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOC);
rt_interrupt_leave();
}
void GPIOD_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOD);
rt_interrupt_leave();
}
void GPIOE_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOE);
rt_interrupt_leave();
}
void GPIOM_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOM);
rt_interrupt_leave();
}
void GPION_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPION);
rt_interrupt_leave();
}
int swm_pin_init(void)
{
return rt_device_pin_register("pin", &swm_pin_ops, RT_NULL);
}
#endif /* BSP_USING_GPIO */
#endif /* RT_USING_PIN */

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#include "board.h"
#define GET_PIN(PORTx,PIN) (rt_uint8_t)__SWM_GET_PIN_##PORTx(PIN)
#define __SWM_GET_PIN_A(PIN) (PIN)
#define __SWM_GET_PIN_B(PIN) (16 + PIN)
#define __SWM_GET_PIN_C(PIN) (32 + PIN)
#define __SWM_GET_PIN_D(PIN) (48 + PIN)
#define __SWM_GET_PIN_E(PIN) (64 + PIN)
#define __SWM_GET_PIN_M(PIN) (80 + PIN)
#define __SWM_GET_PIN_N(PIN) (96 + PIN)
int swm_pin_init(void);
#endif /* __DRV_GPIO_H__ */

View File

@ -0,0 +1,615 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_hwtimer.h"
#ifdef RT_USING_HWTIMER
#ifdef BSP_USING_TIM
//#define DRV_DEBUG
#define LOG_TAG "drv.hwtimer"
#include <drv_log.h>
#if !defined(BSP_USING_TIM0) && !defined(BSP_USING_TIM1) && !defined(BSP_USING_TIM2) && !defined(BSP_USING_TIM3) \
&& !defined(BSP_USING_TIM4) && !defined(BSP_USING_BTIM0) && !defined(BSP_USING_BTIM1) && !defined(BSP_USING_BTIM2) \
&& !defined(BSP_USING_BTIM3) && !defined(BSP_USING_BTIM4) && !defined(BSP_USING_BTIM5) && !defined(BSP_USING_BTIM6) \
&& !defined(BSP_USING_BTIM7) && !defined(BSP_USING_BTIM8) && !defined(BSP_USING_BTIM9) && !defined(BSP_USING_BTIM10) \
&& !defined(BSP_USING_BTIM11)
#error "Please define at least one BSP_USING_TIMx or BSP_USING_BTIMx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifndef TIM_DEV_INFO_CONFIG
#define TIM_DEV_INFO_CONFIG \
{ \
.maxfreq = 1000000, \
.minfreq = 1000000, \
.maxcnt = 0xFFFFFFFF, \
.cntmode = HWTIMER_CNTMODE_DW, \
}
#endif /* TIM_DEV_INFO_CONFIG */
#ifdef BSP_USING_TIM0
#ifndef TIM0_CFG
#define TIM0_CFG \
{ \
.name = "timer0", \
.TIMRx = TIMR0, \
}
#endif /* TIM0_CFG */
#endif /* BSP_USING_TIM0 */
#ifdef BSP_USING_TIM1
#ifndef TIM1_CFG
#define TIM1_CFG \
{ \
.name = "timer1", \
.TIMRx = TIMR1, \
}
#endif /* TIM1_CFG */
#endif /* BSP_USING_TIM1 */
#ifdef BSP_USING_TIM2
#ifndef TIM2_CFG
#define TIM2_CFG \
{ \
.name = "timer2", \
.TIMRx = TIMR2, \
}
#endif /* TIM2_CFG */
#endif /* BSP_USING_TIM2 */
#ifdef BSP_USING_TIM3
#ifndef TIM3_CFG
#define TIM3_CFG \
{ \
.name = "timer3", \
.TIMRx = TIMR3, \
}
#endif /* TIM3_CFG */
#endif /* BSP_USING_TIM3 */
#ifdef BSP_USING_TIM4
#ifndef TIM4_CFG
#define TIM4_CFG \
{ \
.name = "timer4", \
.TIMRx = TIMR4, \
}
#endif /* TIM4_CFG */
#endif /* BSP_USING_TIM4 */
#ifdef BSP_USING_BTIM0
#ifndef BTIM0_CFG
#define BTIM0_CFG \
{ \
.name = "btimer0", \
.TIMRx = BTIMR0, \
}
#endif /* BTIM0_CFG */
#endif /* BSP_USING_BTIM0 */
#ifdef BSP_USING_BTIM1
#ifndef BTIM1_CFG
#define BTIM1_CFG \
{ \
.name = "btimer1", \
.TIMRx = BTIMR1, \
}
#endif /* BTIM1_CFG */
#endif /* BSP_USING_BTIM1 */
#ifdef BSP_USING_BTIM2
#ifndef BTIM2_CFG
#define BTIM2_CFG \
{ \
.name = "btimer2", \
.TIMRx = BTIMR2, \
}
#endif /* BTIM2_CFG */
#endif /* BSP_USING_BTIM2 */
#ifdef BSP_USING_BTIM3
#ifndef BTIM3_CFG
#define BTIM3_CFG \
{ \
.name = "btimer3", \
.TIMRx = BTIMR3, \
}
#endif /* BTIM3_CFG */
#endif /* BSP_USING_BTIM3 */
#ifdef BSP_USING_BTIM4
#ifndef BTIM4_CFG
#define BTIM4_CFG \
{ \
.name = "btimer4", \
.TIMRx = BTIMR4, \
}
#endif /* BTIM4_CFG */
#endif /* BSP_USING_BTIM4 */
#ifdef BSP_USING_BTIM5
#ifndef BTIM5_CFG
#define BTIM5_CFG \
{ \
.name = "btimer5", \
.TIMRx = BTIMR5, \
}
#endif /* BTIM5_CFG */
#endif /* BSP_USING_BTIM5 */
#ifdef BSP_USING_BTIM6
#ifndef BTIM6_CFG
#define BTIM6_CFG \
{ \
.name = "btimer6", \
.TIMRx = BTIMR6, \
}
#endif /* BTIM6_CFG */
#endif /* BSP_USING_BTIM6 */
#ifdef BSP_USING_BTIM7
#ifndef BTIM7_CFG
#define BTIM7_CFG \
{ \
.name = "btimer7", \
.TIMRx = BTIMR7, \
}
#endif /* BTIM7_CFG */
#endif /* BSP_USING_BTIM7 */
#ifdef BSP_USING_BTIM8
#ifndef BTIM8_CFG
#define BTIM8_CFG \
{ \
.name = "btimer8", \
.TIMRx = BTIMR8, \
}
#endif /* BTIM8_CFG */
#endif /* BSP_USING_BTIM8 */
#ifdef BSP_USING_BTIM9
#ifndef BTIM9_CFG
#define BTIM9_CFG \
{ \
.name = "btimer9", \
.TIMRx = BTIMR9, \
}
#endif /* BTIM9_CFG */
#endif /* BSP_USING_BTIM9 */
#ifdef BSP_USING_BTIM10
#ifndef BTIM10_CFG
#define BTIM10_CFG \
{ \
.name = "btimer10", \
.TIMRx = BTIMR10, \
}
#endif /* BTIM10_CFG */
#endif /* BSP_USING_BTIM10 */
#ifdef BSP_USING_BTIM11
#ifndef BTIM11_CFG
#define BTIM11_CFG \
{ \
.name = "btimer11", \
.TIMRx = BTIMR11, \
}
#endif /* BTIM11_CFG */
#endif /* BSP_USING_BTIM11 */
struct swm_hwtimer_cfg
{
char *name;
TIMR_TypeDef *TIMRx;
};
struct swm_hwtimer_device
{
struct swm_hwtimer_cfg *hwtimer_cfg;
rt_hwtimer_t time_device;
};
enum
{
#ifdef BSP_USING_TIM0
TIM0_INDEX,
#endif
#ifdef BSP_USING_TIM1
TIM1_INDEX,
#endif
#ifdef BSP_USING_TIM2
TIM2_INDEX,
#endif
#ifdef BSP_USING_TIM3
TIM3_INDEX,
#endif
#ifdef BSP_USING_TIM4
TIM4_INDEX,
#endif
#ifdef BSP_USING_BTIM0
BTIM0_INDEX,
#endif
#ifdef BSP_USING_BTIM1
BTIM1_INDEX,
#endif
#ifdef BSP_USING_BTIM2
BTIM2_INDEX,
#endif
#ifdef BSP_USING_BTIM3
BTIM3_INDEX,
#endif
#ifdef BSP_USING_BTIM4
BTIM4_INDEX,
#endif
#ifdef BSP_USING_BTIM5
BTIM5_INDEX,
#endif
#ifdef BSP_USING_BTIM6
BTIM6_INDEX,
#endif
#ifdef BSP_USING_BTIM7
BTIM7_INDEX,
#endif
#ifdef BSP_USING_BTIM8
BTIM8_INDEX,
#endif
#ifdef BSP_USING_BTIM9
BTIM9_INDEX,
#endif
#ifdef BSP_USING_BTIM10
BTIM10_INDEX,
#endif
#ifdef BSP_USING_BTIM11
BTIM11_INDEX,
#endif
};
static struct swm_hwtimer_cfg swm_hwtimer_cfg[] =
{
#ifdef BSP_USING_TIM0
TIM0_CFG,
#endif
#ifdef BSP_USING_TIM1
TIM1_CFG,
#endif
#ifdef BSP_USING_TIM2
TIM2_CFG,
#endif
#ifdef BSP_USING_TIM3
TIM3_CFG,
#endif
#ifdef BSP_USING_TIM4
TIM4_CFG,
#endif
#ifdef BSP_USING_BTIM0
BTIM0_CFG,
#endif
#ifdef BSP_USING_BTIM1
BTIM1_CFG,
#endif
#ifdef BSP_USING_BTIM2
BTIM2_CFG,
#endif
#ifdef BSP_USING_BTIM3
BTIM3_CFG,
#endif
#ifdef BSP_USING_BTIM4
BTIM4_CFG,
#endif
#ifdef BSP_USING_BTIM5
BTIM5_CFG,
#endif
#ifdef BSP_USING_BTIM6
BTIM6_CFG,
#endif
#ifdef BSP_USING_BTIM7
BTIM7_CFG,
#endif
#ifdef BSP_USING_BTIM8
BTIM8_CFG,
#endif
#ifdef BSP_USING_BTIM9
BTIM9_CFG,
#endif
#ifdef BSP_USING_BTIM10
BTIM10_CFG,
#endif
#ifdef BSP_USING_BTIM11
BTIM11_CFG,
#endif
};
static struct swm_hwtimer_device hwtimer_obj[sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0])] = {0};
static void swm_timer_configure(struct rt_hwtimer_device *timer_device, rt_uint32_t state)
{
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
RT_ASSERT(timer_device != RT_NULL);
if (state)
{
hwtimer_cfg = timer_device->parent.user_data;
TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, CyclesPerUs, 1000000, 1);
timer_device->freq = 1000000;
}
}
static rt_err_t swm_timer_start(rt_hwtimer_t *timer_device, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
{
rt_err_t result = RT_EOK;
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
RT_ASSERT(timer_device != RT_NULL);
hwtimer_cfg = timer_device->parent.user_data;
if (opmode == HWTIMER_MODE_ONESHOT)
{
/* set timer to single mode */
timer_device->mode = HWTIMER_MODE_ONESHOT;
}
else
{
timer_device->mode = HWTIMER_MODE_PERIOD;
}
hwtimer_cfg->TIMRx->LOAD = cnt - 1;
TIMR_Stop(hwtimer_cfg->TIMRx);
TIMR_Start(hwtimer_cfg->TIMRx);
return result;
}
static void swm_timer_stop(rt_hwtimer_t *timer_device)
{
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
RT_ASSERT(timer_device != RT_NULL);
hwtimer_cfg = timer_device->parent.user_data;
/* stop timer */
TIMR_Stop(hwtimer_cfg->TIMRx);
}
static rt_uint32_t swm_timer_count_get(rt_hwtimer_t *timer_device)
{
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
RT_ASSERT(timer_device != RT_NULL);
hwtimer_cfg = timer_device->parent.user_data;
return TIMR_GetCurValue(hwtimer_cfg->TIMRx);
}
static rt_err_t swm_timer_control(rt_hwtimer_t *timer_device, rt_uint32_t cmd, void *args)
{
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
rt_err_t result = RT_EOK;
RT_ASSERT(timer_device != RT_NULL);
RT_ASSERT(args != RT_NULL);
hwtimer_cfg = timer_device->parent.user_data;
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
{
rt_uint32_t freq;
freq = *(rt_uint32_t *)args;
TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, CyclesPerUs, freq, 1);
}
break;
default:
{
result = -RT_ENOSYS;
}
break;
}
return result;
}
static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
static struct rt_hwtimer_ops swm_timer_ops =
{
.init = swm_timer_configure,
.start = swm_timer_start,
.stop = swm_timer_stop,
.count_get = swm_timer_count_get,
.control = swm_timer_control};
void swm_timer_isr(rt_hwtimer_t *timer_device)
{
struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
RT_ASSERT(timer_device != RT_NULL);
hwtimer_cfg = timer_device->parent.user_data;
TIMR_INTClr(hwtimer_cfg->TIMRx);
rt_device_hwtimer_isr(timer_device);
}
#ifdef BSP_USING_TIM0
void TIMR0_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[TIM0_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_TIM0
#ifdef BSP_USING_TIM1
void TIMR1_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[TIM1_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_TIM1
#ifdef BSP_USING_TIM2
void TIMR2_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[TIM2_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_TIM2
#ifdef BSP_USING_TIM3
void TIMR3_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[TIM3_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_TIM3
#ifdef BSP_USING_TIM4
void TIMR4_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[TIM4_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_TIM4
#ifdef BSP_USING_BTIM0
void BTIMR0_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM0_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM0
#ifdef BSP_USING_BTIM1
void BTIMR1_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM1_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM1
#ifdef BSP_USING_BTIM2
void BTIMR2_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM2_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM2
#ifdef BSP_USING_BTIM3
void BTIMR3_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM3_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM3
#ifdef BSP_USING_BTIM4
void BTIMR4_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM4_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM4
#ifdef BSP_USING_BTIM5
void BTIMR5_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM5_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM5
#ifdef BSP_USING_BTIM6
void BTIMR6_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM6_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM6
#ifdef BSP_USING_BTIM7
void BTIMR7_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM7_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM7
#ifdef BSP_USING_BTIM8
void BTIMR8_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM8_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM8
#ifdef BSP_USING_BTIM9
void BTIMR9_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM9_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM9
#ifdef BSP_USING_BTIM10
void BTIMR10_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM10_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM10
#ifdef BSP_USING_BTIM11
void BTIMR11_Handler(void)
{
rt_interrupt_enter();
swm_timer_isr(&(hwtimer_obj[BTIM11_INDEX].time_device));
rt_interrupt_leave();
}
#endif // BSP_USING_BTIM11
int swm_timer_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0]); i++)
{
hwtimer_obj[i].hwtimer_cfg = &swm_hwtimer_cfg[i];
hwtimer_obj[i].time_device.info = &_info;
hwtimer_obj[i].time_device.ops = &swm_timer_ops;
result = rt_device_hwtimer_register(&hwtimer_obj[i].time_device, hwtimer_obj[i].hwtimer_cfg->name, hwtimer_obj[i].hwtimer_cfg);
if (result != RT_EOK)
{
LOG_E("%s register fail.", hwtimer_obj[i].hwtimer_cfg->name);
}
else
{
LOG_D("%s register success.", hwtimer_obj[i].hwtimer_cfg->name);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_timer_init);
#endif /* BSP_USING_TIM */
#endif /* RT_USING_HWTIMER */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_HWTIMER_H__
#define __DRV_HWTIMER_H__
#include "board.h"
int swm_timer_init(void);
#endif /* __DRV_HWTIMER_H__ */

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-15 SummerGift first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>

View File

@ -0,0 +1,408 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_pwm.h"
#ifdef RT_USING_PWM
#ifdef BSP_USING_PWM
//#define DRV_DEBUG
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#if !defined(BSP_USING_PWM0) && !defined(BSP_USING_PWM1) && !defined(BSP_USING_PWM2) && !defined(BSP_USING_PWM3) && !defined(BSP_USING_PWM4)
#error "Please define at least one BSP_USING_PWMx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#define MIN_PERIOD 2
#define MIN_PULSE 1
#ifdef BSP_USING_PWM0
#ifndef PWM0_CFG
#define PWM0_CFG \
{ \
.name = "pwm0", \
.PWMx = PWM0, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM0_MSK, \
}
#endif /* PWM0_CFG */
#endif /* BSP_USING_PWM0 */
#ifdef BSP_USING_PWM1
#ifndef PWM1_CFG
#define PWM1_CFG \
{ \
.name = "pwm1", \
.PWMx = PWM1, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM1_MSK, \
}
#endif /* PWM1_CFG */
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM2
#ifndef PWM2_CFG
#define PWM2_CFG \
{ \
.name = "pwm2", \
.PWMx = PWM2, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM2_MSK, \
}
#endif /* PWM2_CFG */
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
#ifndef PWM3_CFG
#define PWM3_CFG \
{ \
.name = "pwm3", \
.PWMx = PWM3, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM3_MSK, \
}
#endif /* PWM3_CFG */
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
#ifndef PWM4_CFG
#define PWM4_CFG \
{ \
.name = "pwm4", \
.PWMx = PWM4, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM4_MSK, \
}
#endif /* PWM4_CFG */
#endif /* BSP_USING_PWM4 */
struct swm_pwm_cfg
{
const char *name;
PWM_TypeDef *PWMx;
PWM_InitStructure pwm_initstruct;
uint32_t pwm_mask;
};
struct swm_pwm_device
{
struct swm_pwm_cfg *pwm_cfg;
struct rt_device_pwm pwm_device;
};
static struct swm_pwm_cfg swm_pwm_cfg[] =
{
#ifdef BSP_USING_PWM0
PWM0_CFG,
#endif
#ifdef BSP_USING_PWM1
PWM1_CFG,
#endif
#ifdef BSP_USING_PWM2
PWM2_CFG,
#endif
#ifdef BSP_USING_PWM3
PWM3_CFG,
#endif
#ifdef BSP_USING_PWM4
PWM4_CFG,
#endif
};
static struct swm_pwm_device pwm_obj[sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0])] = {0};
static rt_err_t swm_pwm_enable(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
if (!enable)
{
PWM_Stop(pwm_cfg->pwm_mask);
}
else
{
PWM_Start(pwm_cfg->pwm_mask);
}
return RT_EOK;
}
static rt_err_t swm_pwm_get(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
{
rt_uint64_t tim_clock;
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
configuration->period = PWM_GetPeriod(pwm_cfg->PWMx) * 1000UL; //中心对称模式下频率降低一半
configuration->pulse = PWM_GetHDuty(pwm_cfg->PWMx, configuration->channel) * 1000UL;
return RT_EOK;
}
static rt_err_t swm_pwm_set(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
{
rt_uint32_t period, pulse;
rt_uint64_t tim_clock;
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
period = (unsigned long long)configuration->period / 1000UL; //中心对称模式下频率降低一半
pulse = (unsigned long long)configuration->pulse / 1000UL;
if (period < MIN_PERIOD)
{
period = MIN_PERIOD;
}
if (pulse < MIN_PULSE)
{
pulse = MIN_PULSE;
}
PWM_SetPeriod(pwm_cfg->PWMx, period);
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_A, pulse);
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_B, pulse);
return RT_EOK;
}
static rt_err_t swm_pwm_control(struct rt_device_pwm *pwm_device, int cmd, void *arg)
{
RT_ASSERT(pwm_device != RT_NULL);
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
switch (cmd)
{
case PWM_CMD_ENABLE:
return swm_pwm_enable(pwm_device, configuration, RT_TRUE);
case PWM_CMD_DISABLE:
return swm_pwm_enable(pwm_device, configuration, RT_FALSE);
case PWM_CMD_SET:
return swm_pwm_set(pwm_device, configuration);
case PWM_CMD_GET:
return swm_pwm_get(pwm_device, configuration);
default:
return RT_EINVAL;
}
}
static struct rt_pwm_ops pwm_ops =
{
.control = swm_pwm_control};
int swm_pwm_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0]); i++)
{
pwm_obj[i].pwm_cfg = &swm_pwm_cfg[i];
if (pwm_obj[i].pwm_cfg->PWMx == PWM0)
{
#ifdef BSP_USING_PWM0A
PORT_Init(PORTM, PIN1, PORTM_PIN1_PWM0A, 0);
#endif
#ifdef BSP_USING_PWM0AN
PORT_Init(PORTM, PIN4, PORTM_PIN4_PWM0AN, 0);
#endif
#ifdef BSP_USING_PWM0B
PORT_Init(PORTM, PIN2, PORTM_PIN2_PWM0B, 0);
#endif
#ifdef BSP_USING_PWM0BN
PORT_Init(PORTM, PIN5, PORTM_PIN5_PWM0BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM1)
{
#ifdef BSP_USING_PWM1A
PORT_Init(PORTM, PIN3, PORTM_PIN3_PWM1A, 0);
#endif
#ifdef BSP_USING_PWM1AN
PORT_Init(PORTM, PIN6, PORTM_PIN6_PWM1AN, 0);
#endif
#ifdef BSP_USING_PWM1B
PORT_Init(PORTD, PIN9, PORTD_PIN9_PWM1B, 0);
#endif
#ifdef BSP_USING_PWM1BN
PORT_Init(PORTD, PIN8, PORTD_PIN8_PWM1BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM2)
{
#ifdef BSP_USING_PWM2A
PORT_Init(PORTM, PIN12, PORTM_PIN12_PWM2A, 0);
#endif
#ifdef BSP_USING_PWM2AN
PORT_Init(PORTM, PIN9, PORTM_PIN9_PWM2AN, 0);
#endif
#ifdef BSP_USING_PWM2B
PORT_Init(PORTM, PIN11, PORTM_PIN11_PWM2B, 0);
#endif
#ifdef BSP_USING_PWM2BN
PORT_Init(PORTM, PIN8, PORTM_PIN8_PWM2BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM3)
{
#ifdef BSP_USING_PWM3A
PORT_Init(PORTC, PIN2, PORTC_PIN2_PWM3A, 0);
#endif
#ifdef BSP_USING_PWM3AN
PORT_Init(PORTC, PIN3, PORTC_PIN3_PWM3AN, 0);
#endif
#ifdef BSP_USING_PWM3B
PORT_Init(PORTB, PIN1, PORTB_PIN1_PWM3B, 0);
#endif
#ifdef BSP_USING_PWM3BN
PORT_Init(PORTB, PIN0, PORTB_PIN0_PWM3BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM4)
{
#ifdef BSP_USING_PWM4A
PORT_Init(PORTB, PIN15, PORTB_PIN15_PWM4A, 0);
#endif
#ifdef BSP_USING_PWM4AN
// PORT_Init(PORTB, PIN14, PORTB_PIN14_PWM4AN, 0); //SWDIO
#endif
#ifdef BSP_USING_PWM4B
PORT_Init(PORTB, PIN13, PORTB_PIN13_PWM4B, 0);
#endif
#ifdef BSP_USING_PWM4BN
// PORT_Init(PORTB, PIN12, PORTB_PIN12_PWM4BN, 0); //SWDCK
#endif
}
pwm_obj[i].pwm_cfg->pwm_initstruct.Clkdiv = SystemCoreClock / 1000000UL / 2; //中心对称模式下频率降低一半
PWM_Init(pwm_obj[i].pwm_cfg->PWMx, &(pwm_obj[i].pwm_cfg->pwm_initstruct));
result = rt_device_pwm_register(&pwm_obj[i].pwm_device, pwm_obj[i].pwm_cfg->name, &pwm_ops, pwm_obj[i].pwm_cfg);
if(result != RT_EOK)
{
LOG_E("%s register fail.", pwm_obj[i].pwm_cfg->name);
}
else
{
LOG_D("%s register success.", pwm_obj[i].pwm_cfg->name);
}
}
return result;
}
INIT_DEVICE_EXPORT(swm_pwm_init);
#endif /* BSP_USING_PWM */
#endif /* RT_USING_PWM */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_PWM_H__
#define __DRV_PWM_H__
#include "board.h"
int swm_pwm_init(void);
#endif /* __DRV_PWM_H__ */

View File

@ -0,0 +1,230 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-25 lik first version
*/
#include "drv_rgb_lcd.h"
#ifdef BSP_USING_RGB_LCD
#include "rgb_lcd_port.h"
#define DRV_DEBUG
#define LOG_TAG "drv.rgb_lcd"
#include <drv_log.h>
#define LCD_DEVICE(dev) (struct swm_rgb_lcd_device *)(dev)
struct swm_rgb_lcd_device rgb_lcd_obj;
static rt_err_t swm_rgb_lcd_configure(struct rt_device *device)
{
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
/* nothing, right now */
rgb_lcd = rgb_lcd;
return RT_EOK;
}
static rt_err_t swm_rgb_lcd_control(struct rt_device *device, int cmd, void *args)
{
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
RT_ASSERT(info != RT_NULL);
info->pixel_format = rgb_lcd->lcd_info.pixel_format;
info->bits_per_pixel = rgb_lcd->lcd_info.bits_per_pixel;
info->width = rgb_lcd->lcd_info.width;
info->height = rgb_lcd->lcd_info.height;
info->framebuffer = rgb_lcd->lcd_info.framebuffer;
}
break;
default:
return -RT_EINVAL;
}
return RT_EOK;
}
#if defined(LCD_BACKLIGHT_USING_PWM)
static void turn_on_lcd_backlight(void)
{
struct rt_device_pwm *pwm_dev;
/* turn on the LCD backlight */
pwm_dev = (struct rt_device_pwm *)rt_device_find(LCD_PWM_DEV_NAME);
/* pwm frequency:100K = 10000ns */
rt_pwm_set(pwm_dev, LCD_PWM_DEV_CHANNEL, 10000, 10000);
rt_pwm_enable(pwm_dev, LCD_PWM_DEV_CHANNEL);
}
#elif defined(LCD_BACKLIGHT_USING_GPIO)
static void turn_on_lcd_backlight(void)
{
rt_pin_mode(LCD_DISP_GPIO, PIN_MODE_OUTPUT);
rt_pin_write(LCD_DISP_GPIO, PIN_HIGH);
rt_pin_mode(LCD_BL_GPIO, PIN_MODE_OUTPUT);
rt_pin_write(LCD_BL_GPIO, PIN_HIGH);
}
#else
static void turn_on_lcd_backlight(void)
{
}
#endif
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops swm_lcd_ops =
{
.init = swm_rgb_lcd_configure,
.open = RT_NULL,
.close = RT_NULL,
.read = RT_NULL,
.write = RT_NULL,
.control = swm_rgb_lcd_control};
#endif
int swm_rgb_lcd_init(void)
{
rt_err_t result = RT_EOK;
struct rt_device *device = &rgb_lcd_obj.parent;
/* memset rgb_lcd_obj to zero */
memset(&rgb_lcd_obj, 0x00, sizeof(rgb_lcd_obj));
/* config LCD dev info */
rgb_lcd_obj.lcd_info.height = LCD_HEIGHT;
rgb_lcd_obj.lcd_info.width = LCD_WIDTH;
rgb_lcd_obj.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
rgb_lcd_obj.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
/* malloc memory for Triple Buffering */
rgb_lcd_obj.lcd_info.framebuffer = rt_malloc_align(LCD_BUF_SIZE,4);
if (rgb_lcd_obj.lcd_info.framebuffer == RT_NULL)
{
LOG_E("init frame buffer failed!\n");
result = -RT_ENOMEM;
goto __exit;
}
/* memset buff to 0xFF */
memset(rgb_lcd_obj.lcd_info.framebuffer, 0xFF, LCD_BUF_SIZE);
device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
device->ops = &swm_lcd_ops;
#else
device->init = swm_rgb_lcd_configure;
device->control = swm_rgb_lcd_control;
#endif
/* register lcd device */
rt_device_register(device, "rgb_lcd", RT_DEVICE_FLAG_RDWR);
LCD_InitStructure LCD_initStruct;
// PORT_Init(PORTB, PIN1, PORTB_PIN1_LCD_B0, 0);
// PORT_Init(PORTB, PIN11, PORTB_PIN11_LCD_B1, 0);
// PORT_Init(PORTB, PIN13, PORTB_PIN13_LCD_B2, 0);
PORT_Init(PORTB, PIN15, PORTB_PIN15_LCD_B3, 0);
PORT_Init(PORTA, PIN2, PORTA_PIN2_LCD_B4, 0);
PORT_Init(PORTA, PIN9, PORTA_PIN9_LCD_B5, 0);
PORT_Init(PORTA, PIN10, PORTA_PIN10_LCD_B6, 0);
PORT_Init(PORTA, PIN11, PORTA_PIN11_LCD_B7, 0);
// PORT_Init(PORTA, PIN12, PORTA_PIN12_LCD_G0, 0);
// PORT_Init(PORTA, PIN13, PORTA_PIN13_LCD_G1, 0);
PORT_Init(PORTA, PIN14, PORTA_PIN14_LCD_G2, 0);
PORT_Init(PORTA, PIN15, PORTA_PIN15_LCD_G3, 0);
PORT_Init(PORTC, PIN0, PORTC_PIN0_LCD_G4, 0);
PORT_Init(PORTC, PIN1, PORTC_PIN1_LCD_G5, 0);
PORT_Init(PORTC, PIN2, PORTC_PIN2_LCD_G6, 0);
PORT_Init(PORTC, PIN3, PORTC_PIN3_LCD_G7, 0);
// PORT_Init(PORTC, PIN4, PORTC_PIN4_LCD_R0, 0);
// PORT_Init(PORTC, PIN5, PORTC_PIN5_LCD_R1, 0);
// PORT_Init(PORTC, PIN8, PORTC_PIN8_LCD_R2, 0);
PORT_Init(PORTC, PIN9, PORTC_PIN9_LCD_R3, 0);
PORT_Init(PORTC, PIN10, PORTC_PIN10_LCD_R4, 0);
PORT_Init(PORTC, PIN11, PORTC_PIN11_LCD_R5, 0);
PORT_Init(PORTC, PIN12, PORTC_PIN12_LCD_R6, 0);
PORT_Init(PORTC, PIN13, PORTC_PIN13_LCD_R7, 0);
PORT_Init(PORTB, PIN2, PORTB_PIN2_LCD_VSYNC, 0);
PORT_Init(PORTB, PIN3, PORTB_PIN3_LCD_HSYNC, 0);
PORT_Init(PORTB, PIN4, PORTB_PIN4_LCD_DEN, 0);
PORT_Init(PORTB, PIN5, PORTB_PIN5_LCD_DCLK, 0);
LCD_initStruct.ClkDiv = LCD_CLK_DIV;
LCD_initStruct.Format = ((LCD_BITS_PER_PIXEL == 16) ? LCD_FMT_RGB565 : LCD_FMT_RGB888);
LCD_initStruct.HnPixel = LCD_WIDTH;
LCD_initStruct.VnPixel = LCD_HEIGHT;
LCD_initStruct.Hfp = LCD_HFP;
LCD_initStruct.Hbp = LCD_HBP;
LCD_initStruct.Vfp = LCD_VFP;
LCD_initStruct.Vbp = LCD_VBP;
LCD_initStruct.HsyncWidth = LCD_HSYNC_WIDTH;
LCD_initStruct.VsyncWidth = LCD_VSYNC_WIDTH;
LCD_initStruct.DataSource = (uint32_t)rgb_lcd_obj.lcd_info.framebuffer;
LCD_initStruct.Background = 0xFFFFFF;
LCD_initStruct.SampleEdge = LCD_SAMPLE_FALL;
LCD_initStruct.IntEOTEn = 0;
LCD_Init(LCD, &LCD_initStruct);
LCD_Start(LCD);
turn_on_lcd_backlight();
__exit:
if (result != RT_EOK)
{
if (rgb_lcd_obj.lcd_info.framebuffer)
{
rt_free(rgb_lcd_obj.lcd_info.framebuffer);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_rgb_lcd_init);
int lcd_test(void)
{
struct swm_rgb_lcd_device *rgb_lcd;
rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
// while (1)
{
/* red */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x00;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* green */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0xE0;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* blue */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x1F;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
}
return 0;
}
MSH_CMD_EXPORT(lcd_test, lcd_test);
#endif /* BSP_USING_RGB_LCD */

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_RGB_LCD_H__
#define __DRV_RGB_LCD_H__
#include "board.h"
struct swm_rgb_lcd_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
};
int swm_rgb_lcd_init(void);
#endif /* __DRV_RGB_LCD_H__ */

View File

@ -0,0 +1,191 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_rtc.h"
#ifdef RT_USING_RTC
#ifdef BSP_USING_RTC
//#define DRV_DEBUG
#define LOG_TAG "drv.rtc"
#include <drv_log.h>
static struct rt_device rtc_device;
static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
{
uint32_t i, cnt = 0;
const uint32_t daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (i = 1; i < month; i++)
cnt += daysOfMonth[i];
cnt += date;
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) && (month >= 3))
cnt += 1;
cnt += (year - 1901) * 365;
for (i = 1901; i < year; i++)
{
if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
cnt += 1;
}
return (cnt + 1) % 7;
}
static time_t swm_get_rtc_time_stamp(void)
{
RTC_DateTime get_datetime = {0};
struct tm tm_new;
RTC_GetDateTime(RTC, &get_datetime);
tm_new.tm_sec = get_datetime.Second;
tm_new.tm_min = get_datetime.Minute;
tm_new.tm_hour = get_datetime.Hour;
tm_new.tm_mday = get_datetime.Date;
tm_new.tm_mon = get_datetime.Month - 1;
tm_new.tm_year = get_datetime.Year - 1900;
LOG_D("get rtc time.");
return mktime(&tm_new);
}
static rt_err_t swm_set_rtc_time_stamp(time_t time_stamp)
{
RTC_DateTime set_datetime = {0};
struct tm *p_tm;
p_tm = gmtime(&time_stamp);
set_datetime.Second = p_tm->tm_sec;
set_datetime.Minute = p_tm->tm_min;
set_datetime.Hour = p_tm->tm_hour;
set_datetime.Date = p_tm->tm_mday;
set_datetime.Month = p_tm->tm_mon + 1;
set_datetime.Year = p_tm->tm_year + 1900;
// set_datetime.Day = p_tm->tm_wday;
RTC_Stop(RTC);
while (RTC->CFGABLE == 0)
;
RTC->MINSEC = (set_datetime.Second << RTC_MINSEC_SEC_Pos) |
(set_datetime.Minute << RTC_MINSEC_MIN_Pos);
RTC->DATHUR = (set_datetime.Hour << RTC_DATHUR_HOUR_Pos) |
((set_datetime.Date) << RTC_DATHUR_DATE_Pos);
RTC->MONDAY = (calcWeekDay(set_datetime.Year, set_datetime.Month, set_datetime.Date)
<< RTC_MONDAY_DAY_Pos) |
((set_datetime.Month) << RTC_MONDAY_MON_Pos);
RTC->YEAR = set_datetime.Year;
RTC->LOAD = 1 << RTC_LOAD_TIME_Pos;
RTC_Start(RTC);
LOG_D("set rtc time.");
return RT_EOK;
}
static rt_err_t swm_rtc_control(rt_device_t rtc_device, int cmd, void *args)
{
rt_err_t result = RT_EOK;
RT_ASSERT(rtc_device != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
*(rt_uint32_t *)args = swm_get_rtc_time_stamp();
LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
if (swm_set_rtc_time_stamp(*(rt_uint32_t *)args))
{
result = -RT_ERROR;
}
LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
break;
default:
break;
}
return result;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops swm_rtc_ops =
{
.init = RT_NULL,
.open = RT_NULL,
.close = RT_NULL,
.read = RT_NULL,
.write = RT_NULL,
.control = swm_rtc_control};
#endif
static void swm_rtc_configure(void)
{
RTC_InitStructure rtc_initstruct;
rtc_initstruct.clksrc = RTC_CLKSRC_XTAL32K;
rtc_initstruct.Year = 2020;
rtc_initstruct.Month = 2;
rtc_initstruct.Date = 29;
rtc_initstruct.Hour = 23;
rtc_initstruct.Minute = 59;
rtc_initstruct.Second = 55;
rtc_initstruct.SecondIEn = 0;
rtc_initstruct.MinuteIEn = 0;
RTC_Init(RTC, &rtc_initstruct);
RTC_Start(RTC);
}
static rt_err_t swm_onchip_rtc_register(rt_device_t rtc_device, const char *name, rt_uint32_t flag)
{
RT_ASSERT(rtc_device != RT_NULL);
swm_rtc_configure();
#ifdef RT_USING_DEVICE_OPS
rtc_device->ops = &swm_rtc_ops;
#else
rtc_device->init = RT_NULL;
rtc_device->open = RT_NULL;
rtc_device->close = RT_NULL;
rtc_device->read = RT_NULL;
rtc_device->write = RT_NULL;
rtc_device->control = swm_rtc_control;
#endif
rtc_device->type = RT_Device_Class_RTC;
rtc_device->rx_indicate = RT_NULL;
rtc_device->tx_complete = RT_NULL;
rtc_device->user_data = RT_NULL;
/* register a character device */
return rt_device_register(rtc_device, name, flag);
}
int swm_rtc_init(void)
{
rt_err_t result;
result = swm_onchip_rtc_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
if (result != RT_EOK)
{
LOG_E("rtc register fail.");
}
else
{
LOG_D("rtc register success.");
}
return result;
}
INIT_DEVICE_EXPORT(swm_rtc_init);
#endif /* BSP_USING_RTC */
#endif /* RT_USING_RTC */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_RTC_H__
#define __DRV_RTC_H__
#include "board.h"
#include "sys/time.h"
int swm_rtc_init(void);
#endif /* __DRV_RTC_H__ */

View File

@ -0,0 +1,705 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_sdio.h"
#ifdef RT_USING_SDIO
#ifdef BSP_USING_SDIO
//#define DRV_DEBUG
#define LOG_TAG "drv.sdio"
#include <drv_log.h>
#define SDIO_BUFF_SIZE 4096
#define SDIO_ALIGN_LEN 4
#ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (42000000)
#endif
struct swm_sdio_pkg
{
struct rt_mmcsd_cmd *cmd;
void *buff;
rt_uint32_t flag;
};
typedef rt_err_t (*sdio_txconfig)(struct swm_sdio_pkg *pkg, rt_uint32_t *buff, int size);
typedef rt_err_t (*sdio_rxconfig)(struct swm_sdio_pkg *pkg, rt_uint32_t *buff, int size);
typedef rt_uint32_t (*sdio_clk_get)(SDIO_TypeDef *swm_sdio);
struct swm_sdio_des
{
SDIO_TypeDef *swm_sdio;
sdio_txconfig txconfig;
sdio_rxconfig rxconfig;
sdio_clk_get clk_get;
};
static struct rt_mmcsd_host *host;
#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER)
#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
struct swm_sdio_device
{
struct rt_mmcsd_host *host;
struct swm_sdio_des sdio_des;
struct rt_event event;
struct rt_mutex mutex;
struct swm_sdio_pkg *pkg;
};
ALIGN(SDIO_ALIGN_LEN)
static rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
/**
* @brief This function wait sdio completed.
* @param sdio swm_sdio_device
* @retval None
*/
static void swm_sdio_wait_completed(struct swm_sdio_device *sdio)
{
rt_uint32_t status;
struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
SDIO_TypeDef *swm_sdio = sdio->sdio_des.swm_sdio;
if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
rt_tick_from_millisecond(2000), &status) != RT_EOK)
{
LOG_E("wait completed timeout");
cmd->err = -RT_ETIMEOUT;
return;
}
if (sdio->pkg == RT_NULL)
{
return;
}
if (resp_type(cmd) == RESP_NONE)
{
;
}
else if (resp_type(cmd) == RESP_R2)
{
LOG_I("R2");
cmd->resp[0] = (swm_sdio->RESP[3] << 8) + ((swm_sdio->RESP[2] >> 24) & 0xFF);
cmd->resp[1] = (swm_sdio->RESP[2] << 8) + ((swm_sdio->RESP[1] >> 24) & 0xFF);
cmd->resp[2] = (swm_sdio->RESP[1] << 8) + ((swm_sdio->RESP[0] >> 24) & 0xFF);
cmd->resp[3] = (swm_sdio->RESP[0] << 8) + 0x00;
}
else
{
cmd->resp[0] = swm_sdio->RESP[0];
}
if (status & SDIO_IF_ERROR_Msk)
{
if ((status & SDIO_IF_CMDCRCERR_Msk) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
{
cmd->err = RT_EOK;
}
else
{
cmd->err = -RT_ERROR;
}
if (status & SDIO_IF_CMDTIMEOUT_Msk)
{
cmd->err = -RT_ETIMEOUT;
}
if (status & SDIO_IF_DATCRCERR_Msk)
{
data->err = -RT_ERROR;
}
if (status & SDIO_IF_DATTIMEOUT_Msk)
{
data->err = -RT_ETIMEOUT;
}
if (cmd->err == RT_EOK)
{
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
}
else
{
LOG_D("err:0x%08x, %s cmd:%d arg:0x%08x rw:%c len:%d blksize:%d",
status,
status == 0 ? "NULL" : "",
cmd->cmd_code,
cmd->arg,
data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
data ? data->blks * data->blksize : 0,
data ? data->blksize : 0);
}
}
else
{
cmd->err = RT_EOK;
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
}
}
/**
* @brief This function transfer data by dma.
* @param sdio swm_sdio_device
* @param pkg sdio package
* @retval None
*/
static void swm_sdio_transfer(struct swm_sdio_device *sdio, struct swm_sdio_pkg *pkg)
{
struct rt_mmcsd_data *data;
int size;
void *buff;
if ((RT_NULL == pkg) || (RT_NULL == sdio))
{
LOG_E("swm_sdio_transfer invalid args");
return;
}
data = pkg->cmd->data;
if (RT_NULL == data)
{
LOG_E("swm_sdio_transfer invalid args");
return;
}
buff = pkg->buff;
if (RT_NULL == buff)
{
LOG_E("swm_sdio_transfer invalid args");
return;
}
size = data->blks * data->blksize;
if (data->flags & DATA_DIR_WRITE)
{
sdio->sdio_des.txconfig(pkg, (rt_uint32_t *)buff, size);
}
else if (data->flags & DATA_DIR_READ)
{
sdio->sdio_des.rxconfig(pkg, (rt_uint32_t *)buff, size);
}
}
/**
* @brief This function send command.
* @param sdio swm_sdio_device
* @param pkg sdio package
* @retval None
*/
static void swm_sdio_send_command(struct swm_sdio_device *sdio, struct swm_sdio_pkg *pkg)
{
struct rt_mmcsd_cmd *cmd = pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
SDIO_TypeDef *swm_sdio = sdio->sdio_des.swm_sdio;
rt_uint32_t reg_cmd;
/* save pkg */
sdio->pkg = pkg;
LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d",
cmd->cmd_code,
cmd->arg,
resp_type(cmd) == RESP_NONE ? "NONE" : "",
resp_type(cmd) == RESP_R1 ? "R1" : "",
resp_type(cmd) == RESP_R1B ? "R1B" : "",
resp_type(cmd) == RESP_R2 ? "R2" : "",
resp_type(cmd) == RESP_R3 ? "R3" : "",
resp_type(cmd) == RESP_R4 ? "R4" : "",
resp_type(cmd) == RESP_R5 ? "R5" : "",
resp_type(cmd) == RESP_R6 ? "R6" : "",
resp_type(cmd) == RESP_R7 ? "R7" : "",
data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
data ? data->blks * data->blksize : 0,
data ? data->blksize : 0);
/* config cmd reg */
reg_cmd = (cmd->cmd_code << SDIO_CMD_CMDINDX_Pos) |
(0 << SDIO_CMD_CMDTYPE_Pos) |
(0 << SDIO_CMD_IDXCHECK_Pos) |
(0 << SDIO_CMD_CRCCHECK_Pos) |
(0 << SDIO_CMD_DMAEN_Pos);
if (resp_type(cmd) == RESP_NONE)
reg_cmd |= SD_RESP_NO << SDIO_CMD_RESPTYPE_Pos;
else if (resp_type(cmd) == RESP_R2)
reg_cmd |= SD_RESP_128b << SDIO_CMD_RESPTYPE_Pos;
else
reg_cmd |= SD_RESP_32b << SDIO_CMD_RESPTYPE_Pos;
/* config data reg */
if (data != RT_NULL)
{
rt_uint32_t dir = 0;
dir = (data->flags & DATA_DIR_READ) ? 1 : 0;
swm_sdio->BLK = (data->blks << SDIO_BLK_COUNT_Pos) | (data->blksize << SDIO_BLK_SIZE_Pos);
reg_cmd |= (1 << SDIO_CMD_HAVEDATA_Pos) |
(dir << SDIO_CMD_DIRREAD_Pos) |
((data->blks > 1) << SDIO_CMD_MULTBLK_Pos) |
((data->blks > 1) << SDIO_CMD_BLKCNTEN_Pos) |
(0 << SDIO_CMD_AUTOCMD12_Pos);
}
else
{
reg_cmd |= (0 << SDIO_CMD_HAVEDATA_Pos);
}
if (cmd->cmd_code != SD_IO_SEND_OP_COND)
{
/* send cmd */
swm_sdio->ARG = cmd->arg;
swm_sdio->CMD = reg_cmd;
}
/* transfer config */
if (data != RT_NULL)
{
swm_sdio_transfer(sdio, pkg);
}
/* wait completed */
swm_sdio_wait_completed(sdio);
/* clear pkg */
sdio->pkg = RT_NULL;
}
/**
* @brief This function send sdio request.
* @param sdio swm_sdio_device
* @param req request
* @retval None
*/
static void swm_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
{
struct swm_sdio_pkg pkg;
struct swm_sdio_device *sdio = host->private_data;
struct rt_mmcsd_data *data;
RTHW_SDIO_LOCK(sdio);
if (req->cmd != RT_NULL)
{
rt_memset(&pkg, 0, sizeof(pkg));
data = req->cmd->data;
pkg.cmd = req->cmd;
if (data != RT_NULL)
{
rt_uint32_t size = data->blks * data->blksize;
RT_ASSERT(size <= SDIO_BUFF_SIZE);
pkg.buff = data->buf;
if ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1))
{
pkg.buff = cache_buf;
if (data->flags & DATA_DIR_WRITE)
{
rt_memcpy(cache_buf, data->buf, size);
}
}
}
swm_sdio_send_command(sdio, &pkg);
if ((data != RT_NULL) && (data->flags & DATA_DIR_READ) && ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1)))
{
rt_memcpy(data->buf, cache_buf, data->blksize * data->blks);
}
}
if (req->stop != RT_NULL)
{
rt_memset(&pkg, 0, sizeof(pkg));
pkg.cmd = req->stop;
swm_sdio_send_command(sdio, &pkg);
}
RTHW_SDIO_UNLOCK(sdio);
mmcsd_req_complete(sdio->host);
}
/**
* @brief This function config sdio.
* @param host rt_mmcsd_host
* @param io_cfg rt_mmcsd_io_cfg
* @retval None
*/
static void swm_sdio_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
{
rt_uint32_t clkcr, div, clk_src;
rt_uint32_t clk = io_cfg->clock;
struct swm_sdio_device *sdio = host->private_data;
SDIO_TypeDef *swm_sdio = sdio->sdio_des.swm_sdio;
clk_src = sdio->sdio_des.clk_get(sdio->sdio_des.swm_sdio);
if (clk_src < 400 * 1000)
{
LOG_E("The clock rate is too low! rata:%d", clk_src);
return;
}
if (clk > host->freq_max)
clk = host->freq_max;
if (clk > clk_src)
{
LOG_W("Setting rate is greater than clock source rate.");
clk = clk_src;
}
LOG_D("clk:%d width:%s%s%s power:%s%s%s",
clk,
io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "",
io_cfg->power_mode == MMCSD_POWER_OFF ? "OFF" : "",
io_cfg->power_mode == MMCSD_POWER_UP ? "UP" : "",
io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : "");
RTHW_SDIO_LOCK(sdio);
swm_sdio->CR1 = (1 << SDIO_CR1_CDSRC_Pos) | (7 << SDIO_CR1_VOLT_Pos);
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
{
swm_sdio->CR1 |= (1 << SDIO_CR1_8BIT_Pos);
}
else
{
swm_sdio->CR1 &= ~SDIO_CR1_8BIT_Msk;
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
{
swm_sdio->CR1 |= (1 << SDIO_CR1_4BIT_Pos);
}
else
{
swm_sdio->CR1 &= ~SDIO_CR1_4BIT_Msk;
}
}
switch (io_cfg->power_mode)
{
case MMCSD_POWER_OFF:
swm_sdio->CR1 &= ~SDIO_CR1_PWRON_Msk;
break;
case MMCSD_POWER_UP:
case MMCSD_POWER_ON:
swm_sdio->CR1 |= (1 << SDIO_CR1_PWRON_Pos);
break;
default:
LOG_W("unknown power_mode %d", io_cfg->power_mode);
break;
}
div = clk_src / clk;
if ((clk == 0) || (div == 0))
{
clkcr = 0;
}
else
{
if (div > 128)
clkcr = 0x80;
else if (div > 64)
clkcr = 0x40;
else if (div > 32)
clkcr = 0x20;
else if (div > 16)
clkcr = 0x10;
else if (div > 8)
clkcr = 0x08;
else if (div > 4)
clkcr = 0x04;
else if (div > 2)
clkcr = 0x02;
else if (div > 1)
clkcr = 0x01;
else
clkcr = 0x00;
}
SDIO->CR2 = (1 << SDIO_CR2_CLKEN_Pos) |
(1 << SDIO_CR2_SDCLKEN_Pos) |
(clkcr << SDIO_CR2_SDCLKDIV_Pos) |
(0xC << SDIO_CR2_TIMEOUT_Pos); // 2**25 SDIO_CLK
while ((SDIO->CR2 & SDIO_CR2_CLKRDY_Msk) == 0)
;
RTHW_SDIO_UNLOCK(sdio);
}
/**
* @brief This function delect sdcard.
* @param host rt_mmcsd_host
* @retval 0x01
*/
static rt_int32_t swm_sdio_get_card_status(struct rt_mmcsd_host *host)
{
LOG_D("try to detect device");
return 0x01;
}
/**
* @brief This function update sdio interrupt.
* @param host rt_mmcsd_host
* @param enable
* @retval None
*/
void swm_sdio_enable_irq(struct rt_mmcsd_host *host, rt_int32_t enable)
{
struct swm_sdio_device *sdio = host->private_data;
SDIO_TypeDef *swm_sdio = sdio->sdio_des.swm_sdio;
if (enable)
{
LOG_D("enable sdio irq");
swm_sdio->IM = 0xFFFFFFFF;
swm_sdio->IE = 0xFFFF000F;
}
else
{
LOG_D("disable sdio irq");
swm_sdio->IM &= ~0xFFFFFFFF;
swm_sdio->IE &= ~0xFFFFFFFF;
}
}
static const struct rt_mmcsd_host_ops swm_sdio_ops =
{
.request = swm_sdio_request,
.set_iocfg = swm_sdio_set_iocfg,
.get_card_status = swm_sdio_get_card_status,
.enable_sdio_irq = swm_sdio_enable_irq,
};
struct rt_mmcsd_host *swm_sdio_host_create(struct swm_sdio_des *sdio_des)
{
struct rt_mmcsd_host *host;
struct swm_sdio_device *sdio = RT_NULL;
if ((sdio_des == RT_NULL) || (sdio_des->txconfig == RT_NULL) || (sdio_des->rxconfig == RT_NULL))
{
LOG_E("L:%d F:%s %s %s %s",
(sdio_des == RT_NULL ? "sdio_des is NULL" : ""),
(sdio_des ? (sdio_des->txconfig ? "txconfig is NULL" : "") : ""),
(sdio_des ? (sdio_des->rxconfig ? "rxconfig is NULL" : "") : ""));
return RT_NULL;
}
sdio = rt_malloc(sizeof(struct swm_sdio_device));
if (sdio == RT_NULL)
{
LOG_E("L:%d F:%s malloc swm_sdio_device fail");
return RT_NULL;
}
rt_memset(sdio, 0, sizeof(struct swm_sdio_device));
host = mmcsd_alloc_host();
if (host == RT_NULL)
{
LOG_E("L:%d F:%s mmcsd alloc host fail");
rt_free(sdio);
return RT_NULL;
}
rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct swm_sdio_des));
rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO);
rt_mutex_init(&sdio->mutex, "sdio", RT_IPC_FLAG_FIFO);
/* set host defautl attributes */
host->ops = &swm_sdio_ops;
host->freq_min = 400 * 1000;
host->freq_max = SDIO_MAX_FREQ;
host->valid_ocr = 0X00FFFF80; /* The voltage range supported is 1.65v-3.6v */
#ifndef SDIO_USING_1_BIT
host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ;
#else
host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ;
#endif
host->max_seg_size = SDIO_BUFF_SIZE;
host->max_dma_segs = 1;
host->max_blk_size = 512;
host->max_blk_count = 512;
/* link up host and sdio */
sdio->host = host;
host->private_data = sdio;
swm_sdio_enable_irq(host, 1);
/* ready to change */
mmcsd_change(host);
return host;
}
static rt_uint32_t swm_sdio_clock_get(SDIO_TypeDef *swm_sdio)
{
uint32_t prediv;
switch((SYS->CLKSEL & SYS_CLKSEL_SDIO_Msk) >> SYS_CLKSEL_SDIO_Pos)
{
case 0: prediv = 1; break;
case 1: prediv = 3; break;
case 2: prediv = 2; break;
case 3: prediv = 0; break;
}
return (SystemCoreClock / (1 << prediv));
}
static rt_err_t swm_sdio_rxconfig(struct swm_sdio_pkg *pkg, rt_uint32_t *buff, int size)
{
struct rt_mmcsd_cmd *cmd = pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
int offset = 0;
for (uint32_t i = 0; i < data->blks; i++)
{
offset = i* data->blksize / 4;
while ((SDIO->IF & SDIO_IF_BUFRDRDY_Msk) == 0)
__NOP();
SDIO->IF = SDIO_IF_BUFRDRDY_Msk;
for (uint32_t j = 0; j < data->blksize / 4; j++)
{
buff[offset + j] = SDIO->DATA;
}
}
return RT_EOK;
}
static rt_err_t swm_sdio_txconfig(struct swm_sdio_pkg *pkg, rt_uint32_t *buff, int size)
{
struct rt_mmcsd_cmd *cmd = pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
int offset = 0;
for (uint32_t i = 0; i < data->blks; i++)
{
offset = i* data->blksize / 4;
while ((SDIO->IF & SDIO_IF_BUFWRRDY_Msk) == 0)
__NOP();
SDIO->IF = SDIO_IF_BUFWRRDY_Msk;
for (uint32_t j = 0; j < data->blksize / 4; j++)
{
SDIO->DATA = buff[offset + j];
}
}
return RT_EOK;
}
/**
* @brief This function interrupt process function.
* @param host rt_mmcsd_host
* @retval None
*/
static void swm_sdio_irq_process(struct rt_mmcsd_host *host)
{
int complete = 0;
struct swm_sdio_device *sdio = host->private_data;
SDIO_TypeDef *swm_sdio = sdio->sdio_des.swm_sdio;
rt_uint32_t intstatus = swm_sdio->IF;
if (intstatus & SDIO_IF_ERROR_Msk)
{
swm_sdio->IF = 0xFFFFFFFF;
complete = 1;
}
else
{
if (intstatus & SDIO_IF_CMDDONE_Msk)
{
swm_sdio->IF = SDIO_IF_CMDDONE_Msk;
if (sdio->pkg != RT_NULL)
{
if (!sdio->pkg->cmd->data)
{
complete = 1;
}
}
}
if (intstatus & SDIO_IF_TRXDONE_Msk)
{
swm_sdio->IF = SDIO_IF_TRXDONE_Msk;
complete = 1;
}
}
if (complete)
{
rt_event_send(&sdio->event, intstatus);
}
}
void SDIO_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
/* Process All SDIO Interrupt Sources */
swm_sdio_irq_process(host);
/* leave interrupt */
rt_interrupt_leave();
}
int swm_sdio_init(void)
{
int result = RT_EOK;
struct swm_sdio_des sdio_des;
PORT_Init(PORTM, PIN2, PORTM_PIN2_SD_CLK, 0);
PORT_Init(PORTM, PIN4, PORTM_PIN4_SD_CMD, 1);
PORT_Init(PORTM, PIN5, PORTM_PIN5_SD_D0, 1);
PORT_Init(PORTM, PIN6, PORTM_PIN6_SD_D1, 1);
PORT_Init(PORTN, PIN0, PORTN_PIN0_SD_D2, 1);
PORT_Init(PORTN, PIN1, PORTN_PIN1_SD_D3, 1);
NVIC_EnableIRQ(SDIO_IRQn);
SYS->CLKSEL &= ~SYS_CLKSEL_SDIO_Msk;
if (SystemCoreClock > 80000000) //SDIO时钟需要小于52MHz
SYS->CLKSEL |= (2 << SYS_CLKSEL_SDIO_Pos); //SDCLK = SYSCLK / 4
else
SYS->CLKSEL |= (1 << SYS_CLKSEL_SDIO_Pos); //SDCLK = SYSCLK / 2
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_SDIO_Pos);
SDIO->CR2 = (1 << SDIO_CR2_RSTALL_Pos);
NVIC_EnableIRQ(SDIO_IRQn);
sdio_des.clk_get = swm_sdio_clock_get;
sdio_des.swm_sdio = SDIO;
sdio_des.rxconfig = swm_sdio_rxconfig;
sdio_des.txconfig = swm_sdio_txconfig;
host = swm_sdio_host_create(&sdio_des);
if (host == RT_NULL)
{
LOG_E("host create fail.");
result = -1;
}
else
{
LOG_D("host create success.");
result = 0;
}
return result;
}
INIT_DEVICE_EXPORT(swm_sdio_init);
#endif /* BSP_USING_SDIO */
#endif /* RT_USING_SDIO */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#include "board.h"
int swm_sdio_init(void);
#endif /* __DRV_SDIO_H__ */

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_sdram.h"
#ifdef BSP_USING_SDRAM
#define DRV_DEBUG
#define LOG_TAG "drv.sdram"
#include <drv_log.h>
int swm_sdram_init(void)
{
SDRAM_InitStructure SDRAM_InitStruct;
PORT_Init(PORTM, PIN13, PORTM_PIN13_SDR_CLK, 0);
PORT_Init(PORTM, PIN14, PORTM_PIN14_SDR_CKE, 0);
PORT_Init(PORTB, PIN7, PORTB_PIN7_SDR_WE, 0);
PORT_Init(PORTB, PIN8, PORTB_PIN8_SDR_CAS, 0);
PORT_Init(PORTB, PIN9, PORTB_PIN9_SDR_RAS, 0);
PORT_Init(PORTB, PIN10, PORTB_PIN10_SDR_CS, 0);
PORT_Init(PORTE, PIN15, PORTE_PIN15_SDR_BA0, 0);
PORT_Init(PORTE, PIN14, PORTE_PIN14_SDR_BA1, 0);
PORT_Init(PORTN, PIN14, PORTN_PIN14_SDR_A0, 0);
PORT_Init(PORTN, PIN13, PORTN_PIN13_SDR_A1, 0);
PORT_Init(PORTN, PIN12, PORTN_PIN12_SDR_A2, 0);
PORT_Init(PORTN, PIN11, PORTN_PIN11_SDR_A3, 0);
PORT_Init(PORTN, PIN10, PORTN_PIN10_SDR_A4, 0);
PORT_Init(PORTN, PIN9, PORTN_PIN9_SDR_A5, 0);
PORT_Init(PORTN, PIN8, PORTN_PIN8_SDR_A6, 0);
PORT_Init(PORTN, PIN7, PORTN_PIN7_SDR_A7, 0);
PORT_Init(PORTN, PIN6, PORTN_PIN6_SDR_A8, 0);
PORT_Init(PORTN, PIN3, PORTN_PIN3_SDR_A9, 0);
PORT_Init(PORTN, PIN15, PORTN_PIN15_SDR_A10, 0);
PORT_Init(PORTN, PIN2, PORTN_PIN2_SDR_A11, 0);
PORT_Init(PORTM, PIN15, PORTM_PIN15_SDR_A12, 0);
PORT_Init(PORTE, PIN7, PORTE_PIN7_SDR_D0, 1);
PORT_Init(PORTE, PIN6, PORTE_PIN6_SDR_D1, 1);
PORT_Init(PORTE, PIN5, PORTE_PIN5_SDR_D2, 1);
PORT_Init(PORTE, PIN4, PORTE_PIN4_SDR_D3, 1);
PORT_Init(PORTE, PIN3, PORTE_PIN3_SDR_D4, 1);
PORT_Init(PORTE, PIN2, PORTE_PIN2_SDR_D5, 1);
PORT_Init(PORTE, PIN1, PORTE_PIN1_SDR_D6, 1);
PORT_Init(PORTE, PIN0, PORTE_PIN0_SDR_D7, 1);
PORT_Init(PORTE, PIN8, PORTE_PIN8_SDR_D8, 1);
PORT_Init(PORTE, PIN9, PORTE_PIN9_SDR_D9, 1);
PORT_Init(PORTE, PIN10, PORTE_PIN10_SDR_D10, 1);
PORT_Init(PORTE, PIN11, PORTE_PIN11_SDR_D11, 1);
PORT_Init(PORTE, PIN12, PORTE_PIN12_SDR_D12, 1);
PORT_Init(PORTE, PIN13, PORTE_PIN13_SDR_D13, 1);
PORT_Init(PORTC, PIN14, PORTC_PIN14_SDR_D14, 1);
PORT_Init(PORTC, PIN15, PORTC_PIN15_SDR_D15, 1);
PORT_Init(PORTB, PIN6, PORTB_PIN6_SDR_LDQM, 0);
PORT_Init(PORTM, PIN12, PORTM_PIN12_SDR_UDQM, 0);
SDRAM_InitStruct.Size = SDRAM_SIZE_8MB;
SDRAM_InitStruct.ClkDiv = SDRAM_CLKDIV_1;
SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_3;
SDRAM_InitStruct.TimeTRP = SDRAM_TRP_2;
SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_2;
SDRAM_InitStruct.TimeTRFC = SDRAM_TRFC_9;
SDRAM_Init(&SDRAM_InitStruct);
return 0;
}
#endif /* BSP_USING_SDRAM */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SDRAM_H__
#define __DRV_SDRAM_H__
#include "board.h"
int swm_sdram_init(void);
#endif /* __DRV_SDRAM_H__ */

View File

@ -0,0 +1,219 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_soft_i2c.h"
#ifdef RT_USING_I2C
#ifdef BSP_USING_I2C
//#define DRV_DEBUG
#define LOG_TAG "drv.i2c"
#include <drv_log.h>
#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_I2C0
#define I2C0_BUS_CFG \
{ \
.scl = BSP_I2C0_SCL_PIN, \
.sda = BSP_I2C0_SDA_PIN, \
.name = "i2c0", \
}
#endif
#ifdef BSP_USING_I2C1
#define I2C1_BUS_CFG \
{ \
.scl = BSP_I2C1_SCL_PIN, \
.sda = BSP_I2C1_SDA_PIN, \
.name = "i2c1", \
}
#endif
/* swm config class */
struct swm_soft_i2c_cfg
{
rt_uint8_t scl;
rt_uint8_t sda;
const char *name;
};
/* swm i2c dirver class */
struct swm_soft_i2c_device
{
struct rt_i2c_bit_ops ops;
struct rt_i2c_bus_device i2c2_bus;
};
static const struct swm_soft_i2c_cfg swm_soft_i2c_cfg[] =
{
#ifdef BSP_USING_I2C0
I2C0_BUS_CFG,
#endif
#ifdef BSP_USING_I2C1
I2C1_BUS_CFG,
#endif
};
static struct swm_soft_i2c_device i2c_obj[sizeof(swm_soft_i2c_cfg) / sizeof(swm_soft_i2c_cfg[0])];
/**
* This function initializes the i2c pin.
*
* @param swm i2c dirver class.
*/
static void swm_i2c_gpio_init(struct swm_soft_i2c_device *i2c)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)i2c->ops.data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
}
/**
* This function sets the sda pin.
*
* @param swm config class.
* @param The sda pin state.
*/
static void swm_i2_set_sda(void *data, rt_int32_t state)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
if (state)
{
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
}
else
{
rt_pin_write(soft_i2c_cfg->sda, PIN_LOW);
}
}
/**
* This function sets the scl pin.
*
* @param swm config class.
* @param The scl pin state.
*/
static void swm_i2c_set_scl(void *data, rt_int32_t state)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
if (state)
{
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
}
else
{
rt_pin_write(soft_i2c_cfg->scl, PIN_LOW);
}
}
/**
* This function gets the sda pin state.
*
* @param The sda pin state.
*/
static rt_int32_t swm_i2c_get_sda(void *data)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_INPUT_PULLDOWN);
return rt_pin_read(soft_i2c_cfg->sda);
}
/**
* This function gets the scl pin state.
*
* @param The scl pin state.
*/
static rt_int32_t swm_i2c_get_scl(void *data)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_INPUT_PULLDOWN);
return rt_pin_read(soft_i2c_cfg->scl);
}
/**
* The time delay function.
*
* @param microseconds.
*/
static void swm_i2c_udelay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
static const struct rt_i2c_bit_ops swm_i2c_bit_ops =
{
.data = RT_NULL,
.set_sda = swm_i2_set_sda,
.set_scl = swm_i2c_set_scl,
.get_sda = swm_i2c_get_sda,
.get_scl = swm_i2c_get_scl,
.udelay = swm_i2c_udelay,
.delay_us = 1,
.timeout = 100};
/* I2C initialization function */
int swm_i2c_init(void)
{
rt_err_t result;
for (int i = 0; i < sizeof(i2c_obj) / sizeof(struct swm_soft_i2c_device); i++)
{
i2c_obj[i].ops = swm_i2c_bit_ops;
i2c_obj[i].ops.data = (void *)&swm_soft_i2c_cfg[i];
i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
swm_i2c_gpio_init(&i2c_obj[i]);
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, swm_soft_i2c_cfg[i].name);
RT_ASSERT(result == RT_EOK);
LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
swm_soft_i2c_cfg[i].name,
swm_soft_i2c_cfg[i].scl,
swm_soft_i2c_cfg[i].sda);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(swm_i2c_init);
#endif /* BSP_USING_I2C */
#endif /* RT_USING_I2C */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SOFT_I2C_H__
#define __DRV_SOFT_I2C_H__
#include "board.h"
int swm_i2c_init(void);
#endif /* __DRV_SOFT_I2C_H__ */

View File

@ -0,0 +1,375 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_spi.h"
#ifdef RT_USING_SPI
#ifdef BSP_USING_SPI
//#define DRV_DEBUG
#define LOG_TAG "drv.spi"
#include <drv_log.h>
#if !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1)
#error "Please define at least one BSP_USING_SPIx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
struct swm_spi_cs
{
GPIO_TypeDef *GPIOx;
uint32_t gpio_pin;
};
struct swm_spi_cfg
{
const char *name;
SPI_TypeDef *SPIx;
SPI_InitStructure spi_initstruct;
};
/* swm spi dirver class */
struct swm_spi_device
{
struct swm_spi_cfg *spi_cfg;
struct rt_spi_configuration *configure;
struct rt_spi_bus spi_bus;
};
#ifdef BSP_USING_SPI0
#ifndef SPI0_BUS_CONFIG
#define SPI0_BUS_CONFIG \
{ \
.name = "spi0", \
.SPIx = SPI0, \
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
.spi_initstruct.WordSize = 8, \
.spi_initstruct.Master = 1, \
.spi_initstruct.RXThreshold = 0, \
.spi_initstruct.RXThresholdIEn = 0, \
.spi_initstruct.TXThreshold = 0, \
.spi_initstruct.TXThresholdIEn = 0, \
.spi_initstruct.TXCompleteIEn = 0, \
}
#endif /* SPI0_BUS_CONFIG */
#endif /* BSP_USING_SPI0 */
#ifdef BSP_USING_SPI1
#ifndef SPI1_BUS_CONFIG
#define SPI1_BUS_CONFIG \
{ \
.name = "spi1", \
.SPIx = SPI1, \
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
.spi_initstruct.WordSize = 8, \
.spi_initstruct.Master = 1, \
.spi_initstruct.RXThreshold = 0, \
.spi_initstruct.RXThresholdIEn = 0, \
.spi_initstruct.TXThreshold = 0, \
.spi_initstruct.TXThresholdIEn = 0, \
.spi_initstruct.TXCompleteIEn = 0, \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
static struct swm_spi_cfg swm_spi_cfg[] =
{
#ifdef BSP_USING_SPI0
SPI0_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI1
SPI1_BUS_CONFIG,
#endif
};
static struct swm_spi_device spi_bus_obj[sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0])] = {0};
static rt_err_t swm_spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configure)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configure != RT_NULL);
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
spi_drv->configure = configure;
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
if (configure->mode & RT_SPI_SLAVE)
{
spi_cfg->spi_initstruct.Master = 0;
}
else
{
spi_cfg->spi_initstruct.Master = 1;
}
if (configure->mode & RT_SPI_3WIRE)
{
return RT_EINVAL;
}
if (configure->data_width == 8)
{
spi_cfg->spi_initstruct.WordSize = 8;
}
else if (configure->data_width == 16)
{
spi_cfg->spi_initstruct.WordSize = 16;
}
else
{
return RT_EIO;
}
if (configure->mode & RT_SPI_CPHA)
{
spi_cfg->spi_initstruct.SampleEdge = SPI_SECOND_EDGE;
}
else
{
spi_cfg->spi_initstruct.SampleEdge = SPI_FIRST_EDGE;
}
if (configure->mode & RT_SPI_CPOL)
{
spi_cfg->spi_initstruct.IdleLevel = SPI_HIGH_LEVEL;
}
else
{
spi_cfg->spi_initstruct.IdleLevel = SPI_LOW_LEVEL;
}
if (configure->max_hz >= SystemCoreClock / 2)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_4;
}
else if (configure->max_hz >= SystemCoreClock / 4)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_4;
}
else if (configure->max_hz >= SystemCoreClock / 8)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_8;
}
else if (configure->max_hz >= SystemCoreClock / 16)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_16;
}
else if (configure->max_hz >= SystemCoreClock / 32)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_32;
}
else if (configure->max_hz >= SystemCoreClock / 64)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_64;
}
else if (configure->max_hz >= SystemCoreClock / 128)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_128;
}
else if (configure->max_hz >= SystemCoreClock / 256)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_256;
}
else
{
/* min prescaler 512 */
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_512;
}
SPI_Init(spi_cfg->SPIx, &(spi_cfg->spi_initstruct));
SPI_Open(spi_cfg->SPIx);
LOG_D("%s init done", spi_cfg->name);
return RT_EOK;
}
#define SPISTEP(datalen) (((datalen) == 8) ? 1 : 2)
#define SPISEND_1(reg, ptr, datalen) \
do \
{ \
if (datalen == 8) \
{ \
(reg) = *(rt_uint8_t *)(ptr); \
} \
else \
{ \
(reg) = *(rt_uint16_t *)(ptr); \
} \
} while (0)
#define SPIRECV_1(reg, ptr, datalen) \
do \
{ \
if (datalen == 8) \
{ \
*(rt_uint8_t *)(ptr) = (reg); \
} \
else \
{ \
*(rt_uint16_t *)(ptr) = reg; \
} \
} while (0)
static rt_err_t swm_spi_txrx1b(struct swm_spi_device *spi_drv, void *rcvb, const void *sndb)
{
rt_uint32_t padrcv = 0;
rt_uint32_t padsnd = 0xFF;
if (!rcvb && !sndb)
{
return RT_ERROR;
}
if (!rcvb)
{
rcvb = &padrcv;
}
if (!sndb)
{
sndb = &padsnd;
}
while (SPI_IsTXFull(spi_drv->spi_cfg->SPIx))
;
SPISEND_1(spi_drv->spi_cfg->SPIx->DATA, sndb, spi_drv->spi_cfg->spi_initstruct.WordSize);
while (SPI_IsRXEmpty(spi_drv->spi_cfg->SPIx))
;
SPIRECV_1(spi_drv->spi_cfg->SPIx->DATA, rcvb, spi_drv->spi_cfg->spi_initstruct.WordSize);
return RT_EOK;
}
static rt_uint32_t swm_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_err_t res;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
RT_ASSERT(message != RT_NULL);
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
struct swm_spi_cs *cs = device->parent.user_data;
if (message->cs_take)
{
GPIO_ClrBit(cs->GPIOx, cs->gpio_pin);
}
LOG_D("%s transfer prepare and start", spi_cfg->name);
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
spi_cfg->name, (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length);
const rt_uint8_t *sndb = message->send_buf;
rt_uint8_t *rcvb = message->recv_buf;
rt_int32_t length = message->length;
while (length)
{
res = swm_spi_txrx1b(spi_drv, rcvb, sndb);
if (rcvb)
{
rcvb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
}
if (sndb)
{
sndb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
}
if (res != RT_EOK)
{
break;
}
length--;
}
/* Wait until Busy flag is reset before disabling SPI */
while (!SPI_IsTXEmpty(spi_cfg->SPIx) && !SPI_IsRXEmpty(spi_cfg->SPIx))
;
if (message->cs_release)
{
GPIO_SetBit(cs->GPIOx, cs->gpio_pin);
}
return message->length - length;
}
const static struct rt_spi_ops swm_spi_ops =
{
.configure = swm_spi_configure,
.xfer = swm_spi_xfer,
};
//cannot be used before completion init
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *cs_gpiox, uint32_t cs_gpio_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result;
struct rt_spi_device *spi_device;
struct swm_spi_cs *cs_pin;
GPIO_Init(cs_gpiox, cs_gpio_pin, 1, 1, 0, 0);
GPIO_SetBit(cs_gpiox, cs_gpio_pin);
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
cs_pin = (struct swm_spi_cs *)rt_malloc(sizeof(struct swm_spi_cs));
RT_ASSERT(cs_pin != RT_NULL);
cs_pin->GPIOx = cs_gpiox;
cs_pin->gpio_pin = cs_gpio_pin;
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
if (result != RT_EOK)
{
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
RT_ASSERT(result == RT_EOK);
LOG_D("%s attach to %s done", device_name, bus_name);
return result;
}
int swm_spi_init(void)
{
rt_err_t result;
#ifdef BSP_USING_SPI0
PORT_Init(PORTM, PIN2, PORTM_PIN2_SPI0_SCLK, 0);
PORT_Init(PORTM, PIN4, PORTM_PIN4_SPI0_MISO, 1);
PORT_Init(PORTM, PIN5, PORTM_PIN5_SPI0_MOSI, 0);
#endif //BSP_USING_SPI0
#ifdef BSP_USING_SPI1
PORT_Init(PORTB, PIN2, PORTB_PIN2_SPI1_SCLK, 0);
PORT_Init(PORTB, PIN3, PORTB_PIN3_SPI1_MISO, 1);
PORT_Init(PORTB, PIN4, PORTB_PIN4_SPI1_MOSI, 0);
#endif //BSP_USING_SPI1
for (int i = 0; i < sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0]); i++)
{
spi_bus_obj[i].spi_cfg = &swm_spi_cfg[i];
spi_bus_obj[i].spi_bus.parent.user_data = &swm_spi_cfg[i];
result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, swm_spi_cfg[i].name, &swm_spi_ops);
if (result != RT_EOK)
{
LOG_E("%s bus register fail.", swm_spi_cfg[i].name);
}
else
{
LOG_D("%s bus register success.", swm_spi_cfg[i].name);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_spi_init);
#endif /* BSP_USING_SPI */
#endif /* RT_USING_SPI */

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include "board.h"
//cannot be used before completion init
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *GPIOx, uint32_t n);
int swm_spi_init(void);
#endif /* __DRV_SPI_H__ */

View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_uart.h"
#ifdef RT_USING_SERIAL
#ifdef BSP_USING_UART
//#define DRV_DEBUG
#define LOG_TAG "drv.uart"
#include <drv_log.h>
#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
!defined(BSP_USING_UART3)
#error "Please define at least one BSP_USING_UARTx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#endif
#ifdef BSP_USING_UART0
#ifndef UART0_CFG
#define UART0_CFG \
{ \
.name = "uart0", \
.UARTx = UART0, \
.irq = UART0_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART0_CFG */
#endif /* BSP_USING_UART0 */
#ifdef BSP_USING_UART1
#ifndef UART1_CFG
#define UART1_CFG \
{ \
.name = "uart1", \
.UARTx = UART1, \
.irq = UART1_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART1_CFG */
#endif /* BSP_USING_UART1 */
#ifdef BSP_USING_UART2
#ifndef UART2_CFG
#define UART2_CFG \
{ \
.name = "uart2", \
.UARTx = UART2, \
.irq = UART2_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART2_CFG */
#endif /* BSP_USING_UART2 */
#ifdef BSP_USING_UART3
#ifndef UART3_CFG
#define UART3_CFG \
{ \
.name = "uart3", \
.UARTx = UART3, \
.irq = UART3_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART3_CFG */
#endif /* BSP_USING_UART3 */
/* swm config class */
struct swm_uart_cfg
{
const char *name;
UART_TypeDef *UARTx;
IRQn_Type irq;
UART_InitStructure uart_initstruct;
};
/* swm uart dirver class */
struct swm_uart_device
{
struct swm_uart_cfg *uart_cfg;
struct rt_serial_device serial_device;
};
enum
{
#ifdef BSP_USING_UART0
UART0_INDEX,
#endif
#ifdef BSP_USING_UART1
UART1_INDEX,
#endif
#ifdef BSP_USING_UART2
UART2_INDEX,
#endif
#ifdef BSP_USING_UART3
UART3_INDEX,
#endif
};
static struct swm_uart_cfg swm_uart_cfg[] =
{
#ifdef BSP_USING_UART0
UART0_CFG,
#endif
#ifdef BSP_USING_UART1
UART1_CFG,
#endif
#ifdef BSP_USING_UART2
UART2_CFG,
#endif
#ifdef BSP_USING_UART3
UART3_CFG,
#endif
};
static struct swm_uart_device uart_obj[sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0])] = {0};
static rt_err_t swm_uart_configure(struct rt_serial_device *serial_device, struct serial_configure *configure)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
RT_ASSERT(configure != RT_NULL);
uart_cfg = serial_device->parent.user_data;
uart_cfg->uart_initstruct.Baudrate = configure->baud_rate;
switch (configure->data_bits)
{
case DATA_BITS_8:
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
break;
case DATA_BITS_9:
uart_cfg->uart_initstruct.DataBits = UART_DATA_9BIT;
break;
default:
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
break;
}
switch (configure->stop_bits)
{
case STOP_BITS_1:
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
break;
case STOP_BITS_2:
uart_cfg->uart_initstruct.StopBits = UART_STOP_2BIT;
break;
default:
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
break;
}
switch (configure->parity)
{
case PARITY_NONE:
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
break;
case PARITY_ODD:
uart_cfg->uart_initstruct.Parity = UART_PARITY_ODD;
break;
case PARITY_EVEN:
uart_cfg->uart_initstruct.Parity = UART_PARITY_EVEN;
break;
default:
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
break;
}
UART_Init(uart_cfg->UARTx, &(uart_cfg->uart_initstruct));
UART_Open(uart_cfg->UARTx);
return RT_EOK;
}
static rt_err_t swm_uart_control(struct rt_serial_device *serial_device, int cmd, void *arg)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* disable rx irq */
NVIC_DisableIRQ(uart_cfg->irq);
break;
case RT_DEVICE_CTRL_SET_INT:
/* enable rx irq */
NVIC_EnableIRQ(uart_cfg->irq);
break;
}
return RT_EOK;
}
static int swm_uart_putc(struct rt_serial_device *serial_device, char c)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
UART_WriteByte(uart_cfg->UARTx, c);
while (UART_IsTXBusy(uart_cfg->UARTx))
;
return 1;
}
static int swm_uart_getc(struct rt_serial_device *serial_device)
{
int ch;
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
ch = -1;
if (UART_IsRXFIFOEmpty(uart_cfg->UARTx) == 0)
{
UART_ReadByte(uart_cfg->UARTx, (uint32_t *)&ch);
}
return ch;
}
static const struct rt_uart_ops swm_uart_ops =
{
.configure = swm_uart_configure,
.control = swm_uart_control,
.putc = swm_uart_putc,
.getc = swm_uart_getc,
.dma_transmit = RT_NULL};
/**
* Uart common interrupt process. This need add to uart ISR.
*
* @param serial serial device
*/
static void swm_uart_isr(struct rt_serial_device *serial_device)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
/* UART in mode Receiver -------------------------------------------------*/
if (UART_INTRXThresholdStat(uart_cfg->UARTx) || UART_INTTimeoutStat(uart_cfg->UARTx))
{
rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
}
}
#if defined(BSP_USING_UART0)
void UART0_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART0_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART0 */
#if defined(BSP_USING_UART1)
void UART1_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART1_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART1 */
#if defined(BSP_USING_UART2)
void UART2_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART2_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART2 */
#if defined(BSP_USING_UART3)
void UART3_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART3_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART3 */
int swm_uart_init(void)
{
struct serial_configure serial_cfg = RT_SERIAL_CONFIG_DEFAULT;
int i = 0;
rt_err_t result = RT_EOK;
#ifdef BSP_USING_UART0
PORT_Init(PORTM, PIN0, PORTM_PIN0_UART0_RX, 1);
PORT_Init(PORTM, PIN1, PORTM_PIN1_UART0_TX, 0);
#endif
#ifdef BSP_USING_UART1
PORT_Init(PORTD, PIN4, PORTD_PIN4_UART1_RX, 1);
PORT_Init(PORTD, PIN3, PORTD_PIN3_UART1_TX, 0);
#endif
#ifdef BSP_USING_UART2
PORT_Init(PORTC, PIN1, PORTC_PIN1_UART2_RX, 1);
PORT_Init(PORTC, PIN0, PORTC_PIN0_UART2_TX, 0);
#endif
#ifdef BSP_USING_UART3
PORT_Init(PORTC, PIN2, PORTC_PIN2_UART3_RX, 1);
PORT_Init(PORTC, PIN3, PORTC_PIN3_UART3_TX, 0);
#endif
for (i = 0; i < sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0]); i++)
{
uart_obj[i].uart_cfg = &swm_uart_cfg[i];
uart_obj[i].serial_device.ops = &swm_uart_ops;
uart_obj[i].serial_device.config = serial_cfg;
result = rt_hw_serial_register(&uart_obj[i].serial_device, uart_obj[i].uart_cfg->name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart_obj[i].uart_cfg);
RT_ASSERT(result == RT_EOK);
}
return result;
}
#endif /* BSP_USING_UART */
#endif /* RT_USING_SERIAL */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "board.h"
int swm_uart_init(void);
#endif /* __DRV_UART_H__ */

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_wdt.h"
#ifdef RT_USING_WDT
#ifdef BSP_USING_WDT
//#define DRV_DEBUG
#define LOG_TAG "drv.wdt"
#include <drv_log.h>
struct swm_wdt_cfg
{
const char *name;
WDT_TypeDef *WDTx;
};
struct swm_wdt_device
{
struct swm_wdt_cfg *wdt_cfg;
struct rt_watchdog_device wdt_device;
};
static struct swm_wdt_cfg swm_wdt_cfg =
{
.name = "wdt",
.WDTx = WDT,
};
static struct swm_wdt_device wdt_obj;
static rt_err_t swm_wdt_config(rt_watchdog_t *wdt_device)
{
return RT_EOK;
}
static rt_err_t swm_wdt_control(rt_watchdog_t *wdt_device, int cmd, void *arg)
{
struct swm_wdt_cfg *wdt_cfg;
RT_ASSERT(wdt_device != RT_NULL);
wdt_cfg = wdt_device->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
WDT_Feed(wdt_cfg->WDTx);
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
WDT_Init(wdt_cfg->WDTx, 0, (1024 * (*(rt_uint32_t *)arg)));
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
*(rt_uint32_t *)arg = (wdt_cfg->WDTx->RSTVAL) / 1024;
break;
case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
// not support
break;
case RT_DEVICE_CTRL_WDT_START:
WDT_Start(wdt_cfg->WDTx);
break;
case RT_DEVICE_CTRL_WDT_STOP:
WDT_Stop(wdt_cfg->WDTx);
break;
default:
LOG_W("This command is not supported.");
return -RT_ERROR;
}
return RT_EOK;
}
const static struct rt_watchdog_ops swm_wdt_ops =
{
.init = swm_wdt_config,
.control = swm_wdt_control};
int swm_wdt_init(void)
{
int result = RT_EOK;
wdt_obj.wdt_cfg = &swm_wdt_cfg;
wdt_obj.wdt_device.ops = &swm_wdt_ops;
result = rt_hw_watchdog_register(&wdt_obj.wdt_device, wdt_obj.wdt_cfg->name, RT_DEVICE_FLAG_RDWR, wdt_obj.wdt_cfg);
if(result != RT_EOK)
{
LOG_E("wdt device register fail.");
}
else
{
LOG_D("wdt device register success.");
}
return result;
}
INIT_BOARD_EXPORT(swm_wdt_init);
#endif /* BSP_USING_WDT */
#endif /* RT_USING_WDT */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_WDT_H__
#define __DRV_WDT_H__
#include "board.h"
int swm_wdt_init(void);
#endif /* __DRV_WDT_H__ */

View File

@ -0,0 +1,62 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x00000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x0007FFFF;
define symbol __ICFEDIT_region_IROM2_start__ = 0x0;
define symbol __ICFEDIT_region_IROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM1_start__ = 0x0;
define symbol __ICFEDIT_region_EROM1_end__ = 0x0;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x2000FFFF;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0x400;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region IROM_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]
| mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
define region EROM_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]
| mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]
| mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__];
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]
| mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__];
define region ERAM_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]
| mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]
| mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
do not initialize { section .noinit };
initialize by copy { readwrite };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
// Required in a multi-threaded application
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in IROM_region { readonly };
place in EROM_region { readonly section application_specific_ro };
place in IRAM_region { readwrite, block CSTACK, block PROC_STACK, block HEAP };
place in ERAM_region { readwrite section application_specific_rw };

View File

@ -0,0 +1,156 @@
/*
* linker script for SWM341 with GNU ld
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 512k /* 512KB flash */
RAM (rw) : ORIGIN = 0x20000000, LENGTH = 64k /* 64KB sram */
}
ENTRY(Reset_Handler)
_system_stack_size = 0x400;
SECTIONS
{
.text :
{
. = ALIGN(4);
_stext = .;
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);
_etext = .;
} > ROM = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > ROM
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} > RAM
.stack :
{
. = ALIGN(4);
_sstack = .;
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} > RAM
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > RAM
__bss_end = .;
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1,16 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-26 lik first version
*/
#ifndef __LCD_PORT_H__
#define __LCD_PORT_H__
#include "board.h"
/* atk 4.3 inch screen, 480 * 272 */
#define LCD_WIDTH 480
#define LCD_HEIGHT 272
#define LCD_BITS_PER_PIXEL 16
#define LCD_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_BITS_PER_PIXEL / 8)
#define LCD_PIXEL_FORMAT RTGRAPHIC_PIXEL_FORMAT_RGB565
#define LCD_CLK_DIV 15
#define LCD_HSYNC_WIDTH 5
#define LCD_VSYNC_WIDTH 5
#define LCD_HBP 40
#define LCD_VBP 8
#define LCD_HFP 5
#define LCD_VFP 8
#define LCD_BACKLIGHT_USING_GPIO
#define LCD_BL_GPIO GET_PIN(D, 9)
#define LCD_DISP_GPIO GET_PIN(D, 1)
#endif /* __LCD_PORT_H__ */

37
bsp/swm341/keilkill.bat Normal file
View File

@ -0,0 +1,37 @@
del *.bak /s
del *.ddk /s
del *.edk /s
del *.lst /s
::del *.lnp /s
del *.mpf /s
del *.mpj /s
del *.obj /s
del *.omf /s
::del *.opt /s ::不允许删除JLINK的设置
del *.plg /s
del *.rpt /s
del *.tmp /s
::del *.__i /s
::del *._ia /s
del *.crf /s
del *.o /s
del *.d /s
del *.axf /s
del *.tra /s
del *.dep /s
::del JLinkLog.txt /s
del *.iex /s
del *.htm /s
::del *.sct /s
del *.map /s
del *.whsj2 /s
del *.SYNWIT_Lik /s
del *.whsj2 /s
del *.scvd /s
rmdir /s/q .git
rmdir /s/q .vscode
exit

View File

@ -0,0 +1,411 @@
/******************************************************************************
* @file cachel1_armv7.h
* @brief CMSIS Level 1 Cache API for Armv7-M and later
* @version V1.0.0
* @date 03. March 2020
******************************************************************************/
/*
* Copyright (c) 2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_CACHEL1_ARMV7_H
#define ARM_CACHEL1_ARMV7_H
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_CacheFunctions Cache Functions
\brief Functions that configure Instruction and Data cache.
@{
*/
/* Cache Size ID Register Macros */
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
#ifndef __SCB_DCACHE_LINE_SIZE
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
#ifndef __SCB_ICACHE_LINE_SIZE
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
/**
\brief Enable I-Cache
\details Turns on I-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */
__DSB();
__ISB();
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable I-Cache
\details Turns off I-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate I-Cache
\details Invalidates I-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->ICIALLU = 0UL;
__DSB();
__ISB();
#endif
}
/**
\brief I-Cache Invalidate by address
\details Invalidates I-Cache for the given address.
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
I-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] isize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (void *addr, int32_t isize)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if ( isize > 0 ) {
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_ICACHE_LINE_SIZE;
op_size -= __SCB_ICACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief Enable D-Cache
\details Turns on D-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable D-Cache
\details Turns off D-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate D-Cache
\details Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean D-Cache
\details Cleans D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean & Invalidate D-Cache
\details Cleans and Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief D-Cache Invalidate by address
\details Invalidates D-Cache for the given address.
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean by address
\details Cleans D-Cache for the given address
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean and Invalidate by address
\details Cleans and invalidates D_Cache for the given address
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated.
\param[in] addr address (aligned to 32-byte boundary)
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/*@} end of CMSIS_Core_CacheFunctions */
#endif /* ARM_CACHEL1_ARMV7_H */

View File

@ -0,0 +1,885 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
* @version V5.2.1
* @date 26. March 2020
******************************************************************************/
/*
* Copyright (c) 2009-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* __ARM_ARCH_8_1M_MAIN__ not applicable */
/* CMSIS compiler control DSP macros */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __ARM_FEATURE_DSP 1
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static __forceinline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __memory_changed()
#endif
/* ######################### Startup and Lowlevel Init ######################## */
#ifndef __PROGRAM_START
#define __PROGRAM_START __main
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __Vectors
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET")))
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value != 0U; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return result;
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.1.0
* @date 09. October 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,968 @@
/**************************************************************************//**
* @file cmsis_iccarm.h
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
* @version V5.2.0
* @date 28. January 2020
******************************************************************************/
//------------------------------------------------------------------------------
//
// Copyright (c) 2017-2019 IAR Systems
// Copyright (c) 2017-2019 Arm Limited. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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.
//
//------------------------------------------------------------------------------
#ifndef __CMSIS_ICCARM_H__
#define __CMSIS_ICCARM_H__
#ifndef __ICCARM__
#error This file should only be compiled by ICCARM
#endif
#pragma system_include
#define __IAR_FT _Pragma("inline=forced") __intrinsic
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif
#ifndef __ALIGNED
#if __ICCARM_V8
#define __ALIGNED(x) __attribute__((aligned(x)))
#elif (__VER__ >= 7080000)
/* Needs IAR language extensions */
#define __ALIGNED(x) __attribute__((aligned(x)))
#else
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#endif
/* Define compiler macros for CPU architecture, used in CMSIS 5.
*/
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
/* Macros already defined */
#else
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
#if __ARM_ARCH == 6
#define __ARM_ARCH_6M__ 1
#elif __ARM_ARCH == 7
#if __ARM_FEATURE_DSP
#define __ARM_ARCH_7EM__ 1
#else
#define __ARM_ARCH_7M__ 1
#endif
#endif /* __ARM_ARCH */
#endif /* __ARM_ARCH_PROFILE == 'M' */
#endif
/* Alternativ core deduction for older ICCARM's */
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
#define __ARM_ARCH_6M__ 1
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
#define __ARM_ARCH_7M__ 1
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
#define __ARM_ARCH_7EM__ 1
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#else
#error "Unknown target."
#endif
#endif
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
#define __IAR_M0_FAMILY 1
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
#define __IAR_M0_FAMILY 1
#else
#define __IAR_M0_FAMILY 0
#endif
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __NO_RETURN
#if __ICCARM_V8
#define __NO_RETURN __attribute__((__noreturn__))
#else
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
#endif
#endif
#ifndef __PACKED
#if __ICCARM_V8
#define __PACKED __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED __packed
#endif
#endif
#ifndef __PACKED_STRUCT
#if __ICCARM_V8
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_STRUCT __packed struct
#endif
#endif
#ifndef __PACKED_UNION
#if __ICCARM_V8
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_UNION __packed union
#endif
#endif
#ifndef __RESTRICT
#if __ICCARM_V8
#define __RESTRICT __restrict
#else
/* Needs IAR language extensions */
#define __RESTRICT restrict
#endif
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE _Pragma("inline=forced")
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
{
return *(__packed uint16_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
{
*(__packed uint16_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
{
return *(__packed uint32_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
{
*(__packed uint32_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#pragma language=save
#pragma language=extended
__packed struct __iar_u32 { uint32_t v; };
#pragma language=restore
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
#endif
#ifndef __USED
#if __ICCARM_V8
#define __USED __attribute__((used))
#else
#define __USED _Pragma("__root")
#endif
#endif
#ifndef __WEAK
#if __ICCARM_V8
#define __WEAK __attribute__((weak))
#else
#define __WEAK _Pragma("__weak")
#endif
#endif
#ifndef __PROGRAM_START
#define __PROGRAM_START __iar_program_start
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP CSTACK$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT CSTACK$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __vector_table
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE @".intvec"
#endif
#ifndef __ICCARM_INTRINSICS_VERSION__
#define __ICCARM_INTRINSICS_VERSION__ 0
#endif
#if __ICCARM_INTRINSICS_VERSION__ == 2
#if defined(__CLZ)
#undef __CLZ
#endif
#if defined(__REVSH)
#undef __REVSH
#endif
#if defined(__RBIT)
#undef __RBIT
#endif
#if defined(__SSAT)
#undef __SSAT
#endif
#if defined(__USAT)
#undef __USAT
#endif
#include "iccarm_builtin.h"
#define __disable_fault_irq __iar_builtin_disable_fiq
#define __disable_irq __iar_builtin_disable_interrupt
#define __enable_fault_irq __iar_builtin_enable_fiq
#define __enable_irq __iar_builtin_enable_interrupt
#define __arm_rsr __iar_builtin_rsr
#define __arm_wsr __iar_builtin_wsr
#define __get_APSR() (__arm_rsr("APSR"))
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
#define __get_CONTROL() (__arm_rsr("CONTROL"))
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
#define __get_FPSCR() (__arm_rsr("FPSCR"))
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
#else
#define __get_FPSCR() ( 0 )
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#define __get_IPSR() (__arm_rsr("IPSR"))
#define __get_MSP() (__arm_rsr("MSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __get_MSPLIM() (0U)
#else
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
#endif
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
#define __get_PSP() (__arm_rsr("PSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __get_PSPLIM() (0U)
#else
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
#endif
#define __get_xPSR() (__arm_rsr("xPSR"))
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __set_MSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
#endif
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __set_PSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
#endif
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __TZ_get_PSPLIM_NS() (0U)
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
#else
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
#endif
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
#define __NOP __iar_builtin_no_operation
#define __CLZ __iar_builtin_CLZ
#define __CLREX __iar_builtin_CLREX
#define __DMB __iar_builtin_DMB
#define __DSB __iar_builtin_DSB
#define __ISB __iar_builtin_ISB
#define __LDREXB __iar_builtin_LDREXB
#define __LDREXH __iar_builtin_LDREXH
#define __LDREXW __iar_builtin_LDREX
#define __RBIT __iar_builtin_RBIT
#define __REV __iar_builtin_REV
#define __REV16 __iar_builtin_REV16
__IAR_FT int16_t __REVSH(int16_t val)
{
return (int16_t) __iar_builtin_REVSH(val);
}
#define __ROR __iar_builtin_ROR
#define __RRX __iar_builtin_RRX
#define __SEV __iar_builtin_SEV
#if !__IAR_M0_FAMILY
#define __SSAT __iar_builtin_SSAT
#endif
#define __STREXB __iar_builtin_STREXB
#define __STREXH __iar_builtin_STREXH
#define __STREXW __iar_builtin_STREX
#if !__IAR_M0_FAMILY
#define __USAT __iar_builtin_USAT
#endif
#define __WFE __iar_builtin_WFE
#define __WFI __iar_builtin_WFI
#if __ARM_MEDIA__
#define __SADD8 __iar_builtin_SADD8
#define __QADD8 __iar_builtin_QADD8
#define __SHADD8 __iar_builtin_SHADD8
#define __UADD8 __iar_builtin_UADD8
#define __UQADD8 __iar_builtin_UQADD8
#define __UHADD8 __iar_builtin_UHADD8
#define __SSUB8 __iar_builtin_SSUB8
#define __QSUB8 __iar_builtin_QSUB8
#define __SHSUB8 __iar_builtin_SHSUB8
#define __USUB8 __iar_builtin_USUB8
#define __UQSUB8 __iar_builtin_UQSUB8
#define __UHSUB8 __iar_builtin_UHSUB8
#define __SADD16 __iar_builtin_SADD16
#define __QADD16 __iar_builtin_QADD16
#define __SHADD16 __iar_builtin_SHADD16
#define __UADD16 __iar_builtin_UADD16
#define __UQADD16 __iar_builtin_UQADD16
#define __UHADD16 __iar_builtin_UHADD16
#define __SSUB16 __iar_builtin_SSUB16
#define __QSUB16 __iar_builtin_QSUB16
#define __SHSUB16 __iar_builtin_SHSUB16
#define __USUB16 __iar_builtin_USUB16
#define __UQSUB16 __iar_builtin_UQSUB16
#define __UHSUB16 __iar_builtin_UHSUB16
#define __SASX __iar_builtin_SASX
#define __QASX __iar_builtin_QASX
#define __SHASX __iar_builtin_SHASX
#define __UASX __iar_builtin_UASX
#define __UQASX __iar_builtin_UQASX
#define __UHASX __iar_builtin_UHASX
#define __SSAX __iar_builtin_SSAX
#define __QSAX __iar_builtin_QSAX
#define __SHSAX __iar_builtin_SHSAX
#define __USAX __iar_builtin_USAX
#define __UQSAX __iar_builtin_UQSAX
#define __UHSAX __iar_builtin_UHSAX
#define __USAD8 __iar_builtin_USAD8
#define __USADA8 __iar_builtin_USADA8
#define __SSAT16 __iar_builtin_SSAT16
#define __USAT16 __iar_builtin_USAT16
#define __UXTB16 __iar_builtin_UXTB16
#define __UXTAB16 __iar_builtin_UXTAB16
#define __SXTB16 __iar_builtin_SXTB16
#define __SXTAB16 __iar_builtin_SXTAB16
#define __SMUAD __iar_builtin_SMUAD
#define __SMUADX __iar_builtin_SMUADX
#define __SMMLA __iar_builtin_SMMLA
#define __SMLAD __iar_builtin_SMLAD
#define __SMLADX __iar_builtin_SMLADX
#define __SMLALD __iar_builtin_SMLALD
#define __SMLALDX __iar_builtin_SMLALDX
#define __SMUSD __iar_builtin_SMUSD
#define __SMUSDX __iar_builtin_SMUSDX
#define __SMLSD __iar_builtin_SMLSD
#define __SMLSDX __iar_builtin_SMLSDX
#define __SMLSLD __iar_builtin_SMLSLD
#define __SMLSLDX __iar_builtin_SMLSLDX
#define __SEL __iar_builtin_SEL
#define __QADD __iar_builtin_QADD
#define __QSUB __iar_builtin_QSUB
#define __PKHBT __iar_builtin_PKHBT
#define __PKHTB __iar_builtin_PKHTB
#endif
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#define __CLZ __cmsis_iar_clz_not_active
#define __SSAT __cmsis_iar_ssat_not_active
#define __USAT __cmsis_iar_usat_not_active
#define __RBIT __cmsis_iar_rbit_not_active
#define __get_APSR __cmsis_iar_get_APSR_not_active
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
#endif
#ifdef __INTRINSICS_INCLUDED
#error intrinsics.h is already included previously!
#endif
#include <intrinsics.h>
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#undef __CLZ
#undef __SSAT
#undef __USAT
#undef __RBIT
#undef __get_APSR
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
{
if (data == 0U) { return 32U; }
uint32_t count = 0U;
uint32_t mask = 0x80000000U;
while ((data & mask) == 0U)
{
count += 1U;
mask = mask >> 1U;
}
return count;
}
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
{
uint8_t sc = 31U;
uint32_t r = v;
for (v >>= 1U; v; v >>= 1U)
{
r <<= 1U;
r |= v & 1U;
sc--;
}
return (r << sc);
}
__STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t res;
__asm("MRS %0,APSR" : "=r" (res));
return res;
}
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#undef __get_FPSCR
#undef __set_FPSCR
#define __get_FPSCR() (0)
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#pragma diag_suppress=Pe940
#pragma diag_suppress=Pe177
#define __enable_irq __enable_interrupt
#define __disable_irq __disable_interrupt
#define __NOP __no_operation
#define __get_xPSR __get_PSR
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
{
return __LDREX((unsigned long *)ptr);
}
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
{
return __STREX(value, (unsigned long *)ptr);
}
#endif
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
#if (__CORTEX_M >= 0x03)
__IAR_FT uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM volatile("RRX %0, %1" : "=r"(result) : "r" (value));
return(result);
}
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
{
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
}
#define __enable_fault_irq __enable_fiq
#define __disable_fault_irq __disable_fiq
#endif /* (__CORTEX_M >= 0x03) */
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
}
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint32_t __get_MSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_MSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __get_PSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_PSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
{
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
{
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
{
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_SP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,SP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
{
__asm volatile("MSR SP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
{
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
{
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
{
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
#endif
return res;
}
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
{
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
#if __IAR_M0_FAMILY
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t res;
__ASM volatile ("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t res;
__ASM volatile ("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t res;
__ASM volatile ("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return res;
}
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM volatile ("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM volatile ("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM volatile ("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
{
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
{
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
{
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#undef __IAR_FT
#undef __IAR_M0_FAMILY
#undef __ICCARM_V8
#pragma diag_default=Pe940
#pragma diag_default=Pe177
#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2))
#endif /* __CMSIS_ICCARM_H__ */

View File

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.4
* @date 23. July 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,952 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V5.0.8
* @date 21. August 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M0
@{
*/
#include "cmsis_version.h"
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
#define __CORTEX_M (0U) /*!< Cortex-M Core */
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_FP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TI_ARM__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000U
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RESERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Core Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
#ifdef CMSIS_NVIC_VIRTUAL
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
#endif
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
#else
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
#define NVIC_SystemReset __NVIC_SystemReset
#endif /* CMSIS_NVIC_VIRTUAL */
#ifdef CMSIS_VECTAB_VIRTUAL
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
#endif
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#else
#define NVIC_SetVector __NVIC_SetVector
#define NVIC_GetVector __NVIC_GetVector
#endif /* (CMSIS_VECTAB_VIRTUAL) */
#define NVIC_USER_IRQ_OFFSET 16
/* The following EXC_RETURN values are saved the LR on exception entry */
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
/* Interrupt Priorities are WORD accessible only under Armv6-M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
#define __NVIC_SetPriorityGrouping(X) (void)(X)
#define __NVIC_GetPriorityGrouping() (0U)
/**
\brief Enable Interrupt
\details Enables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
__COMPILER_BARRIER();
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
__COMPILER_BARRIER();
}
}
/**
\brief Get Interrupt Enable status
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt is not enabled.
\return 1 Interrupt is enabled.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Disable Interrupt
\details Disables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
__DSB();
__ISB();
}
}
/**
\brief Get Pending Interrupt
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Set Interrupt Priority
\details Sets the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
\note The priority cannot be set for every processor exception.
*/
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief Encode Priority
\details Encodes the priority for an interrupt with the given priority group,
preemptive priority value, and subpriority value.
In case of a conflict between priority grouping and available
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
\param [in] PriorityGroup Used priority group.
\param [in] PreemptPriority Preemptive priority value (starting from 0).
\param [in] SubPriority Subpriority value (starting from 0).
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
*/
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
uint32_t PreemptPriorityBits;
uint32_t SubPriorityBits;
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
return (
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
);
}
/**
\brief Decode Priority
\details Decodes an interrupt priority value with a given priority group to
preemptive priority value and subpriority value.
In case of a conflict between priority grouping and available
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
\param [in] PriorityGroup Used priority group.
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
\param [out] pSubPriority Subpriority value (starting from 0).
*/
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
{
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
uint32_t PreemptPriorityBits;
uint32_t SubPriorityBits;
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
}
/**
\brief Set Interrupt Vector
\details Sets an interrupt vector in SRAM based interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
Address 0 must be mapped to SRAM.
\param [in] IRQn Interrupt number
\param [in] vector Address of interrupt handler function
*/
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */
*(vectors + (int32_t)IRQn) = vector; /* use pointer arithmetic to access vector */
/* ARM Application Note 321 states that the M0 does not require the architectural barrier */
}
/**
\brief Get Interrupt Vector
\details Reads an interrupt vector from interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Address of interrupt handler function
*/
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
{
uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */
return *(vectors + (int32_t)IRQn); /* use pointer arithmetic to access vector */
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ########################## FPU functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_FpuFunctions FPU Functions
\brief Function that provides FPU type.
@{
*/
/**
\brief get FPU type
\details returns the FPU type
\returns
- \b 0: No FPU
- \b 1: Single precision FPU
- \b 2: Double + Single precision FPU
*/
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
{
return 0U; /* No FPU */
}
/*@} end of CMSIS_Core_FpuFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,979 @@
/**************************************************************************//**
* @file core_cm1.h
* @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File
* @version V1.0.1
* @date 12. November 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM1_H_GENERIC
#define __CORE_CM1_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M1
@{
*/
#include "cmsis_version.h"
/* CMSIS CM1 definitions */
#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \
__CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
#define __CORTEX_M (1U) /*!< Cortex-M Core */
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_FP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TI_ARM__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM1_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM1_H_DEPENDANT
#define __CORE_CM1_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM1_REV
#define __CM1_REV 0x0100U
#warning "__CM1_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M1 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
\brief Type definitions for the System Control and ID Register not in the SCB
@{
*/
/**
\brief Structure type to access the System Control and ID Register not in the SCB.
*/
typedef struct
{
uint32_t RESERVED0[2U];
__IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
} SCnSCB_Type;
/* Auxiliary Control Register Definitions */
#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */
#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */
#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */
#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */
/*@} end of group CMSIS_SCnotSCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M1 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Core Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
#ifdef CMSIS_NVIC_VIRTUAL
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
#endif
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
#else
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
#define NVIC_SystemReset __NVIC_SystemReset
#endif /* CMSIS_NVIC_VIRTUAL */
#ifdef CMSIS_VECTAB_VIRTUAL
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
#endif
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#else
#define NVIC_SetVector __NVIC_SetVector
#define NVIC_GetVector __NVIC_GetVector
#endif /* (CMSIS_VECTAB_VIRTUAL) */
#define NVIC_USER_IRQ_OFFSET 16
/* The following EXC_RETURN values are saved the LR on exception entry */
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
/* Interrupt Priorities are WORD accessible only under Armv6-M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
#define __NVIC_SetPriorityGrouping(X) (void)(X)
#define __NVIC_GetPriorityGrouping() (0U)
/**
\brief Enable Interrupt
\details Enables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
__COMPILER_BARRIER();
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
__COMPILER_BARRIER();
}
}
/**
\brief Get Interrupt Enable status
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt is not enabled.
\return 1 Interrupt is enabled.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Disable Interrupt
\details Disables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
__DSB();
__ISB();
}
}
/**
\brief Get Pending Interrupt
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Set Interrupt Priority
\details Sets the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
\note The priority cannot be set for every processor exception.
*/
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief Encode Priority
\details Encodes the priority for an interrupt with the given priority group,
preemptive priority value, and subpriority value.
In case of a conflict between priority grouping and available
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
\param [in] PriorityGroup Used priority group.
\param [in] PreemptPriority Preemptive priority value (starting from 0).
\param [in] SubPriority Subpriority value (starting from 0).
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
*/
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
uint32_t PreemptPriorityBits;
uint32_t SubPriorityBits;
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
return (
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
);
}
/**
\brief Decode Priority
\details Decodes an interrupt priority value with a given priority group to
preemptive priority value and subpriority value.
In case of a conflict between priority grouping and available
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
\param [in] PriorityGroup Used priority group.
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
\param [out] pSubPriority Subpriority value (starting from 0).
*/
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
{
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
uint32_t PreemptPriorityBits;
uint32_t SubPriorityBits;
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
}
/**
\brief Set Interrupt Vector
\details Sets an interrupt vector in SRAM based interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
Address 0 must be mapped to SRAM.
\param [in] IRQn Interrupt number
\param [in] vector Address of interrupt handler function
*/
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
uint32_t *vectors = (uint32_t *)0x0U;
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
/* ARM Application Note 321 states that the M1 does not require the architectural barrier */
}
/**
\brief Get Interrupt Vector
\details Reads an interrupt vector from interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Address of interrupt handler function
*/
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
{
uint32_t *vectors = (uint32_t *)0x0U;
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ########################## FPU functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_FpuFunctions FPU Functions
\brief Function that provides FPU type.
@{
*/
/**
\brief get FPU type
\details returns the FPU type
\returns
- \b 0: No FPU
- \b 1: Single precision FPU
- \b 2: Double + Single precision FPU
*/
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
{
return 0U; /* No FPU */
}
/*@} end of CMSIS_Core_FpuFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM1_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,275 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for Armv7-M MPU
* @version V5.1.1
* @date 10. February 2020
******************************************************************************/
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) \
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
((Region) & MPU_RBAR_REGION_Msk) | \
(MPU_RBAR_VALID_Msk))
/**
* MPU Memory Access Attributes
*
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
*/
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
(((MPU_RASR_ENABLE_Msk))))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
/**
* MPU Memory Access Attribute for strongly ordered memory.
* - TEX: 000b
* - Shareable
* - Non-cacheable
* - Non-bufferable
*/
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
/**
* MPU Memory Access Attribute for device memory.
* - TEX: 000b (if shareable) or 010b (if non-shareable)
* - Shareable or non-shareable
* - Non-cacheable
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
*
* \param IsShareable Configures the device memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
/**
* MPU Memory Access Attribute for normal memory.
* - TEX: 1BBb (reflecting outer cacheability rules)
* - Shareable or non-shareable
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
*
* \param OuterCp Configures the outer cache policy.
* \param InnerCp Configures the inner cache policy.
* \param IsShareable Configures the memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U))
/**
* MPU Memory Access Attribute non-cacheable policy.
*/
#define ARM_MPU_CACHEP_NOCACHE 0U
/**
* MPU Memory Access Attribute write-back, write and read allocate policy.
*/
#define ARM_MPU_CACHEP_WB_WRA 1U
/**
* MPU Memory Access Attribute write-through, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WT_NWA 2U
/**
* MPU Memory Access Attribute write-back, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WB_NWA 3U
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; //!< The region base address register value (RBAR)
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0U;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
while (cnt > MPU_TYPE_RALIASES) {
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
table += MPU_TYPE_RALIASES;
cnt -= MPU_TYPE_RALIASES;
}
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
}
#endif

View File

@ -0,0 +1,352 @@
/******************************************************************************
* @file mpu_armv8.h
* @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU
* @version V5.1.2
* @date 10. February 2020
******************************************************************************/
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV8_H
#define ARM_MPU_ARMV8_H
/** \brief Attribute for device memory (outer only) */
#define ARM_MPU_ATTR_DEVICE ( 0U )
/** \brief Attribute for non-cacheable, normal memory */
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
/** \brief Attribute for normal memory (outer and inner)
* \param NT Non-Transient: Set to 1 for non-transient data.
* \param WB Write-Back: Set to 1 to use write-back update policy.
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
*/
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U))
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
/** \brief Memory Attribute
* \param O Outer memory attributes
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
*/
#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U)))
/** \brief Normal memory non-shareable */
#define ARM_MPU_SH_NON (0U)
/** \brief Normal memory outer shareable */
#define ARM_MPU_SH_OUTER (2U)
/** \brief Normal memory inner shareable */
#define ARM_MPU_SH_INNER (3U)
/** \brief Memory access permissions
* \param RO Read-Only: Set to 1 for read-only memory.
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
*/
#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U))
/** \brief Region Base Address Register value
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
* \param SH Defines the Shareability domain for this memory region.
* \param RO Read-Only: Set to 1 for a read-only memory region.
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
*/
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
(((BASE) & MPU_RBAR_BASE_Msk) | \
(((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
(((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
/** \brief Region Limit Address Register value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR(LIMIT, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#if defined(MPU_RLAR_PXN_Pos)
/** \brief Region Limit Address Register with PXN value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#endif
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; /*!< Region Base Address Register value */
uint32_t RLAR; /*!< Region Limit Address Register value */
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#ifdef MPU_NS
/** Enable the Non-secure MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
{
__DMB();
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the Non-secure MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#endif
/** Set the memory attribute encoding to the given MPU.
* \param mpu Pointer to the MPU to be configured.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
{
const uint8_t reg = idx / 4U;
const uint32_t pos = ((idx % 4U) * 8U);
const uint32_t mask = 0xFFU << pos;
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
return; // invalid index
}
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
}
/** Set the memory attribute encoding.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
}
#ifdef MPU_NS
/** Set the memory attribute encoding to the Non-secure MPU.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
}
#endif
/** Clear and disable the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
{
mpu->RNR = rnr;
mpu->RLAR = 0U;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU, rnr);
}
#ifdef MPU_NS
/** Clear and disable the given Non-secure MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
}
#endif
/** Configure the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
mpu->RNR = rnr;
mpu->RBAR = rbar;
mpu->RLAR = rlar;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
}
#ifdef MPU_NS
/** Configure the given Non-secure MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
}
#endif
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table to the given MPU.
* \param mpu Pointer to the MPU registers to be used.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
if (cnt == 1U) {
mpu->RNR = rnr;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
} else {
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
table += c;
cnt -= c;
rnrOffset = 0U;
rnrBase += MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
}
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
}
}
/** Load the given number of MPU regions from a table.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
}
#ifdef MPU_NS
/** Load the given number of MPU regions from a table to the Non-secure MPU.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
}
#endif
#endif

View File

@ -0,0 +1,337 @@
/******************************************************************************
* @file pmu_armv8.h
* @brief CMSIS PMU API for Armv8.1-M PMU
* @version V1.0.0
* @date 24. March 2020
******************************************************************************/
/*
* Copyright (c) 2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_PMU_ARMV8_H
#define ARM_PMU_ARMV8_H
/**
* \brief PMU Events
* \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events.
* */
#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */
#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */
#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */
#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */
#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */
#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */
#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */
#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */
#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */
#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */
#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */
#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */
#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */
#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */
#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */
#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */
#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */
#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */
#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */
#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */
#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */
#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */
#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */
#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */
#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */
#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */
#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */
#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */
#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */
#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */
#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */
#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */
#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */
#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */
#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */
#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */
#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */
#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */
#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */
#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */
#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */
#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */
#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */
#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */
#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */
#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */
#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */
#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */
#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */
#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */
#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */
#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */
#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */
#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */
#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */
#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */
#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */
#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */
#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */
#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */
#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */
#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */
#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */
#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */
#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */
#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */
#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */
#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */
#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */
#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */
#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */
#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */
#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */
#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */
#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */
#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */
#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */
#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */
#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */
#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */
#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */
#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */
#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */
#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */
#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */
#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */
#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */
#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */
#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */
#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */
#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */
#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */
#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */
#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */
#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */
#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */
/** \brief PMU Functions */
__STATIC_INLINE void ARM_PMU_Enable(void);
__STATIC_INLINE void ARM_PMU_Disable(void);
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type);
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void);
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void);
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask);
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void);
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num);
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void);
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask);
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask);
/**
\brief Enable the PMU
*/
__STATIC_INLINE void ARM_PMU_Enable(void)
{
PMU->CTRL |= PMU_CTRL_ENABLE_Msk;
}
/**
\brief Disable the PMU
*/
__STATIC_INLINE void ARM_PMU_Disable(void)
{
PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk;
}
/**
\brief Set event to count for PMU eventer counter
\param [in] num Event counter (0-30) to configure
\param [in] type Event to count
*/
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type)
{
PMU->EVTYPER[num] = type;
}
/**
\brief Reset cycle counter
*/
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void)
{
PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk;
}
/**
\brief Reset all event counters
*/
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void)
{
PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk;
}
/**
\brief Enable counters
\param [in] mask Counters to enable
\note Enables one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask)
{
PMU->CNTENSET = mask;
}
/**
\brief Disable counters
\param [in] mask Counters to enable
\note Disables one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask)
{
PMU->CNTENCLR = mask;
}
/**
\brief Read cycle counter
\return Cycle count
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void)
{
return PMU->CCNTR;
}
/**
\brief Read event counter
\param [in] num Event counter (0-30) to read
\return Event count
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num)
{
return PMU->EVCNTR[num];
}
/**
\brief Read counter overflow status
\return Counter overflow status bits for the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void)
{
return PMU->OVSSET;
}
/**
\brief Clear counter overflow status
\param [in] mask Counter overflow status bits to clear
\note Clears overflow status bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask)
{
PMU->OVSCLR = mask;
}
/**
\brief Enable counter overflow interrupt request
\param [in] mask Counter overflow interrupt request bits to set
\note Sets overflow interrupt request bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
{
PMU->INTENSET = mask;
}
/**
\brief Disable counter overflow interrupt request
\param [in] mask Counter overflow interrupt request bits to clear
\note Clears overflow interrupt request bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
{
PMU->INTENCLR = mask;
}
/**
\brief Software increment event counter
\param [in] mask Counters to increment
\note Software increment bits for one or more event counters (0-30)
*/
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask)
{
PMU->SWINC = mask;
}
#endif

View File

@ -0,0 +1,70 @@
/******************************************************************************
* @file tz_context.h
* @brief Context Management for Armv8-M TrustZone
* @version V1.0.1
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef TZ_CONTEXT_H
#define TZ_CONTEXT_H
#include <stdint.h>
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// \details TZ Memory ID identifies an allocated memory slot.
typedef uint32_t TZ_MemoryId_t;
/// Initialize secure context memory system
/// \return execution status (1: success, 0: error)
uint32_t TZ_InitContextSystem_S (void);
/// Allocate context memory for calling secure software modules in TrustZone
/// \param[in] module identifies software modules called from non-secure mode
/// \return value != 0 id TrustZone memory slot identifier
/// \return value 0 no memory available or internal error
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
/// Load secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
/// Store secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
#endif // TZ_CONTEXT_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,710 @@
;******************************************************************************************************************************************
; 文件名称: startup_SWM341.s
; 功能说明: SWM341单片机的启动文件
; 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
; 注意事项:
; 版本日期: V1.1.0 2017年10月25日
; 升级记录:
;
;
;******************************************************************************************************************************************
; @attention
;
; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
; REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
; FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
; OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
; -ECTION WITH THEIR PRODUCTS.
;
; COPYRIGHT 2012 Synwit Technology
;******************************************************************************************************************************************
; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00004000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD UART0_Handler
DCD UART1_Handler
DCD TIMR0_Handler
DCD TIMR1_Handler
DCD DMA_Handler
DCD SPI0_Handler
DCD PWM0_Handler
DCD WDT_Handler
DCD UART2_Handler
DCD PWM1_Handler
DCD ADC0_Handler
DCD BTIMR0_Handler
DCD HALL0_Handler
DCD PWM2_Handler
DCD PWMBRK_Handler
DCD I2C0_Handler
DCD CAN0_Handler
DCD SPI1_Handler
DCD RTC_Handler
DCD PWM3_Handler
DCD TIMR2_Handler
DCD UART3_Handler
DCD TIMR3_Handler
DCD ADC1_Handler
DCD BOD_Handler
DCD CORDIC_Handler
DCD BTIMR1_Handler
DCD PWM4_Handler
DCD HALL3_Handler
DCD BTIMR2_Handler
DCD I2C1_Handler
DCD BTIMR3_Handler
DCD ACMP_Handler
DCD XTALSTOP_Handler
DCD FSPI_Handler
DCD GPIOA_Handler
DCD GPIOB_Handler
DCD GPIOC_Handler
DCD GPIOD_Handler
DCD GPIOM_Handler
DCD GPION_Handler
DCD GPIOA0_Handler
DCD GPIOA1_Handler
DCD GPIOA5_Handler
DCD GPIOA6_Handler
DCD GPIOA10_Handler
DCD GPIOA11_Handler
DCD GPIOA12_Handler
DCD GPIOA13_Handler
DCD GPIOB0_Handler
DCD GPIOB1_Handler
DCD GPIOB2_Handler
DCD GPIOC0_Handler
DCD GPIOC1_Handler
DCD GPIOC2_Handler
DCD GPIOC3_Handler
DCD GPIOC4_Handler
DCD GPIOD3_Handler
DCD GPIOD4_Handler
DCD GPIOD5_Handler
DCD GPIOD6_Handler
DCD GPIOD7_Handler
DCD GPIOD8_Handler
DCD GPIOC9_Handler
DCD GPIOC10_Handler
DCD GPIOC11_Handler
DCD GPIOC12_Handler
DCD GPIOM0_Handler
DCD GPIOM1_Handler
DCD GPIOM2_Handler
DCD GPIOM3_Handler
DCD GPIOM4_Handler
DCD DIV_Handler
DCD LCD_Handler
DCD GPIOE_Handler
DCD JPEG_Handler
DCD SDIO_Handler
DCD USB_Handler
DCD CAN1_Handler
DCD TIMR4_Handler
DCD BTIMR4_Handler
DCD BTIMR5_Handler
DCD BTIMR6_Handler
DCD BTIMR7_Handler
DCD BTIMR8_Handler
DCD BTIMR9_Handler
DCD BTIMR10_Handler
DCD BTIMR11_Handler
DCD DMA2D_Handler
DCD QEI_Handler
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT FPU_Enable
LDR R0, =FPU_Enable
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
UART0_Handler PROC
EXPORT UART0_Handler [WEAK]
B .
ENDP
UART1_Handler PROC
EXPORT UART1_Handler [WEAK]
B .
ENDP
TIMR0_Handler PROC
EXPORT TIMR0_Handler [WEAK]
B .
ENDP
TIMR1_Handler PROC
EXPORT TIMR1_Handler [WEAK]
B .
ENDP
DMA_Handler PROC
EXPORT DMA_Handler [WEAK]
B .
ENDP
SPI0_Handler PROC
EXPORT SPI0_Handler [WEAK]
B .
ENDP
PWM0_Handler PROC
EXPORT PWM0_Handler [WEAK]
B .
ENDP
WDT_Handler PROC
EXPORT WDT_Handler [WEAK]
B .
ENDP
UART2_Handler PROC
EXPORT UART2_Handler [WEAK]
B .
ENDP
PWM1_Handler PROC
EXPORT PWM1_Handler [WEAK]
B .
ENDP
ADC0_Handler PROC
EXPORT ADC0_Handler [WEAK]
B .
ENDP
BTIMR0_Handler PROC
EXPORT BTIMR0_Handler [WEAK]
B .
ENDP
HALL0_Handler PROC
EXPORT HALL0_Handler [WEAK]
B .
ENDP
PWM2_Handler PROC
EXPORT PWM2_Handler [WEAK]
B .
ENDP
PWMBRK_Handler PROC
EXPORT PWMBRK_Handler [WEAK]
B .
ENDP
I2C0_Handler PROC
EXPORT I2C0_Handler [WEAK]
B .
ENDP
CAN0_Handler PROC
EXPORT CAN0_Handler [WEAK]
B .
ENDP
SPI1_Handler PROC
EXPORT SPI1_Handler [WEAK]
B .
ENDP
RTC_Handler PROC
EXPORT RTC_Handler [WEAK]
B .
ENDP
PWM3_Handler PROC
EXPORT PWM3_Handler [WEAK]
B .
ENDP
TIMR2_Handler PROC
EXPORT TIMR2_Handler [WEAK]
B .
ENDP
UART3_Handler PROC
EXPORT UART3_Handler [WEAK]
B .
ENDP
TIMR3_Handler PROC
EXPORT TIMR3_Handler [WEAK]
B .
ENDP
ADC1_Handler PROC
EXPORT ADC1_Handler [WEAK]
B .
ENDP
BOD_Handler PROC
EXPORT BOD_Handler [WEAK]
B .
ENDP
CORDIC_Handler PROC
EXPORT CORDIC_Handler [WEAK]
B .
ENDP
BTIMR1_Handler PROC
EXPORT BTIMR1_Handler [WEAK]
B .
ENDP
PWM4_Handler PROC
EXPORT PWM4_Handler [WEAK]
B .
ENDP
HALL3_Handler PROC
EXPORT HALL3_Handler [WEAK]
B .
ENDP
BTIMR2_Handler PROC
EXPORT BTIMR2_Handler [WEAK]
B .
ENDP
I2C1_Handler PROC
EXPORT I2C1_Handler [WEAK]
B .
ENDP
BTIMR3_Handler PROC
EXPORT BTIMR3_Handler [WEAK]
B .
ENDP
ACMP_Handler PROC
EXPORT ACMP_Handler [WEAK]
B .
ENDP
XTALSTOP_Handler PROC
EXPORT XTALSTOP_Handler [WEAK]
B .
ENDP
FSPI_Handler PROC
EXPORT FSPI_Handler [WEAK]
B .
ENDP
GPIOA_Handler PROC
EXPORT GPIOA_Handler [WEAK]
B .
ENDP
GPIOB_Handler PROC
EXPORT GPIOB_Handler [WEAK]
B .
ENDP
GPIOC_Handler PROC
EXPORT GPIOC_Handler [WEAK]
B .
ENDP
GPIOD_Handler PROC
EXPORT GPIOD_Handler [WEAK]
B .
ENDP
GPIOM_Handler PROC
EXPORT GPIOM_Handler [WEAK]
B .
ENDP
GPION_Handler PROC
EXPORT GPION_Handler [WEAK]
B .
ENDP
GPIOA0_Handler PROC
EXPORT GPIOA0_Handler [WEAK]
B .
ENDP
GPIOA1_Handler PROC
EXPORT GPIOA1_Handler [WEAK]
B .
ENDP
GPIOA5_Handler PROC
EXPORT GPIOA5_Handler [WEAK]
B .
ENDP
GPIOA6_Handler PROC
EXPORT GPIOA6_Handler [WEAK]
B .
ENDP
GPIOA10_Handler PROC
EXPORT GPIOA10_Handler [WEAK]
B .
ENDP
GPIOA11_Handler PROC
EXPORT GPIOA11_Handler [WEAK]
B .
ENDP
GPIOA12_Handler PROC
EXPORT GPIOA12_Handler [WEAK]
B .
ENDP
GPIOA13_Handler PROC
EXPORT GPIOA13_Handler [WEAK]
B .
ENDP
GPIOB0_Handler PROC
EXPORT GPIOB0_Handler [WEAK]
B .
ENDP
GPIOB1_Handler PROC
EXPORT GPIOB1_Handler [WEAK]
B .
ENDP
GPIOB2_Handler PROC
EXPORT GPIOB2_Handler [WEAK]
B .
ENDP
GPIOC0_Handler PROC
EXPORT GPIOC0_Handler [WEAK]
B .
ENDP
GPIOC1_Handler PROC
EXPORT GPIOC1_Handler [WEAK]
B .
ENDP
GPIOC2_Handler PROC
EXPORT GPIOC2_Handler [WEAK]
B .
ENDP
GPIOC3_Handler PROC
EXPORT GPIOC3_Handler [WEAK]
B .
ENDP
GPIOC4_Handler PROC
EXPORT GPIOC4_Handler [WEAK]
B .
ENDP
GPIOD3_Handler PROC
EXPORT GPIOD3_Handler [WEAK]
B .
ENDP
GPIOD4_Handler PROC
EXPORT GPIOD4_Handler [WEAK]
B .
ENDP
GPIOD5_Handler PROC
EXPORT GPIOD5_Handler [WEAK]
B .
ENDP
GPIOD6_Handler PROC
EXPORT GPIOD6_Handler [WEAK]
B .
ENDP
GPIOD7_Handler PROC
EXPORT GPIOD7_Handler [WEAK]
B .
ENDP
GPIOD8_Handler PROC
EXPORT GPIOD8_Handler [WEAK]
B .
ENDP
GPIOC9_Handler PROC
EXPORT GPIOC9_Handler [WEAK]
B .
ENDP
GPIOC10_Handler PROC
EXPORT GPIOC10_Handler [WEAK]
B .
ENDP
GPIOC11_Handler PROC
EXPORT GPIOC11_Handler [WEAK]
B .
ENDP
GPIOC12_Handler PROC
EXPORT GPIOC12_Handler [WEAK]
B .
ENDP
GPIOM0_Handler PROC
EXPORT GPIOM0_Handler [WEAK]
B .
ENDP
GPIOM1_Handler PROC
EXPORT GPIOM1_Handler [WEAK]
B .
ENDP
GPIOM2_Handler PROC
EXPORT GPIOM2_Handler [WEAK]
B .
ENDP
GPIOM3_Handler PROC
EXPORT GPIOM3_Handler [WEAK]
B .
ENDP
GPIOM4_Handler PROC
EXPORT GPIOM4_Handler [WEAK]
B .
ENDP
DIV_Handler PROC
EXPORT DIV_Handler [WEAK]
B .
ENDP
LCD_Handler PROC
EXPORT LCD_Handler [WEAK]
B .
ENDP
GPIOE_Handler PROC
EXPORT GPIOE_Handler [WEAK]
B .
ENDP
JPEG_Handler PROC
EXPORT JPEG_Handler [WEAK]
B .
ENDP
SDIO_Handler PROC
EXPORT SDIO_Handler [WEAK]
B .
ENDP
USB_Handler PROC
EXPORT USB_Handler [WEAK]
B .
ENDP
CAN1_Handler PROC
EXPORT CAN1_Handler [WEAK]
B .
ENDP
TIMR4_Handler PROC
EXPORT TIMR4_Handler [WEAK]
B .
ENDP
BTIMR4_Handler PROC
EXPORT BTIMR4_Handler [WEAK]
B .
ENDP
BTIMR5_Handler PROC
EXPORT BTIMR5_Handler [WEAK]
B .
ENDP
BTIMR6_Handler PROC
EXPORT BTIMR6_Handler [WEAK]
B .
ENDP
BTIMR7_Handler PROC
EXPORT BTIMR7_Handler [WEAK]
B .
ENDP
BTIMR8_Handler PROC
EXPORT BTIMR8_Handler [WEAK]
B .
ENDP
BTIMR9_Handler PROC
EXPORT BTIMR9_Handler [WEAK]
B .
ENDP
BTIMR10_Handler PROC
EXPORT BTIMR10_Handler [WEAK]
B .
ENDP
BTIMR11_Handler PROC
EXPORT BTIMR11_Handler [WEAK]
B .
ENDP
DMA2D_Handler PROC
EXPORT DMA2D_Handler [WEAK]
B .
ENDP
QEI_Handler PROC
EXPORT QEI_Handler [WEAK]
B .
ENDP
ALIGN
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END

View File

@ -0,0 +1,515 @@
.syntax unified
.cpu cortex-m33
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
.extern FPU_Enable
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
/* Call the clock system initialization function.*/
bl FPU_Enable
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl entry
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
* @param None
* @retval None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
/* External Interrupts */
.word UART0_Handler
.word UART1_Handler
.word TIMR0_Handler
.word TIMR1_Handler
.word DMA_Handler
.word SPI0_Handler
.word PWM0_Handler
.word WDT_Handler
.word UART2_Handler
.word PWM1_Handler
.word ADC0_Handler
.word BTIMR0_Handler
.word HALL0_Handler
.word PWM2_Handler
.word PWMBRK_Handler
.word I2C0_Handler
.word CAN0_Handler
.word SPI1_Handler
.word RTC_Handler
.word PWM3_Handler
.word TIMR2_Handler
.word UART3_Handler
.word TIMR3_Handler
.word ADC1_Handler
.word BOD_Handler
.word CORDIC_Handler
.word BTIMR1_Handler
.word PWM4_Handler
.word HALL3_Handler
.word BTIMR2_Handler
.word I2C1_Handler
.word BTIMR3_Handler
.word ACMP_Handler
.word XTALSTOP_Handler
.word FSPI_Handler
.word GPIOA_Handler
.word GPIOB_Handler
.word GPIOC_Handler
.word GPIOD_Handler
.word GPIOM_Handler
.word GPION_Handler
.word GPIOA0_Handler
.word GPIOA1_Handler
.word GPIOA5_Handler
.word GPIOA6_Handler
.word GPIOA10_Handler
.word GPIOA11_Handler
.word GPIOA12_Handler
.word GPIOA13_Handler
.word GPIOB0_Handler
.word GPIOB1_Handler
.word GPIOB2_Handler
.word GPIOC0_Handler
.word GPIOC1_Handler
.word GPIOC2_Handler
.word GPIOC3_Handler
.word GPIOC4_Handler
.word GPIOD3_Handler
.word GPIOD4_Handler
.word GPIOD5_Handler
.word GPIOD6_Handler
.word GPIOD7_Handler
.word GPIOD8_Handler
.word GPIOC9_Handler
.word GPIOC10_Handler
.word GPIOC11_Handler
.word GPIOC12_Handler
.word GPIOM0_Handler
.word GPIOM1_Handler
.word GPIOM2_Handler
.word GPIOM3_Handler
.word GPIOM4_Handler
.word DIV_Handler
.word LCD_Handler
.word GPIOE_Handler
.word JPEG_Handler
.word SDIO_Handler
.word USB_Handler
.word CAN1_Handler
.word TIMR4_Handler
.word BTIMR4_Handler
.word BTIMR5_Handler
.word BTIMR6_Handler
.word BTIMR7_Handler
.word BTIMR8_Handler
.word BTIMR9_Handler
.word BTIMR10_Handler
.word BTIMR11_Handler
.word DMA2D_Handler
.word QEI_Handler
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak UART0_Handler
.thumb_set UART0_Handler,Default_Handler
.weak UART1_Handler
.thumb_set UART1_Handler,Default_Handler
.weak TIMR0_Handler
.thumb_set TIMR0_Handler,Default_Handler
.weak TIMR1_Handler
.thumb_set TIMR1_Handler,Default_Handler
.weak DMA_Handler
.thumb_set DMA_Handler,Default_Handler
.weak SPI0_Handler
.thumb_set SPI0_Handler,Default_Handler
.weak PWM0_Handler
.thumb_set PWM0_Handler,Default_Handler
.weak WDT_Handler
.thumb_set WDT_Handler,Default_Handler
.weak UART2_Handler
.thumb_set UART2_Handler,Default_Handler
.weak PWM1_Handler
.thumb_set PWM1_Handler,Default_Handler
.weak ADC0_Handler
.thumb_set ADC0_Handler,Default_Handler
.weak BTIMR0_Handler
.thumb_set BTIMR0_Handler,Default_Handler
.weak HALL0_Handler
.thumb_set HALL0_Handler,Default_Handler
.weak PWM2_Handler
.thumb_set PWM2_Handler,Default_Handler
.weak PWMBRK_Handler
.thumb_set PWMBRK_Handler,Default_Handler
.weak I2C0_Handler
.thumb_set I2C0_Handler,Default_Handler
.weak CAN0_Handler
.thumb_set CAN0_Handler,Default_Handler
.weak SPI1_Handler
.thumb_set SPI1_Handler,Default_Handler
.weak RTC_Handler
.thumb_set RTC_Handler,Default_Handler
.weak PWM3_Handler
.thumb_set PWM3_Handler,Default_Handler
.weak TIMR2_Handler
.thumb_set TIMR2_Handler,Default_Handler
.weak UART3_Handler
.thumb_set UART3_Handler,Default_Handler
.weak TIMR3_Handler
.thumb_set TIMR3_Handler,Default_Handler
.weak ADC1_Handler
.thumb_set ADC1_Handler,Default_Handler
.weak BOD_Handler
.thumb_set BOD_Handler,Default_Handler
.weak CORDIC_Handler
.thumb_set CORDIC_Handler,Default_Handler
.weak BTIMR1_Handler
.thumb_set BTIMR1_Handler,Default_Handler
.weak PWM4_Handler
.thumb_set PWM4_Handler,Default_Handler
.weak HALL3_Handler
.thumb_set HALL3_Handler,Default_Handler
.weak BTIMR2_Handler
.thumb_set BTIMR2_Handler,Default_Handler
.weak I2C1_Handler
.thumb_set I2C1_Handler,Default_Handler
.weak BTIMR3_Handler
.thumb_set BTIMR3_Handler,Default_Handler
.weak ACMP_Handler
.thumb_set ACMP_Handler,Default_Handler
.weak XTALSTOP_Handler
.thumb_set XTALSTOP_Handler,Default_Handler
.weak FSPI_Handler
.thumb_set FSPI_Handler,Default_Handler
.weak GPIOA_Handler
.thumb_set GPIOA_Handler,Default_Handler
.weak GPIOB_Handler
.thumb_set GPIOB_Handler,Default_Handler
.weak GPIOC_Handler
.thumb_set GPIOC_Handler,Default_Handler
.weak GPIOD_Handler
.thumb_set GPIOD_Handler,Default_Handler
.weak GPIOM_Handler
.thumb_set GPIOM_Handler,Default_Handler
.weak GPION_Handler
.thumb_set GPION_Handler,Default_Handler
.weak GPIOA0_Handler
.thumb_set GPIOA0_Handler,Default_Handler
.weak GPIOA1_Handler
.thumb_set GPIOA1_Handler,Default_Handler
.weak GPIOA5_Handler
.thumb_set GPIOA5_Handler,Default_Handler
.weak GPIOA6_Handler
.thumb_set GPIOA6_Handler,Default_Handler
.weak GPIOA10_Handler
.thumb_set GPIOA10_Handler,Default_Handler
.weak GPIOA11_Handler
.thumb_set GPIOA11_Handler,Default_Handler
.weak GPIOA12_Handler
.thumb_set GPIOA12_Handler,Default_Handler
.weak GPIOA13_Handler
.thumb_set GPIOA13_Handler,Default_Handler
.weak GPIOB0_Handler
.thumb_set GPIOB0_Handler,Default_Handler
.weak GPIOB1_Handler
.thumb_set GPIOB1_Handler,Default_Handler
.weak GPIOB2_Handler
.thumb_set GPIOB2_Handler,Default_Handler
.weak GPIOC0_Handler
.thumb_set GPIOC0_Handler,Default_Handler
.weak GPIOC1_Handler
.thumb_set GPIOC1_Handler,Default_Handler
.weak GPIOC2_Handler
.thumb_set GPIOC2_Handler,Default_Handler
.weak GPIOC3_Handler
.thumb_set GPIOC3_Handler,Default_Handler
.weak GPIOC4_Handler
.thumb_set GPIOC4_Handler,Default_Handler
.weak GPIOD3_Handler
.thumb_set GPIOD3_Handler,Default_Handler
.weak GPIOD4_Handler
.thumb_set GPIOD4_Handler,Default_Handler
.weak GPIOD5_Handler
.thumb_set GPIOD5_Handler,Default_Handler
.weak GPIOD6_Handler
.thumb_set GPIOD6_Handler,Default_Handler
.weak GPIOD7_Handler
.thumb_set GPIOD7_Handler,Default_Handler
.weak GPIOD8_Handler
.thumb_set GPIOD8_Handler,Default_Handler
.weak GPIOC9_Handler
.thumb_set GPIOC9_Handler,Default_Handler
.weak GPIOC10_Handler
.thumb_set GPIOC10_Handler,Default_Handler
.weak GPIOC11_Handler
.thumb_set GPIOC11_Handler,Default_Handler
.weak GPIOC12_Handler
.thumb_set GPIOC12_Handler,Default_Handler
.weak GPIOM0_Handler
.thumb_set GPIOM0_Handler,Default_Handler
.weak GPIOM1_Handler
.thumb_set GPIOM1_Handler,Default_Handler
.weak GPIOM2_Handler
.thumb_set GPIOM2_Handler,Default_Handler
.weak GPIOM3_Handler
.thumb_set GPIOM3_Handler,Default_Handler
.weak GPIOM4_Handler
.thumb_set GPIOM4_Handler,Default_Handler
.weak DIV_Handler
.thumb_set DIV_Handler,Default_Handler
.weak LCD_Handler
.thumb_set LCD_Handler,Default_Handler
.weak GPIOE_Handler
.thumb_set GPIOE_Handler,Default_Handler
.weak JPEG_Handler
.thumb_set JPEG_Handler,Default_Handler
.weak SDIO_Handler
.thumb_set SDIO_Handler,Default_Handler
.weak USB_Handler
.thumb_set USB_Handler,Default_Handler
.weak CAN1_Handler
.thumb_set CAN1_Handler,Default_Handler
.weak TIMR4_Handler
.thumb_set TIMR4_Handler,Default_Handler
.weak BTIMR4_Handler
.thumb_set BTIMR4_Handler,Default_Handler
.weak BTIMR5_Handler
.thumb_set BTIMR5_Handler,Default_Handler
.weak BTIMR6_Handler
.thumb_set BTIMR6_Handler,Default_Handler
.weak BTIMR7_Handler
.thumb_set BTIMR7_Handler,Default_Handler
.weak BTIMR8_Handler
.thumb_set BTIMR8_Handler,Default_Handler
.weak BTIMR9_Handler
.thumb_set BTIMR9_Handler,Default_Handler
.weak BTIMR10_Handler
.thumb_set BTIMR10_Handler,Default_Handler
.weak BTIMR11_Handler
.thumb_set BTIMR11_Handler,Default_Handler
.weak DMA2D_Handler
.thumb_set DMA2D_Handler,Default_Handler
.weak QEI_Handler
.thumb_set QEI_Handler,Default_Handler

View File

@ -0,0 +1,648 @@
;******************************************************************************************************************************************
; 文件名称: startup_SWM341.s
; 功能说明: SWM341单片机的启动文件
; 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
; 注意事项:
; 版本日期: V1.0.0 2019年5月30日
; 升级记录:
;
;
;******************************************************************************************************************************************
; @attention
;
; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
; REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
; FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
; OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
; -ECTION WITH THEIR PRODUCTS.
;
; COPYRIGHT 2012 Synwit Technology
;******************************************************************************************************************************************
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
PUBLIC __vector_table
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD UART0_Handler
DCD UART1_Handler
DCD TIMR0_Handler
DCD TIMR1_Handler
DCD DMA_Handler
DCD SPI0_Handler
DCD PWM0_Handler
DCD WDT_Handler
DCD UART2_Handler
DCD PWM1_Handler
DCD ADC0_Handler
DCD BTIMR0_Handler
DCD HALL0_Handler
DCD PWM2_Handler
DCD PWMBRK_Handler
DCD I2C0_Handler
DCD CAN0_Handler
DCD SPI1_Handler
DCD RTC_Handler
DCD PWM3_Handler
DCD TIMR2_Handler
DCD UART3_Handler
DCD TIMR3_Handler
DCD ADC1_Handler
DCD BOD_Handler
DCD CORDIC_Handler
DCD BTIMR1_Handler
DCD PWM4_Handler
DCD HALL3_Handler
DCD BTIMR2_Handler
DCD I2C1_Handler
DCD BTIMR3_Handler
DCD ACMP_Handler
DCD XTALSTOP_Handler
DCD FSPI_Handler
DCD GPIOA_Handler
DCD GPIOB_Handler
DCD GPIOC_Handler
DCD GPIOD_Handler
DCD GPIOM_Handler
DCD GPION_Handler
DCD GPIOA0_Handler
DCD GPIOA1_Handler
DCD GPIOA5_Handler
DCD GPIOA6_Handler
DCD GPIOA10_Handler
DCD GPIOA11_Handler
DCD GPIOA12_Handler
DCD GPIOA13_Handler
DCD GPIOB0_Handler
DCD GPIOB1_Handler
DCD GPIOB2_Handler
DCD GPIOC0_Handler
DCD GPIOC1_Handler
DCD GPIOC2_Handler
DCD GPIOC3_Handler
DCD GPIOC4_Handler
DCD GPIOD3_Handler
DCD GPIOD4_Handler
DCD GPIOD5_Handler
DCD GPIOD6_Handler
DCD GPIOD7_Handler
DCD GPIOD8_Handler
DCD GPIOC9_Handler
DCD GPIOC10_Handler
DCD GPIOC11_Handler
DCD GPIOC12_Handler
DCD GPIOM0_Handler
DCD GPIOM1_Handler
DCD GPIOM2_Handler
DCD GPIOM3_Handler
DCD GPIOM4_Handler
DCD DIV_Handler
DCD LCD_Handler
DCD GPIOE_Handler
DCD JPEG_Handler
DCD SDIO_Handler
DCD USB_Handler
DCD CAN1_Handler
DCD TIMR4_Handler
DCD BTIMR4_Handler
DCD BTIMR5_Handler
DCD BTIMR6_Handler
DCD BTIMR7_Handler
DCD BTIMR8_Handler
DCD BTIMR9_Handler
DCD BTIMR10_Handler
DCD BTIMR11_Handler
DCD DMA2D_Handler
DCD QEI_Handler
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0, =__iar_program_start
BX R0
PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B NMI_Handler
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HardFault_Handler
B HardFault_Handler
PUBWEAK MemManage_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
MemManage_Handler
B MemManage_Handler
PUBWEAK BusFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BusFault_Handler
B BusFault_Handler
PUBWEAK UsageFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UsageFault_Handler
B UsageFault_Handler
PUBWEAK SVC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SVC_Handler
B SVC_Handler
PUBWEAK DebugMon_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
DebugMon_Handler
B DebugMon_Handler
PUBWEAK PendSV_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PendSV_Handler
B PendSV_Handler
PUBWEAK SysTick_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SysTick_Handler
B SysTick_Handler
PUBWEAK UART0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UART0_Handler
B UART0_Handler
PUBWEAK UART1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UART1_Handler
B UART1_Handler
PUBWEAK TIMR0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
TIMR0_Handler
B TIMR0_Handler
PUBWEAK TIMR1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
TIMR1_Handler
B TIMR1_Handler
PUBWEAK DMA_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
DMA_Handler
B DMA_Handler
PUBWEAK SPI0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SPI0_Handler
B SPI0_Handler
PUBWEAK PWM0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWM0_Handler
B PWM0_Handler
PUBWEAK WDT_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
WDT_Handler
B WDT_Handler
PUBWEAK UART2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UART2_Handler
B UART2_Handler
PUBWEAK PWM1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWM1_Handler
B PWM1_Handler
PUBWEAK ADC0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
ADC0_Handler
B ADC0_Handler
PUBWEAK BTIMR0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR0_Handler
B BTIMR0_Handler
PUBWEAK HALL0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HALL0_Handler
B HALL0_Handler
PUBWEAK PWM2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWM2_Handler
B PWM2_Handler
PUBWEAK PWMBRK_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWMBRK_Handler
B PWMBRK_Handler
PUBWEAK I2C0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
I2C0_Handler
B I2C0_Handler
PUBWEAK CAN0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
CAN0_Handler
B CAN0_Handler
PUBWEAK SPI1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SPI1_Handler
B SPI1_Handler
PUBWEAK RTC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
RTC_Handler
B RTC_Handler
PUBWEAK PWM3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWM3_Handler
B PWM3_Handler
PUBWEAK TIMR2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
TIMR2_Handler
B TIMR2_Handler
PUBWEAK UART3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UART3_Handler
B UART3_Handler
PUBWEAK TIMR3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
TIMR3_Handler
B TIMR3_Handler
PUBWEAK ADC1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
ADC1_Handler
B ADC1_Handler
PUBWEAK BOD_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BOD_Handler
B BOD_Handler
PUBWEAK CORDIC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
CORDIC_Handler
B CORDIC_Handler
PUBWEAK BTIMR1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR1_Handler
B BTIMR1_Handler
PUBWEAK PWM4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PWM4_Handler
B PWM4_Handler
PUBWEAK HALL3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HALL3_Handler
B HALL3_Handler
PUBWEAK BTIMR2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR2_Handler
B BTIMR2_Handler
PUBWEAK I2C1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
I2C1_Handler
B I2C1_Handler
PUBWEAK BTIMR3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR3_Handler
B BTIMR3_Handler
PUBWEAK ACMP_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
ACMP_Handler
B ACMP_Handler
PUBWEAK XTALSTOP_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
XTALSTOP_Handler
B XTALSTOP_Handler
PUBWEAK FSPI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
FSPI_Handler
B FSPI_Handler
PUBWEAK GPIOA_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA_Handler
B GPIOA_Handler
PUBWEAK GPIOB_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOB_Handler
B GPIOB_Handler
PUBWEAK GPIOC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC_Handler
B GPIOC_Handler
PUBWEAK GPIOD_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD_Handler
B GPIOD_Handler
PUBWEAK GPIOM_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM_Handler
B GPIOM_Handler
PUBWEAK GPION_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPION_Handler
B GPION_Handler
PUBWEAK GPIOA0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA0_Handler
B GPIOA0_Handler
PUBWEAK GPIOA1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA1_Handler
B GPIOA1_Handler
PUBWEAK GPIOA5_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA5_Handler
B GPIOA5_Handler
PUBWEAK GPIOA6_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA6_Handler
B GPIOA6_Handler
PUBWEAK GPIOA10_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA10_Handler
B GPIOA10_Handler
PUBWEAK GPIOA11_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA11_Handler
B GPIOA11_Handler
PUBWEAK GPIOA12_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA12_Handler
B GPIOA12_Handler
PUBWEAK GPIOA13_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOA13_Handler
B GPIOA13_Handler
PUBWEAK GPIOB0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOB0_Handler
B GPIOB0_Handler
PUBWEAK GPIOB1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOB1_Handler
B GPIOB1_Handler
PUBWEAK GPIOB2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOB2_Handler
B GPIOB2_Handler
PUBWEAK GPIOC0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC0_Handler
B GPIOC0_Handler
PUBWEAK GPIOC1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC1_Handler
B GPIOC1_Handler
PUBWEAK GPIOC2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC2_Handler
B GPIOC2_Handler
PUBWEAK GPIOC3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC3_Handler
B GPIOC3_Handler
PUBWEAK GPIOC4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC4_Handler
B GPIOC4_Handler
PUBWEAK GPIOD3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD3_Handler
B GPIOD3_Handler
PUBWEAK GPIOD4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD4_Handler
B GPIOD4_Handler
PUBWEAK GPIOD5_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD5_Handler
B GPIOD5_Handler
PUBWEAK GPIOD6_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD6_Handler
B GPIOD6_Handler
PUBWEAK GPIOD7_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD7_Handler
B GPIOD7_Handler
PUBWEAK GPIOD8_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOD8_Handler
B GPIOD8_Handler
PUBWEAK GPIOC9_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC9_Handler
B GPIOC9_Handler
PUBWEAK GPIOC10_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC10_Handler
B GPIOC10_Handler
PUBWEAK GPIOC11_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC11_Handler
B GPIOC11_Handler
PUBWEAK GPIOC12_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOC12_Handler
B GPIOC12_Handler
PUBWEAK GPIOM0_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM0_Handler
B GPIOM0_Handler
PUBWEAK GPIOM1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM1_Handler
B GPIOM1_Handler
PUBWEAK GPIOM2_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM2_Handler
B GPIOM2_Handler
PUBWEAK GPIOM3_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM3_Handler
B GPIOM3_Handler
PUBWEAK GPIOM4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOM4_Handler
B GPIOM4_Handler
PUBWEAK DIV_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
DIV_Handler
B DIV_Handler
PUBWEAK LCD_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
LCD_Handler
B LCD_Handler
PUBWEAK GPIOE_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
GPIOE_Handler
B GPIOE_Handler
PUBWEAK JPEG_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
JPEG_Handler
B JPEG_Handler
PUBWEAK SDIO_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SDIO_Handler
B SDIO_Handler
PUBWEAK USB_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
USB_Handler
B USB_Handler
PUBWEAK CAN1_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
CAN1_Handler
B CAN1_Handler
PUBWEAK TIMR4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
TIMR4_Handler
B TIMR4_Handler
PUBWEAK BTIMR4_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR4_Handler
B BTIMR4_Handler
PUBWEAK BTIMR5_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR5_Handler
B BTIMR5_Handler
PUBWEAK BTIMR6_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR6_Handler
B BTIMR6_Handler
PUBWEAK BTIMR7_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR7_Handler
B BTIMR7_Handler
PUBWEAK BTIMR8_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR8_Handler
B BTIMR8_Handler
PUBWEAK BTIMR9_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR9_Handler
B BTIMR9_Handler
PUBWEAK BTIMR10_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR10_Handler
B BTIMR10_Handler
PUBWEAK BTIMR11_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BTIMR11_Handler
B BTIMR11_Handler
PUBWEAK DMA2D_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
DMA2D_Handler
B DMA2D_Handler
PUBWEAK QEI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
QEI_Handler
B QEI_Handler
END

View File

@ -0,0 +1,410 @@
/******************************************************************************************************************************************
* : system_SWM341.c
* : SWM341单片机的时钟设置
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.1.0 20171025
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include <stdint.h>
#include "SWM341.h"
/******************************************************************************************************************************************
*
*****************************************************************************************************************************************/
#define SYS_CLK_20MHz 0 //0 内部高频20MHz RC振荡器
#define SYS_CLK_2M5Hz 1 //1 内部高频2.5MHz RC振荡器
#define SYS_CLK_40MHz 2 //2 内部高频40MHz RC振荡器
#define SYS_CLK_5MHz 3 //3 内部高频 5MHz RC振荡器
#define SYS_CLK_XTAL 4 //4 外部晶体振荡器4-32MHz
#define SYS_CLK_XTAL_DIV8 5 //5 外部晶体振荡器4-32MHz 8分频
#define SYS_CLK_PLL 6 //6 锁相环输出
#define SYS_CLK_PLL_DIV8 7 //7 锁相环输出 8分频
#define SYS_CLK_32KHz 8 //8 内部低频32KHz RC 振荡器
#define SYS_CLK_XTAL_32K 9 //9 外部低频32KHz 晶体振荡器
#define SYS_CLK SYS_CLK_PLL
#define __HSI (20000000UL) //高速内部时钟
#define __LSI ( 32000UL) //低速内部时钟
#define __HSE (12000000UL) //高速外部时钟
#define __LSE ( 32768UL) //低速外部时钟
/********************************** PLL 设定 **********************************************
* VCO输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV
* PLL输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV / OUTDIV = VCO输出频率 / OUTDIV
* VCO输出频率需要在 [600MHz, 1400MHz]
*****************************************************************************************/
#define SYS_PLL_SRC SYS_CLK_XTAL //可取值SYS_CLK_20MHz、SYS_CLK_XTAL
#define PLL_IN_DIV 3
#define PLL_FB_DIV 75
#define PLL_OUT_DIV8 0
#define PLL_OUT_DIV4 1
#define PLL_OUT_DIV2 2
#define PLL_OUT_DIV PLL_OUT_DIV8
uint32_t SystemCoreClock = __HSI; //System Clock Frequency (Core Clock)
uint32_t CyclesPerUs = (__HSI / 1000000); //Cycles per micro second
/******************************************************************************************************************************************
* :
* : This function is used to update the variable SystemCoreClock and must be called whenever the core clock is changed
* :
* :
* :
******************************************************************************************************************************************/
void SystemCoreClockUpdate(void)
{
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //SYS <= HRC
{
if(SYS->HRCCR & SYS_HRCCR_DBL_Msk) //HRC = 40MHz
{
SystemCoreClock = __HSI*2;
}
else //HRC = 20MHz
{
SystemCoreClock = __HSI;
}
}
else //SYS <= CLK
{
switch((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos)
{
case 0:
SystemCoreClock = __LSI;
break;
case 1:
if(SYS->PLLCR & SYS_PLLCR_INSEL_Msk) //PLL_IN <= HRC
{
SystemCoreClock = __HSI;
}
else //PLL_IN <= XTAL
{
SystemCoreClock = __HSE;
}
SystemCoreClock = SystemCoreClock / PLL_IN_DIV * PLL_FB_DIV * 4 / (2 << (2 - PLL_OUT_DIV));
break;
case 2:
SystemCoreClock = __LSE;
break;
case 3:
SystemCoreClock = __HSE;
break;
case 4:
SystemCoreClock = __HSI;
if(SYS->HRCCR & SYS_HRCCR_DBL_Msk) SystemCoreClock *= 2;
break;
}
if(SYS->CLKSEL & SYS_CLKSEL_CLK_DIVx_Msk) SystemCoreClock /= 8;
}
CyclesPerUs = SystemCoreClock / 1000000;
}
/******************************************************************************************************************************************
* :
* : The necessary initializaiton of systerm
* :
* :
* :
******************************************************************************************************************************************/
void SystemInit(void)
{
SYS->CLKEN0 |= (1 << SYS_CLKEN0_ANAC_Pos);
Flash_Param_at_xMHz(150);
switch(SYS_CLK)
{
case SYS_CLK_20MHz:
switchTo20MHz();
break;
case SYS_CLK_2M5Hz:
switchTo2M5Hz();
break;
case SYS_CLK_40MHz:
switchTo40MHz();
break;
case SYS_CLK_5MHz:
switchTo5MHz();
break;
case SYS_CLK_XTAL:
switchToXTAL(0);
break;
case SYS_CLK_XTAL_DIV8:
switchToXTAL(1);
break;
case SYS_CLK_PLL:
switchToPLL(0);
break;
case SYS_CLK_PLL_DIV8:
switchToPLL(1);
break;
case SYS_CLK_32KHz:
switchTo32KHz();
break;
case SYS_CLK_XTAL_32K:
switchToXTAL_32K();
break;
}
SystemCoreClockUpdate();
if(SystemCoreClock > 120000000)
{
Flash_Param_at_xMHz(150);
}
else if(SystemCoreClock > 80000000)
{
Flash_Param_at_xMHz(120);
}
else if(SystemCoreClock > 40000000)
{
Flash_Param_at_xMHz(80);
}
else if(SystemCoreClock > 30000000)
{
Flash_Param_at_xMHz(40);
}
else
{
Flash_Param_at_xMHz(30);
}
PORTM->PULLD &= ~(1 << PIN1);
PORTM->PULLU &= ~((1 << PIN2) | (1 << PIN3));
SYS->USBPHYCR &= ~SYS_USBPHYCR_OPMODE_Msk;
SYS->USBPHYCR |= (1 << SYS_USBPHYCR_OPMODE_Pos); //Non-Driving, DP Pull-Up disable
}
void FPU_Enable(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= (0xF << 20);
#endif
}
static void delay_3ms(void)
{
uint32_t i;
if(((SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) == 0) &&
((((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos) == 0) || //LSI 32KHz
(((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos) == 2))) //LSE 32KHz
{
for(i = 0; i < 20; i++) __NOP();
}
else
{
for(i = 0; i < 20000; i++) __NOP();
}
}
void switchTo20MHz(void)
{
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20Hz
delay_3ms();
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC
}
void switchTo2M5Hz(void)
{
switchTo20MHz();
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (4 << SYS_CLKSEL_CLK_Pos); //CLK <= HRC
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
delay_3ms();
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC/8
}
void switchTo40MHz(void)
{
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
(1 << SYS_HRCCR_DBL_Pos); //HRC = 40MHz
delay_3ms();
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC
}
void switchTo5MHz(void)
{
switchTo40MHz();
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (4 << SYS_CLKSEL_CLK_Pos); //CLK <= HRC
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
delay_3ms();
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC/8
}
void switchToXTAL(uint32_t div8)
{
switchTo20MHz();
PORT_Init(PORTA, PIN3, PORTA_PIN3_XTAL_IN, 0);
PORT_Init(PORTA, PIN4, PORTA_PIN4_XTAL_OUT, 0);
SYS->XTALCR |= (1 << SYS_XTALCR_ON_Pos) | (15 << SYS_XTALCR_DRV_Pos) | (1 << SYS_XTALCR_DET_Pos);
delay_3ms();
delay_3ms();
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (3 << SYS_CLKSEL_CLK_Pos); //CLK <= XTAL
if(div8) SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
else SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= XTAL
}
void switchToPLL(uint32_t div8)
{
switchTo20MHz();
PLLInit();
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_Pos); //CLK <= PLL
if(div8) SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
else SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= PLL
}
void switchTo32KHz(void)
{
switchTo20MHz();
SYS->LRCCR = (1 << SYS_LRCCR_ON_Pos);
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (0 << SYS_CLKSEL_CLK_Pos); //CLK <= LRC
SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
delay_3ms();
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= LRC
}
void switchToXTAL_32K(void)
{
uint32_t i;
switchTo20MHz();
SYS->XTALCR |= (1 << SYS_XTALCR_32KON_Pos) | (7 << SYS_XTALCR_32KDRV_Pos) | (1 << SYS_XTALCR_32KDET_Pos);
for(i = 0; i < 1000; i++) __NOP();
SYS->CLKDIVx_ON = 1;
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
SYS->CLKSEL |= (2 << SYS_CLKSEL_CLK_Pos); //CLK <= XTAL_32K
SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
delay_3ms();
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= XTAL_32K
}
void PLLInit(void)
{
if(SYS_PLL_SRC == SYS_CLK_20MHz)
{
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20Hz
delay_3ms();
SYS->PLLCR |= (1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= HRC
}
else if(SYS_PLL_SRC == SYS_CLK_XTAL)
{
PORT_Init(PORTA, PIN3, PORTA_PIN3_XTAL_IN, 0);
PORT_Init(PORTA, PIN4, PORTA_PIN4_XTAL_OUT, 0);
SYS->XTALCR |= (1 << SYS_XTALCR_ON_Pos) | (15 << SYS_XTALCR_DRV_Pos) | (1 << SYS_XTALCR_DET_Pos);
delay_3ms();
delay_3ms();
SYS->PLLCR &= ~(1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= XTAL
}
SYS->PLLDIV &= ~(SYS_PLLDIV_INDIV_Msk |
SYS_PLLDIV_FBDIV_Msk |
SYS_PLLDIV_OUTDIV_Msk);
SYS->PLLDIV |= (PLL_IN_DIV << SYS_PLLDIV_INDIV_Pos) |
(PLL_FB_DIV << SYS_PLLDIV_FBDIV_Pos) |
(PLL_OUT_DIV<< SYS_PLLDIV_OUTDIV_Pos);
SYS->PLLCR &= ~(1 << SYS_PLLCR_OFF_Pos);
while(SYS->PLLLOCK == 0); //等待PLL锁定
SYS->PLLCR |= (1 << SYS_PLLCR_OUTEN_Pos);
}

View File

@ -0,0 +1,33 @@
#ifndef __SYSTEM_SWM341_H__
#define __SYSTEM_SWM341_H__
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
extern uint32_t CyclesPerUs; // Cycles per micro second
extern void SystemInit(void);
extern void SystemCoreClockUpdate (void);
extern void PLLInit(void);
extern void switchTo20MHz(void);
extern void switchTo2M5Hz(void);
extern void switchTo40MHz(void);
extern void switchTo5MHz(void);
extern void switchToXTAL(uint32_t div8);
extern void switchToPLL(uint32_t div8);
extern void switchTo32KHz(void);
extern void switchToXTAL_32K(void);
#ifdef __cplusplus
}
#endif
#endif //__SYSTEM_SWM341_H__

View File

@ -0,0 +1,17 @@
from building import *
import rtconfig
cwd = GetCurrentDir()
src = Glob('CMSIS/DeviceSupport/*.c')
CPPPATH = [cwd + '/CMSIS/CoreSupport', cwd + '/CMSIS/DeviceSupport', cwd + '/SWM341_StdPeriph_Driver']
src += Glob('SWM341_StdPeriph_Driver/*.c')
if rtconfig.CROSS_TOOL == 'gcc':
src += ['CMSIS/DeviceSupport/startup/gcc/startup_SWM341.s']
elif rtconfig.CROSS_TOOL == 'keil':
src += ['CMSIS/DeviceSupport/startup/arm/startup_SWM341.s']
elif rtconfig.CROSS_TOOL == 'iar':
src += ['CMSIS/DeviceSupport/startup/iar/startup_SWM341.s']
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,355 @@
/******************************************************************************************************************************************
* : SWM341_adc.c
* : SWM341单片机的ADC数模转换器功能驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.0.0 2016130
* :
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_adc.h"
/******************************************************************************************************************************************
* : ADC_Init()
* : ADC模数转换器初始化
* : ADC_TypeDef * ADCx ADCADC0ADC1
* ADC_InitStructure * initStruct ADC各相关定值的结构体
* :
* :
******************************************************************************************************************************************/
void ADC_Init(ADC_TypeDef * ADCx, ADC_InitStructure * initStruct)
{
uint32_t i;
switch((uint32_t)ADCx)
{
case ((uint32_t)ADC0):
SYS->CLKSEL &= ~(SYS_CLKSEL_AD0_Msk | SYS_CLKSEL_AD0DIV_Msk);
SYS->CLKSEL |= (initStruct->clk_src << SYS_CLKSEL_AD0_Pos);
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_ADC0_Pos);
break;
case ((uint32_t)ADC1):
SYS->CLKSEL &= ~(SYS_CLKSEL_AD1_Msk | SYS_CLKSEL_AD1DIV_Msk);
SYS->CLKSEL |= (initStruct->clk_src << SYS_CLKSEL_AD1_Pos);
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_ADC1_Pos);
break;
}
ADC_Close(ADCx); //一些关键寄存器只能在ADC关闭时设置
ADCx->CR |= (1 <<ADC_CR_RESET_Pos);
for(i = 0; i < 120*20; i++) __NOP(); //至少2个采样时钟周期
ADCx->CR &= ~(1 << ADC_CR_RESET_Pos);
ADCx->CR |= (0xF << ADC_CR_FFCLR_Pos);
ADCx->CR &= ~(0xF << ADC_CR_FFCLR_Pos);
ADCx->CR &= ~ADC_CR_AVG_Msk;
ADCx->CR |= (initStruct->samplAvg << ADC_CR_AVG_Pos);
ADCx->IE = 0;
ADCx->IF = 0x3F3F3F3F; //清除中断标志
ADCx->IE |= (((initStruct->EOC_IEn & ADC_SEQ0) ? 1 : 0) << ADC_IE_SEQ0EOC_Pos) |
(((initStruct->EOC_IEn & ADC_SEQ1) ? 1 : 0) << ADC_IE_SEQ1EOC_Pos) |
(((initStruct->EOC_IEn & ADC_SEQ2) ? 1 : 0) << ADC_IE_SEQ2EOC_Pos) |
(((initStruct->EOC_IEn & ADC_SEQ3) ? 1 : 0) << ADC_IE_SEQ3EOC_Pos);
ADCx->IE |= (((initStruct->HalfIEn & ADC_SEQ0) ? 1 : 0) << ADC_IE_SEQ0HALF_Pos) |
(((initStruct->HalfIEn & ADC_SEQ1) ? 1 : 0) << ADC_IE_SEQ1HALF_Pos) |
(((initStruct->HalfIEn & ADC_SEQ2) ? 1 : 0) << ADC_IE_SEQ2HALF_Pos) |
(((initStruct->HalfIEn & ADC_SEQ3) ? 1 : 0) << ADC_IE_SEQ3HALF_Pos);
switch((uint32_t)ADCx)
{
case ((uint32_t)ADC0):
if(initStruct->EOC_IEn | initStruct->HalfIEn) NVIC_EnableIRQ(ADC0_IRQn);
break;
case ((uint32_t)ADC1):
if(initStruct->EOC_IEn | initStruct->HalfIEn) NVIC_EnableIRQ(ADC1_IRQn);
break;
}
}
static uint32_t ADC_seq2pos(uint32_t seq)
{
uint32_t pos = 0;
switch(seq)
{
case ADC_SEQ0: pos = 0; break;
case ADC_SEQ1: pos = 8; break;
case ADC_SEQ2: pos = 16; break;
case ADC_SEQ3: pos = 24; break;
}
return pos;
}
/******************************************************************************************************************************************
* : ADC_SEQ_Init()
* : ADC序列初始化
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* ADC_SEQ_InitStructure * initStruct ADC序列设定定值的结构体
* :
* :
******************************************************************************************************************************************/
void ADC_SEQ_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_SEQ_InitStructure * initStruct)
{
uint32_t pos = ADC_seq2pos(seq);
switch(seq)
{
case ADC_SEQ0:
case ADC_SEQ1:
ADCx->SEQCHN0 &= ~(0xFFFu << (pos * 2));
ADCx->SEQCHN0 |= (initStruct->channels << (pos * 2));
break;
case ADC_SEQ2:
case ADC_SEQ3:
ADCx->SEQCHN1 &= ~(0xFFFu << ((pos - 16) * 2));
ADCx->SEQCHN1 |= (initStruct->channels << ((pos - 16) * 2));
break;
}
ADCx->SEQTRG &= ~(0xFFu << pos);
ADCx->SEQTRG |= (initStruct->trig_src << pos);
ADCx->SEQCOV &= ~(0xFFu << pos);
ADCx->SEQCOV |= ((initStruct->conv_cnt ? initStruct->conv_cnt - 1 : 0) << pos);
ADCx->SEQSMP &= ~(0xFFu << pos);
ADCx->SEQSMP |= (initStruct->samp_tim << pos);
}
/******************************************************************************************************************************************
* : ADC_CMP_Init()
* : ADC比较功能初始化
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* ADC_CMP_InitStructure * initStruct ADC比较功能设定定值的结构体
* :
* :
******************************************************************************************************************************************/
void ADC_CMP_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_CMP_InitStructure * initStruct)
{
uint32_t idx;
uint32_t pos = ADC_seq2pos(seq);
idx = pos / 8;
ADCx->SEQ[idx].CMP = (initStruct->UpperLimit << ADC_CMP_MAX_Pos) |
(initStruct->LowerLimit << ADC_CMP_MIN_Pos);
if(initStruct->UpperLimitIEn) ADCx->IE |= (1 << (pos + 4));
else ADCx->IE &= ~(1 << (pos + 4));
if(initStruct->LowerLimitIEn) ADCx->IE |= (1 << (pos + 5));
else ADCx->IE &= ~(1 << (pos + 5));
if(initStruct->UpperLimitIEn || initStruct->LowerLimitIEn)
{
switch((uint32_t)ADCx)
{
case ((uint32_t)ADC0): NVIC_EnableIRQ(ADC0_IRQn); break;
case ((uint32_t)ADC1): NVIC_EnableIRQ(ADC1_IRQn); break;
}
}
}
/******************************************************************************************************************************************
* : ADC_Open()
* : ADC开启ADC转换
* : ADC_TypeDef * ADCx ADCADC0ADC1
* :
* :
******************************************************************************************************************************************/
void ADC_Open(ADC_TypeDef * ADCx)
{
uint32_t i;
ADCx->CR2 |= (1 << ADC_CR2_ENLDO_Pos);
for(i = 0; i < 64*20; i++) __NOP();
ADCx->CR |= (0x01 << ADC_CR_EN_Pos);
}
/******************************************************************************************************************************************
* : ADC_Calibrate()
* : ADC校准
* : ADC_TypeDef * ADCx ADCADC0ADC1
* :
* :
******************************************************************************************************************************************/
void ADC_Calibrate(ADC_TypeDef * ADCx)
{
uint32_t i;
ADCx->CALIB |= (1 << ADC_CALIB_RESET_Pos);
for(i = 0; i < 120 * 20; i++) __NOP(); //2个采样时钟周期
ADCx->CALIB |= (1 << ADC_CALIB_START_Pos);
for(i = 0; i < 120 * 10; i++) __NOP();
ADCx->CALIB &=~(1 << ADC_CALIB_START_Pos);
while(ADCx->CALIB & ADC_CALIB_BUSY_Msk) __NOP();
ADCx->CALIB |= (1 << ADC_CALIB_LOAD_Pos);
}
/******************************************************************************************************************************************
* : ADC_Close()
* : ADC关闭ADC转换
* : ADC_TypeDef * ADCx ADCADC0ADC1
* :
* :
******************************************************************************************************************************************/
void ADC_Close(ADC_TypeDef * ADCx)
{
ADCx->CR &= ~(0x01 << ADC_CR_EN_Pos);
}
/******************************************************************************************************************************************
* : ADC_Start()
* : ADC转换
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3及其组合
* :
* :
******************************************************************************************************************************************/
void ADC_Start(ADC_TypeDef * ADCx, uint32_t seq)
{
ADCx->GO |= (seq << ADC_GO_SEQ0_Pos);
}
/******************************************************************************************************************************************
* : ADC_Stop()
* : ADC转换
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3及其组合
* :
* :
******************************************************************************************************************************************/
void ADC_Stop(ADC_TypeDef * ADCx, uint32_t seq)
{
ADCx->GO &= ~(seq << ADC_GO_SEQ0_Pos);
}
/******************************************************************************************************************************************
* : ADC_Read()
* :
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* uint32_t *chn ADC_CH0ADC_CH1... ...ADC_CH10ADC_CH11
* : uint32_t
* :
******************************************************************************************************************************************/
uint32_t ADC_Read(ADC_TypeDef * ADCx, uint32_t seq, uint32_t *chn)
{
uint32_t idx = ADC_seq2pos(seq) / 8;
uint32_t reg = ADCx->SEQ[idx].DR;
*chn = 1 << ((reg & ADC_DR_CHNUM_Msk) >> ADC_DR_CHNUM_Pos);
return reg & ADC_DR_VALUE_Msk;
}
/******************************************************************************************************************************************
* : ADC_DataAvailable()
* :
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t ADC_DataAvailable(ADC_TypeDef * ADCx, uint32_t seq)
{
uint32_t idx = ADC_seq2pos(seq) / 8;
return (ADCx->SEQ[idx].SR & ADC_SR_EMPTY_Msk) ? 0 : 1;
}
/******************************************************************************************************************************************
* : ADC_INTEn()
* : 使
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* uint32_t it interrupt typeADC_IT_EOCADC_IT_FIFO_OVFADC_IT_FIFO_HALFADC_IT_FIFO_FULL
* ADC_IT_CMP_MAXADC_IT_CMP_MIN
* :
* :
******************************************************************************************************************************************/
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
{
uint32_t pos = ADC_seq2pos(seq);
ADCx->IE |= (it << pos);
}
/******************************************************************************************************************************************
* : ADC_INTDis()
* :
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* uint32_t it interrupt typeADC_IT_EOCADC_IT_FIFO_OVFADC_IT_FIFO_HALFADC_IT_FIFO_FULL
* ADC_IT_CMP_MAXADC_IT_CMP_MIN
* :
* :
******************************************************************************************************************************************/
void ADC_INTDis(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
{
uint32_t pos = ADC_seq2pos(seq);
ADCx->IE &= ~(it << pos);
}
/******************************************************************************************************************************************
* : ADC_INTClr()
* :
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* uint32_t it interrupt typeADC_IT_EOCADC_IT_FIFO_OVFADC_IT_FIFO_HALFADC_IT_FIFO_FULL
* ADC_IT_CMP_MAXADC_IT_CMP_MIN
* :
* :
******************************************************************************************************************************************/
void ADC_INTClr(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
{
uint32_t pos = ADC_seq2pos(seq);
ADCx->IF = (it << pos);
}
/******************************************************************************************************************************************
* : ADC_INTStat()
* :
* : ADC_TypeDef * ADCx ADCADC0ADC1
* uint32_t seq ADC序列ADC_SEQ0ADC_SEQ1ADC_SEQ2ADC_SEQ3
* uint32_t it interrupt typeADC_IT_EOCADC_IT_FIFO_OVFADC_IT_FIFO_HALFADC_IT_FIFO_FULL
* ADC_IT_CMP_MAXADC_IT_CMP_MIN
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t ADC_INTStat(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
{
uint32_t pos = ADC_seq2pos(seq);
return (ADCx->IF & (it << pos)) ? 1 : 0;
}

View File

@ -0,0 +1,109 @@
#ifndef __SWM341_ADC_H__
#define __SWM341_ADC_H__
typedef struct {
uint8_t clk_src; //ADC转换时钟源ADC_CLKSRC_HRC、ADC_CLKSRC_XTAL、...
uint8_t samplAvg; //采样取平均触发启动ADC转换后ADC在一个通道上连续采样、转换多次并将它们的平均值作为该通道转换结果
uint8_t EOC_IEn; //EOC中断使能 可针对每个序列设置其有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合即“按位或”运算
uint8_t HalfIEn; //FIFO半满中断使能可针对每个序列设置其有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合即“按位或”运算
} ADC_InitStructure;
typedef struct {
uint16_t channels; //ADC序列转换通道选中ADC_CH0、ADC_CH1、... ... 、ADC_CH7及其组合即“按位或”运算
uint8_t trig_src; //ADC序列触发方式ADC_TRIGGER_SW、ADC_TRIGGER_TIMER2、ADC_TRIGGER_TIMER3、... ...
uint16_t conv_cnt; //ADC序列转换次数可取值1--256
uint8_t samp_tim; //ADC序列采样时间可取值ADC_SAMPLE_1CLOCK、ADC_SAMPLE_2CLOCK、ADC_SAMPLE_4CLOCK、ADC_SAMPLE_8CLOCK
} ADC_SEQ_InitStructure;
typedef struct {
uint16_t UpperLimit; //比较上限值
uint16_t UpperLimitIEn; //ADC转换结果大于UpperLimit中断使能
uint16_t LowerLimit; //比较下限值
uint16_t LowerLimitIEn; //ADC转换结果小于LowerLimit中断使能
} ADC_CMP_InitStructure;
#define ADC_CH0 0x001
#define ADC_CH1 0x002
#define ADC_CH2 0x004
#define ADC_CH3 0x008
#define ADC_CH4 0x010
#define ADC_CH5 0x020
#define ADC_CH6 0x040
#define ADC_CH7 0x080
#define ADC_CH8 0x100
#define ADC_CH9 0x200
#define ADC_CH10 0x400
#define ADC_CH11 0x800
#define ADC_SEQ0 0x1
#define ADC_SEQ1 0x2
#define ADC_SEQ2 0x4
#define ADC_SEQ3 0x8
#define ADC_CLKSRC_HRC ((0 << 2) | 0)
#define ADC_CLKSRC_XTAL ((0 << 2) | 1)
#define ADC_CLKSRC_PLL ((0 << 2) | 2)
#define ADC_CLKSRC_HRC_DIV4 ((2 << 2) | 0)
#define ADC_CLKSRC_XTAL_DIV4 ((2 << 2) | 1)
#define ADC_CLKSRC_PLL_DIV4 ((2 << 2) | 2)
#define ADC_CLKSRC_HRC_DIV8 ((3 << 2) | 0)
#define ADC_CLKSRC_XTAL_DIV8 ((3 << 2) | 1)
#define ADC_CLKSRC_PLL_DIV8 ((3 << 2) | 2)
#define ADC_AVG_SAMPLE1 0
#define ADC_AVG_SAMPLE2 1 //一次启动连续采样、转换2次并计算两次结果的平均值作为转换结果
#define ADC_AVG_SAMPLE4 2
#define ADC_AVG_SAMPLE8 3
#define ADC_TRIGGER_NO 0
#define ADC_TRIGGER_SW 1 //软件启动
#define ADC_TRIGGER_TIMER2 2
#define ADC_TRIGGER_TIMER3 3
#define ADC_TRIGGER_EXTRIG0 4
#define ADC_TRIGGER_EXTRIG1 5
#define ADC_TRIGGER_PWM0 0x10
#define ADC_TRIGGER_PWM1 0x11
#define ADC_TRIGGER_PWM2 0x12
#define ADC_TRIGGER_PWM3 0x13
#define ADC_TRIGGER_PWM4 0x14
#define ADC_SAMPLE_1CLOCK 0
#define ADC_SAMPLE_2CLOCK 1
#define ADC_SAMPLE_4CLOCK 2
#define ADC_SAMPLE_8CLOCK 3
#define ADC_SAMPLE_16CLOCK 4
#define ADC_SAMPLE_32CLOCK 5
#define ADC_SAMPLE_64CLOCK 6
#define ADC_SAMPLE_128CLOCK 7
/* Interrupt Type */
#define ADC_IT_EOC (1 << 0) //End Of Conversion
#define ADC_IT_FIFO_OVF (1 << 1) //FIFO Overflow
#define ADC_IT_FIFO_HALF (1 << 2) //FIFO Half Full
#define ADC_IT_FIFO_FULL (1 << 3) //FIFO Full
#define ADC_IT_CMP_MAX (1 << 4) //转换结果大于COMP.MAX
#define ADC_IT_CMP_MIN (1 << 5) //转换结果小于COMP.MIN
void ADC_Init(ADC_TypeDef * ADCx, ADC_InitStructure * initStruct); //ADC模数转换器初始化
void ADC_SEQ_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_SEQ_InitStructure * initStruct); //ADC序列初始化
void ADC_CMP_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_CMP_InitStructure * initStruct); //ADC比较功能初始化
void ADC_Open(ADC_TypeDef * ADCx); //ADC开启可以软件启动、或硬件触发ADC转换
void ADC_Calibrate(ADC_TypeDef * ADCx); //ADC校准
void ADC_Close(ADC_TypeDef * ADCx); //ADC关闭无法软件启动、或硬件触发ADC转换
void ADC_Start(ADC_TypeDef * ADCx, uint32_t seq); //启动指定ADC开始模数转换
void ADC_Stop(ADC_TypeDef * ADCx, uint32_t seq); //关闭指定ADC停止模数转换
uint32_t ADC_Read(ADC_TypeDef * ADCx, uint32_t seq, uint32_t *chn); //从指定通道读取转换结果
uint32_t ADC_DataAvailable(ADC_TypeDef * ADCx, uint32_t seq); //指定序列是否有数据可读取
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
void ADC_INTClr(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
uint32_t ADC_INTStat(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
#endif //__SWM341_ADC_H__

View File

@ -0,0 +1,427 @@
/******************************************************************************************************************************************
* : SWM341_can.c
* : SWM341单片机的CAN模块驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.1.0 20171025
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_can.h"
/******************************************************************************************************************************************
* : CAN_Init()
* : CAN接口初始化
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* CAN_InitStructure * initStruct CAN接口相关设定值的结构体
* :
* :
******************************************************************************************************************************************/
void CAN_Init(CAN_TypeDef * CANx, CAN_InitStructure * initStruct)
{
uint32_t brp = (SystemCoreClock/2)/2/initStruct->Baudrate/(1 + (initStruct->CAN_bs1 + 1) + (initStruct->CAN_bs2 + 1)) - 1;
switch((uint32_t)CANx)
{
case ((uint32_t)CAN0):
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CAN0_Pos);
break;
case ((uint32_t)CAN1):
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_CAN1_Pos);
break;
}
CAN_Close(CANx); //一些关键寄存器只能在CAN关闭时设置
CANx->CR &= ~(CAN_CR_LOM_Msk | CAN_CR_STM_Msk);
CANx->CR |= (initStruct->Mode << CAN_CR_LOM_Pos);
CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
(initStruct->CAN_bs1 << CAN_BT1_TSEG1_Pos) |
(initStruct->CAN_bs2 << CAN_BT1_TSEG2_Pos);
CANx->BT0 = (initStruct->CAN_sjw << CAN_BT0_SJW_Pos) |
((brp & 0x3F) << CAN_BT0_BRP_Pos);
CANx->BT2 = ((brp >> 6) << CAN_BT2_BRP_Pos);
CANx->RXERR = 0; //只能在复位模式下清除
CANx->TXERR = 0;
CANx->IE = (initStruct->RXNotEmptyIEn << CAN_IE_RXDA_Pos) |
(initStruct->ArbitrLostIEn << CAN_IE_ARBLOST_Pos) |
(initStruct->ErrPassiveIEn << CAN_IE_ERRPASS_Pos);
switch((uint32_t)CANx)
{
case ((uint32_t)CAN0):
if(initStruct->RXNotEmptyIEn | initStruct->ArbitrLostIEn | initStruct->ErrPassiveIEn)
{
NVIC_EnableIRQ(CAN0_IRQn);
}
else
{
NVIC_DisableIRQ(CAN0_IRQn);
}
break;
case ((uint32_t)CAN1):
if(initStruct->RXNotEmptyIEn | initStruct->ArbitrLostIEn | initStruct->ErrPassiveIEn)
{
NVIC_EnableIRQ(CAN1_IRQn);
}
else
{
NVIC_DisableIRQ(CAN1_IRQn);
}
break;
}
}
/******************************************************************************************************************************************
* : CAN_Open()
* : CAN接口打开
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* :
* :
******************************************************************************************************************************************/
void CAN_Open(CAN_TypeDef * CANx)
{
CANx->CR &= ~(0x01 << CAN_CR_RST_Pos); //退出复位模式,进入工作模式
}
/******************************************************************************************************************************************
* : CAN_Close()
* : CAN接口关闭
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* :
* :
******************************************************************************************************************************************/
void CAN_Close(CAN_TypeDef * CANx)
{
CANx->CR |= (0x01 << CAN_CR_RST_Pos); //进入复位模式,不能发送和接收数据
}
/******************************************************************************************************************************************
* : CAN_Transmit()
* : CAN发送数据
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t format CAN_FRAME_STD CAN_FRAME_EXT
* uint32_t id ID
* uint8_t data[]
* uint32_t size
* uint32_t once 使NAK
* :
* :
******************************************************************************************************************************************/
void CAN_Transmit(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint8_t data[], uint32_t size, uint32_t once)
{
uint32_t i;
if(format == CAN_FRAME_STD)
{
CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(size << CAN_INFO_DLC_Pos);
CANx->FRAME.DATA[0] = id >> 3;
CANx->FRAME.DATA[1] = id << 5;
for(i = 0; i < size; i++)
{
CANx->FRAME.DATA[i+2] = data[i];
}
}
else //if(format == CAN_FRAME_EXT)
{
CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(size << CAN_INFO_DLC_Pos);
CANx->FRAME.DATA[0] = id >> 21;
CANx->FRAME.DATA[1] = id >> 13;
CANx->FRAME.DATA[2] = id >> 5;
CANx->FRAME.DATA[3] = id << 3;
for(i = 0; i < size; i++)
{
CANx->FRAME.DATA[i+4] = data[i];
}
}
if(CANx->CR & CAN_CR_STM_Msk)
{
CANx->CMD = (1 << CAN_CMD_SRR_Pos);
}
else
{
if(once == 0)
{
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
else
{
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos) | (1 << CAN_CMD_ABTTX_Pos);
}
}
}
/******************************************************************************************************************************************
* : CAN_TransmitRequest()
* : CAN发送远程请求
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t format CAN_FRAME_STD CAN_FRAME_EXT
* uint32_t id ID
* uint32_t once 使NAK
* :
* :
******************************************************************************************************************************************/
void CAN_TransmitRequest(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint32_t once)
{
if(format == CAN_FRAME_STD)
{
CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
CANx->FRAME.DATA[0] = id >> 3;
CANx->FRAME.DATA[1] = id << 5;
}
else //if(format == CAN_FRAME_EXT)
{
CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
CANx->FRAME.DATA[0] = id >> 21;
CANx->FRAME.DATA[1] = id >> 13;
CANx->FRAME.DATA[2] = id >> 5;
CANx->FRAME.DATA[3] = id << 3;
}
if(once == 0)
{
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
else
{
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos) | (1 << CAN_CMD_ABTTX_Pos);
}
}
/******************************************************************************************************************************************
* : CAN_Receive()
* : CAN接收数据
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* CAN_RXMessage *msg
* :
* :
******************************************************************************************************************************************/
void CAN_Receive(CAN_TypeDef * CANx, CAN_RXMessage *msg)
{
uint32_t i;
msg->format = (CANx->FRAME.INFO & CAN_INFO_FF_Msk) >> CAN_INFO_FF_Pos;
msg->remote = (CANx->FRAME.INFO & CAN_INFO_RTR_Msk) >> CAN_INFO_RTR_Pos;
msg->size = (CANx->FRAME.INFO & CAN_INFO_DLC_Msk) >> CAN_INFO_DLC_Pos;
if(msg->format == CAN_FRAME_STD)
{
msg->id = (CANx->FRAME.DATA[0] << 3) | (CANx->FRAME.DATA[1] >> 5);
for(i = 0; i < msg->size; i++)
{
msg->data[i] = CANx->FRAME.DATA[i+2];
}
}
else //if(msg->format == CAN_FRAME_EXT)
{
msg->id = (CANx->FRAME.DATA[0] << 21) | (CANx->FRAME.DATA[1] << 13) | (CANx->FRAME.DATA[2] << 5) | (CANx->FRAME.DATA[3] >> 3);
for(i = 0; i < msg->size; i++)
{
msg->data[i] = CANx->FRAME.DATA[i+4];
}
}
CANx->CMD = (1 << CAN_CMD_RRB_Pos);
}
/******************************************************************************************************************************************
* : CAN_TXComplete()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* : uint32_t 1 0
* : Abort也会触发发送完成
******************************************************************************************************************************************/
uint32_t CAN_TXComplete(CAN_TypeDef * CANx)
{
return (CANx->SR & CAN_SR_TXBR_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CAN_TXSuccess()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t CAN_TXSuccess(CAN_TypeDef * CANx)
{
return (CANx->SR & CAN_SR_TXOK_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CAN_AbortTransmit()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* :
* :
******************************************************************************************************************************************/
void CAN_AbortTransmit(CAN_TypeDef * CANx)
{
CANx->CMD = (1 << CAN_CMD_ABTTX_Pos);
}
/******************************************************************************************************************************************
* : CAN_TXBufferReady()
* : TX Buffer是否准备好可以写入消息
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t CAN_TXBufferReady(CAN_TypeDef * CANx)
{
return (CANx->SR & CAN_SR_TXBR_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CAN_RXDataAvailable()
* : RX FIFO中是否有数据可读出
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t CAN_RXDataAvailable(CAN_TypeDef * CANx)
{
return (CANx->SR & CAN_SR_RXDA_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CAN_SetBaudrate()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t baudrate
* uint32_t CAN_bs1 CAN_BS1_1tqCAN_BS1_2tq... ... CAN_BS1_16tq
* uint32_t CAN_bs2 CAN_BS2_1tqCAN_BS2_2tq... ... CAN_BS2_8tq
* uint32_t CAN_sjw CAN_SJW_1tqCAN_SJW_2tqCAN_SJW_3tqCAN_SJW_4tq
* :
* : CAN_Close()CAN模块
******************************************************************************************************************************************/
void CAN_SetBaudrate(CAN_TypeDef * CANx, uint32_t baudrate, uint32_t CAN_bs1, uint32_t CAN_bs2, uint32_t CAN_sjw)
{
uint32_t brp = (SystemCoreClock/2)/2/baudrate/(1 + (CAN_bs1 + 1) + (CAN_bs2 + 1)) - 1;
CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
(CAN_bs1 << CAN_BT1_TSEG1_Pos) |
(CAN_bs2 << CAN_BT1_TSEG2_Pos);
CANx->BT0 = (CAN_sjw << CAN_BT0_SJW_Pos) |
((brp & 0x3F) << CAN_BT0_BRP_Pos);
CANx->BT2 = ((brp >> 6) << CAN_BT2_BRP_Pos);
}
/******************************************************************************************************************************************
* : CAN_SetFilter32b()
* : 132
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t filter CAN_FILTER_1CAN_FILTER_2...CAN_FILTER_16
* uint32_t check mask一起决定了接收到的Message是否是自己需要的check & mask == ID & mask的Message通过过滤
* uint32_t mask
* :
* :
******************************************************************************************************************************************/
void CAN_SetFilter32b(CAN_TypeDef * CANx, uint32_t filter, uint32_t check, uint32_t mask)
{
CANx->AFM |= (1 << filter);
CANx->ACR[filter] = __REV(check << 3); // 高29位
CANx->AMR[filter] = __REV(~(mask << 3));
CANx->AFE |= (1 << filter);
}
/******************************************************************************************************************************************
* : CAN_SetFilter16b()
* : 216
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t filter CAN_FILTER_1CAN_FILTER_2...CAN_FILTER_16
* uint16_t check1 mask一起决定了接收到的Message是否是自己需要的check & mask == ID & mask的Message通过过滤
* uint16_t mask1
* uint16_t check2
* uint16_t mask2
* :
* :
******************************************************************************************************************************************/
void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint16_t mask1, uint16_t check2, uint16_t mask2)
{
CANx->AFM &= ~(1 << filter);
CANx->ACR[filter] = __REV((check1 << 5) | (check2 << 21)); // 高11位
CANx->AMR[filter] = __REV(~((mask1 << 5) | (mask2 << 21)));
CANx->AFE |= (1 << filter);
}
/******************************************************************************************************************************************
* : CAN_INTEn()
* : 使
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t it interrupt typeCAN_INT_RX_NOTEMPTYCAN_INT_RX_OVERFLOWCAN_INT_TX_EMPTY...
* :
* :
******************************************************************************************************************************************/
void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it)
{
CANx->IE |= it;
}
/******************************************************************************************************************************************
* : CAN_INTDis()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* uint32_t it interrupt typeCAN_INT_RX_NOTEMPTYCAN_INT_RX_OVERFLOWCAN_INT_TX_EMPTY...
* :
* :
******************************************************************************************************************************************/
void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it)
{
CANx->IE &= ~it;
}
/******************************************************************************************************************************************
* : CAN_INTStat()
* :
* : CAN_TypeDef * CANx CAN接口CAN0CAN1
* : uint32_t
* : CANx->IF读取清零ISR中只能读取一次
******************************************************************************************************************************************/
uint32_t CAN_INTStat(CAN_TypeDef * CANx)
{
return CANx->IF;
}

View File

@ -0,0 +1,117 @@
#ifndef __SWM341_CAN_H__
#define __SWM341_CAN_H__
typedef struct {
uint8_t Mode; //CAN_MODE_NORMAL、CAN_MODE_LISTEN、CAN_MODE_SELFTEST
uint8_t CAN_bs1; //CAN_BS1_1tq、CAN_BS1_2tq、... ... 、CAN_BS1_16tq
uint8_t CAN_bs2; //CAN_BS2_1tq、CAN_BS2_2tq、... ... 、CAN_BS2_8tq
uint8_t CAN_sjw; //CAN_SJW_1tq、CAN_SJW_2tq、CAN_SJW_3tq、CAN_SJW_4tq
uint32_t Baudrate; //波特率即位传输速率取值1--1000000
uint8_t RXNotEmptyIEn; //接收FIFO非空有数据可读
uint8_t ArbitrLostIEn; //控制器丢失仲裁变成接收方
uint8_t ErrPassiveIEn; //接收/发送错误计数值达到127
} CAN_InitStructure;
#define CAN_MODE_NORMAL 0 //常规模式
#define CAN_MODE_LISTEN 1 //监听模式
#define CAN_MODE_SELFTEST 2 //自测模式
#define CAN_BS1_1tq 0
#define CAN_BS1_2tq 1
#define CAN_BS1_3tq 2
#define CAN_BS1_4tq 3
#define CAN_BS1_5tq 4
#define CAN_BS1_6tq 5
#define CAN_BS1_7tq 6
#define CAN_BS1_8tq 7
#define CAN_BS1_9tq 8
#define CAN_BS1_10tq 9
#define CAN_BS1_11tq 10
#define CAN_BS1_12tq 11
#define CAN_BS1_13tq 12
#define CAN_BS1_14tq 13
#define CAN_BS1_15tq 14
#define CAN_BS1_16tq 15
#define CAN_BS2_1tq 0
#define CAN_BS2_2tq 1
#define CAN_BS2_3tq 2
#define CAN_BS2_4tq 3
#define CAN_BS2_5tq 4
#define CAN_BS2_6tq 5
#define CAN_BS2_7tq 6
#define CAN_BS2_8tq 7
#define CAN_SJW_1tq 0
#define CAN_SJW_2tq 1
#define CAN_SJW_3tq 2
#define CAN_SJW_4tq 3
#define CAN_FRAME_STD 0
#define CAN_FRAME_EXT 1
#define CAN_FILTER_1 0
#define CAN_FILTER_2 1
#define CAN_FILTER_3 2
#define CAN_FILTER_4 3
#define CAN_FILTER_5 4
#define CAN_FILTER_6 5
#define CAN_FILTER_7 6
#define CAN_FILTER_8 7
#define CAN_FILTER_9 8
#define CAN_FILTER_10 9
#define CAN_FILTER_11 10
#define CAN_FILTER_12 11
#define CAN_FILTER_13 12
#define CAN_FILTER_14 13
#define CAN_FILTER_15 14
#define CAN_FILTER_16 15
#define CAN_INT_RX_NOTEMPTY (0x01 << 0) //RX Buffer Not Empty
#define CAN_INT_RX_OVERFLOW (0x01 << 3) //RX Buffer Overflow
#define CAN_INT_TX_EMPTY (0x01 << 1) //TX Buffer Empty
#define CAN_INT_ARBLOST (0x01 << 6) //Arbitration lost
#define CAN_INT_ERR (0x01 << 7)
#define CAN_INT_ERR_WARN (0x01 << 2) //TXERR/RXERR计数值达到Error Warning Limit
#define CAN_INT_ERR_PASS (0x01 << 5) //TXERR/RXERR计数值达到127
#define CAN_INT_WAKEUP (0x01 << 4)
typedef struct {
uint32_t id; //消息ID
uint8_t format; //帧格式CAN_FRAME_STD、CAN_FRAME_EXT
uint8_t remote; //消息是否为远程帧
uint8_t size; //接收到的数据个数
uint8_t data[8]; //接收到的数据
} CAN_RXMessage;
void CAN_Init(CAN_TypeDef * CANx, CAN_InitStructure * initStruct);
void CAN_Open(CAN_TypeDef * CANx);
void CAN_Close(CAN_TypeDef * CANx);
void CAN_Transmit(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint8_t data[], uint32_t size, uint32_t once);
void CAN_TransmitRequest(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint32_t once);
void CAN_Receive(CAN_TypeDef * CANx, CAN_RXMessage *msg);
uint32_t CAN_TXComplete(CAN_TypeDef * CANx);
uint32_t CAN_TXSuccess(CAN_TypeDef * CANx);
void CAN_AbortTransmit(CAN_TypeDef * CANx);
uint32_t CAN_TXBufferReady(CAN_TypeDef * CANx);
uint32_t CAN_RXDataAvailable(CAN_TypeDef * CANx);
void CAN_SetBaudrate(CAN_TypeDef * CANx, uint32_t baudrate, uint32_t CAN_bs1, uint32_t CAN_bs2, uint32_t CAN_sjw);
void CAN_SetFilter32b(CAN_TypeDef * CANx, uint32_t filter, uint32_t check, uint32_t mask);
void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint16_t mask1, uint16_t check2, uint16_t mask2);
void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it);
void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it);
uint32_t CAN_INTStat(CAN_TypeDef * CANx);
#endif //__SWM341_CAN_H__

View File

@ -0,0 +1,40 @@
/******************************************************************************************************************************************
* : SWM341_cordic.c
* : SWM341单片机的CORDIC功能驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.0.0 2016130
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_cordic.h"
/******************************************************************************************************************************************
* : CORDIC_Init()
* : CORDIC初始化
* : CORDIC_TypeDef * CORDICx CORDICCORDIC
* :
* : CORDIC模块依赖DIV模块CORDIC_Arctan()使
******************************************************************************************************************************************/
void CORDIC_Init(CORDIC_TypeDef * CORDICx)
{
switch((uint32_t)CORDICx)
{
case ((uint32_t)CORDIC):
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CORDIC_Pos);
break;
}
}

View File

@ -0,0 +1,216 @@
#ifndef __SWM341_CORDIC_H__
#define __SWM341_CORDIC_H__
#define CORDIC_PI 3.141592653589793
void CORDIC_Init(CORDIC_TypeDef * CORDICx);
/******************************************************************************************************************************************
* : CORDIC_Sin()
* : 使CORDIC模块计算sin
* : uint32_t radian sin值的角度0.01~1.5616384
* :
* : 16384
******************************************************************************************************************************************/
static __INLINE void CORDIC_Sin(uint32_t radian)
{
CORDIC->INPUT = radian;
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (1 << CORDIC_CMD_SINCOS_Pos);
}
/******************************************************************************************************************************************
* : CORDIC_Sin_IsDone()
* : CORDIC模块sin运算是否完成
* :
* : uint32_t 0 sin运算未完成 1 sin运算已完成
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Sin_IsDone(void)
{
return (CORDIC->SIN & CORDIC_SIN_DONE_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CORDIC_Sin_Result()
* : CORDIC模块sin运算结果
* :
* : uint32_t sin运算结果Result[15:14]Result[13:0]
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Sin_Result(void)
{
return CORDIC->SIN & (CORDIC_SIN_F_Msk | CORDIC_SIN_I_Msk);
}
/******************************************************************************************************************************************
* : CORDIC_Cos()
* : 使CORDIC模块计算cos
* : uint32_t radian cos值的角度0.01~1.5616384
* :
* : 16384
******************************************************************************************************************************************/
static __INLINE void CORDIC_Cos(uint32_t radian)
{
CORDIC->INPUT = radian;
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (1 << CORDIC_CMD_SINCOS_Pos);
}
/******************************************************************************************************************************************
* : CORDIC_Cos_IsDone()
* : CORDIC模块cos运算是否完成
* :
* : uint32_t 0 cos运算未完成 1 cos运算已完成
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Cos_IsDone(void)
{
return (CORDIC->COS & CORDIC_COS_DONE_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CORDIC_Cos_Result()
* : CORDIC模块cos运算结果
* :
* : uint32_t cos运算结果Result[15:14]Result[13:0]
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Cos_Result(void)
{
return CORDIC->COS & (CORDIC_COS_F_Msk | CORDIC_COS_I_Msk);
}
/******************************************************************************************************************************************
* : CORDIC_Arctan()
* : 使CORDIC模块计算arctan
* : uint32_t input 0.05~1000016384
* :
* : 16384
******************************************************************************************************************************************/
static __INLINE void CORDIC_Arctan(uint32_t input)
{
if((input > 819) && (input <= 8192))
{
CORDIC->INPUT = input * 2;
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (0 << CORDIC_CMD_RANGE_Pos);
}
else if((input > 8192) && (input <= 32768))
{
CORDIC->INPUT = input;
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (1 << CORDIC_CMD_RANGE_Pos);
}
else if((input > 32768) && (input < 10000*16384))
{
CORDIC->INPUT = 32768*16384/input;
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (2 << CORDIC_CMD_RANGE_Pos);
}
}
/******************************************************************************************************************************************
* : CORDIC_Arctan_IsDone()
* : CORDIC模块arctan运算是否完成
* :
* : uint32_t 0 arctan运算未完成 1 arctan运算已完成
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Arctan_IsDone(void)
{
return (CORDIC->ARCTAN & CORDIC_ARCTAN_DONE_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CORDIC_Arctan_Result()
* : CORDIC模块arctan运算结果
* :
* : uint32_t arctan运算结果Result[15:14]Result[13:0]
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Arctan_Result(void)
{
return CORDIC->ARCTAN & (CORDIC_ARCTAN_F_Msk | CORDIC_ARCTAN_I_Msk);
}
/******************************************************************************************************************************************
* : CORDIC_Mul()
* : 使CORDIC模块计算乘法
* : uint16_t mul1 1
* uint16_t mul2 2
* :
* : 16384
******************************************************************************************************************************************/
static __INLINE void CORDIC_Mul(uint16_t mul1, uint16_t mul2)
{
CORDIC->INPUT = mul1 | (mul2 << 16);
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (3 << CORDIC_CMD_MULDIV_Pos);
}
/******************************************************************************************************************************************
* : CORDIC_Mul_IsDone()
* : CORDIC模块乘法运算是否完成
* :
* : uint32_t 0 1
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Mul_IsDone(void)
{
return (CORDIC->SIN & CORDIC_SIN_DONE_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CORDIC_Mul_Result()
* : CORDIC模块乘法运算结果
* :
* : uint32_t Result[15:14]Result[13:0]
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Mul_Result(void)
{
return CORDIC->SIN & (CORDIC_SIN_F_Msk | CORDIC_SIN_I_Msk);
}
/******************************************************************************************************************************************
* : CORDIC_Div()
* : 使CORDIC模块计算除法
* : uint16_t dividend
* uint16_t divisor
* :
* : 16384
******************************************************************************************************************************************/
static __INLINE void CORDIC_Div(uint16_t dividend, uint16_t divisor)
{
CORDIC->INPUT = divisor | (dividend << 16);
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (2 << CORDIC_CMD_MULDIV_Pos);
}
/******************************************************************************************************************************************
* : CORDIC_Div_IsDone()
* : CORDIC模块除法运算是否完成
* :
* : uint32_t 0 1
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Div_IsDone(void)
{
return (CORDIC->ARCTAN & CORDIC_ARCTAN_DONE_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : CORDIC_Div_Result()
* : CORDIC模块除法运算结果
* :
* : uint32_t Result[15:14]Result[13:0]
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CORDIC_Div_Result(void)
{
return CORDIC->ARCTAN & (CORDIC_ARCTAN_F_Msk | CORDIC_ARCTAN_I_Msk);
}
#endif //__SWM341_CORDIC_H__

View File

@ -0,0 +1,67 @@
/******************************************************************************************************************************************
* : SWM341_crc.c
* : SWM341单片机的CRC模块驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.1.0 20171025
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_crc.h"
/******************************************************************************************************************************************
* : CRC_Init()
* : CRC
* : CRC_TypeDef * CRCx CRC接口CRC
* CRC_InitStructure * initStruct CRC相关设定值的结构体
* :
* :
******************************************************************************************************************************************/
void CRC_Init(CRC_TypeDef * CRCx, CRC_InitStructure * initStruct)
{
switch((uint32_t)CRCx)
{
case ((uint32_t)CRC):
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CRC_Pos);
break;
}
CRCx->INIVAL = initStruct->init_crc;
CRCx->CR = (1 << CRC_CR_EN_Pos) |
(initStruct->Poly << CRC_CR_POLY_Pos) |
(initStruct->in_width << CRC_CR_IBIT_Pos) |
(initStruct->in_rev << CRC_CR_IREV_Pos) |
(initStruct->in_not << CRC_CR_INOT_Pos) |
(initStruct->out_rev << CRC_CR_OREV_Pos) |
(initStruct->out_not << CRC_CR_ONOT_Pos);
}
/******************************************************************************************************************************************
* : CRC_SetInitVal()
* : CRC计算初始值
* : CRC_TypeDef * CRCx CRC接口CRC
* uint32_t init_crc CRC计算初始值
* :
* :
******************************************************************************************************************************************/
void CRC_SetInitVal(CRC_TypeDef * CRCx, uint32_t init_crc)
{
CRCx->INIVAL = init_crc;
CRCx->CR |= (1 << CRC_CR_EN_Pos);
}

View File

@ -0,0 +1,59 @@
#ifndef __SWM341_CRC_H__
#define __SWM341_CRC_H__
typedef struct {
uint32_t init_crc; // 初始值
uint8_t Poly; // CRC多项式可取值CRC_POLY_11021、CRC_POLY_107、CRC_POLY_18005、CRC_POLY_104C11DB7
uint8_t in_width; // 输入数据宽度可取值CRC_WIDTH_32、CRC_WIDTH_16、CRC_WIDTH_8
uint8_t in_rev; // 输入数据翻转可取值CRC_REV_NOT、CRC_REV_ALL、CRC_REV_IN_BYTE、CRC_REV_BYTE
bool in_not; // 输入数据取反
uint8_t out_rev; // 输出结果翻转可取值CRC_REV_NOT、CRC_REV_ALL、CRC_REV_IN_BYTE、CRC_REV_BYTE
bool out_not; // 输出结果取反
} CRC_InitStructure;
#define CRC_POLY_11021 0 // x^16+x^12+x^5+1
#define CRC_POLY_107 1 // x^8+x^2+x+1
#define CRC_POLY_18005 2 // x^16+x^15+x^2+1
#define CRC_POLY_104C11DB7 3 // x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
#define CRC_WIDTH_32 0
#define CRC_WIDTH_16 1
#define CRC_WIDTH_8 2
#define CRC_REV_NOT 0 // bit顺序不变
#define CRC_REV_ALL 1 // bit顺序完全翻转
#define CRC_REV_IN_BYTE 2 // bit顺序字节内翻转
#define CRC_REV_BYTE 3 // 仅字节顺序翻转
void CRC_Init(CRC_TypeDef * CRCx, CRC_InitStructure * initStruct);
void CRC_SetInitVal(CRC_TypeDef * CRCx, uint32_t init_crc);
/******************************************************************************************************************************************
* : CRC_Write()
* : CRC写入数据
* : uint32_t data
* :
* :
******************************************************************************************************************************************/
static __INLINE void CRC_Write(uint32_t data)
{
CRC->DATAIN = data;
}
/******************************************************************************************************************************************
* : CRC_Result()
* : CRC计算结果
* :
* : uint32_t CRC
* :
******************************************************************************************************************************************/
static __INLINE uint32_t CRC_Result(void)
{
return CRC->RESULT;
}
#endif //__SWM341_CRC_H__

View File

@ -0,0 +1,67 @@
/******************************************************************************************************************************************
* : SWM341_dac.c
* : SWM341单片机的DAC模块驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.1.0 20171025
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_dac.h"
/******************************************************************************************************************************************
* : DAC_Init()
* : DAC
* : DAC_TypeDef * DACx DAC接口DAC
* uint32_t format DAC_FORMAT_LSB12BDAC_FORMAT_MSB12BDAC_FORMAT_8B
* :
* :
******************************************************************************************************************************************/
void DAC_Init(DAC_TypeDef * DACx, uint32_t format)
{
switch((uint32_t)DACx)
{
case ((uint32_t)DAC):
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_DAC_Pos);
break;
}
DACx->CR = (format << DAC_CR_DHRFMT_Pos);
}
/******************************************************************************************************************************************
* : DAC_Open()
* : DAC
* : DAC_TypeDef * DACx DAC接口DAC
* :
* :
******************************************************************************************************************************************/
void DAC_Open(DAC_TypeDef * DACx)
{
DACx->CR |= (1 << ADC_CR_EN_Pos);
}
/******************************************************************************************************************************************
* : DAC_Init()
* : DAC
* : DAC_TypeDef * DACx DAC接口DAC
* :
* :
******************************************************************************************************************************************/
void DAC_Close(DAC_TypeDef * DACx)
{
DACx->CR &= ~DAC_CR_EN_Msk;
}

View File

@ -0,0 +1,15 @@
#ifndef __SWM341_DAC_H__
#define __SWM341_DAC_H__
#define DAC_FORMAT_LSB12B 0 //12位数据DHR[11:0] => DOR[11:0]
#define DAC_FORMAT_MSB12B 1 //12位数据DHR[15:4] => DOR[11:0]
#define DAC_FORMAT_8B 3 // 8位数据DHR[7 :0] => DOR[11:4]
void DAC_Init(DAC_TypeDef * DACx, uint32_t format);
void DAC_Open(DAC_TypeDef * DACx);
void DAC_Close(DAC_TypeDef * DACx);
#endif //__SWM341_DAC_H__

View File

@ -0,0 +1,40 @@
/******************************************************************************************************************************************
* : SWM341_div.c
* : SWM341单片机的DIV硬件除法功能驱动库
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.0.0 2016130
* :
*
*
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_div.h"
/******************************************************************************************************************************************
* : DIV_Init()
* :
* : DIV_TypeDef * DIVx DIV
* :
* :
******************************************************************************************************************************************/
void DIV_Init(DIV_TypeDef * DIVx)
{
switch((uint32_t)DIVx)
{
case ((uint32_t)DIV):
SYS->CLKEN0 |= (0x01u<< SYS_CLKEN0_DIV_Pos);
break;
}
}

View File

@ -0,0 +1,129 @@
#ifndef __SWM341_DIV_H__
#define __SWM341_DIV_H__
void DIV_Init(DIV_TypeDef * DIVx);
/******************************************************************************************************************************************
* : DIV_UDiv()
* : 使
* : uint32_t dividend
* uint32_t divisor
* :
* :
******************************************************************************************************************************************/
static __INLINE void DIV_UDiv(uint32_t dividend, uint32_t divisor)
{
DIV->DIVIDEND = dividend;
DIV->DIVISOR = divisor;
DIV->CR = (1 << DIV_CR_DIVSIGN_Pos) | (1 << DIV_CR_DIVGO_Pos);
}
/******************************************************************************************************************************************
* : DIV_SDiv()
* : 使
* : int32_t dividend
* int32_t divisor
* :
* :
******************************************************************************************************************************************/
static __INLINE void DIV_SDiv(int32_t dividend, int32_t divisor)
{
DIV->DIVIDEND = dividend;
DIV->DIVISOR = divisor;
DIV->CR = (0 << DIV_CR_DIVSIGN_Pos) | (1 << DIV_CR_DIVGO_Pos);
}
/******************************************************************************************************************************************
* : DIV_Div_IsBusy()
* :
* :
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
static __INLINE uint32_t DIV_Div_IsBusy(void)
{
return (DIV->SR & DIV_SR_DIVBUSY_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : DIV_UDiv_Result()
* :
* :
* : uint32_t *quotient
* uint32_t *remainder
* :
******************************************************************************************************************************************/
static __INLINE void DIV_UDiv_Result(uint32_t *quotient, uint32_t *remainder)
{
*quotient = DIV->QUO;
*remainder = DIV->REMAIN;
}
/******************************************************************************************************************************************
* : DIV_SDiv_Result()
* :
* :
* : int32_t *quotient
* int32_t *remainder
* :
******************************************************************************************************************************************/
static __INLINE void DIV_SDiv_Result(int32_t *quotient, int32_t *remainder)
{
*quotient = DIV->QUO & 0x7FFFFFFF;
if(DIV->QUO & (1u << 31)) *quotient = 0 - *quotient;
*remainder = DIV->REMAIN & 0x7FFFFFFF;
if(DIV->REMAIN & (1u << 31)) *remainder = 0 - *remainder;
}
/******************************************************************************************************************************************
* : DIV_Root()
* : 使
* : uint32_t radicand
* uint32_t calcu_frac 0 16 1 16+16
* :
* :
******************************************************************************************************************************************/
static __INLINE void DIV_Root(uint32_t radicand, uint32_t calcu_fractional)
{
DIV->RADICAND = radicand;
DIV->CR = (1 << DIV_CR_ROOTGO_Pos) | (calcu_fractional << DIV_CR_ROOTMOD_Pos);
}
/******************************************************************************************************************************************
* : DIV_Root_IsBusy()
* :
* :
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
static __INLINE uint32_t DIV_Root_IsBusy(void)
{
return (DIV->SR & DIV_SR_ROOTBUSY_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : DIV_Root_Result()
* :
* :
* : uint32_t
* :
******************************************************************************************************************************************/
static __INLINE uint32_t DIV_Root_Result(void)
{
if(DIV->CR & DIV_CR_ROOTMOD_Msk)
{
return DIV->ROOT;
}
else
{
return DIV->ROOT >> 16;
}
}
#endif //__SWM341_DIV_H__

Some files were not shown because too many files have changed in this diff Show More