diff --git a/boards/elan/32f967_dv/32f967_dv.dts b/boards/elan/32f967_dv/32f967_dv.dts new file mode 100644 index 0000000000000..6d20e0557e308 --- /dev/null +++ b/boards/elan/32f967_dv/32f967_dv.dts @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2024 ELAN Microelectronics Corp. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include + +/ { + model = "ELAN EM32F967 Development Board"; + compatible = "elan,em32f967_dv"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash-controller = &em32_flash_controller; + zephyr,flash = &flash0; + zephyr,spi2 = &spi2; + zephyr,udc0 = &usbd; + zephyr,entropy = &trng0; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>; + label = "User LED 0 (PB14)"; + }; + + led1: led_1 { + gpios = <&gpiob 15 GPIO_ACTIVE_HIGH>; + label = "User LED 1 (PB15)"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioa 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "User Button 0 (PA6)"; + }; + + button1: button_1 { + gpios = <&gpiob 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "User Button 1 (PB11)"; + }; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + spi2 = &spi2; + watchdog0 = &wdt0; + }; +}; + +&clk_ahb { + status = "okay"; +}; + +&clk_apb { + clocks = <&clk_ahb>; + status = "okay"; +}; + +&sram0 { + reg = <0x20000000 0x28000>; +}; + +#if 0 +&uart1 { + pinctrl-0 = <&uart1_rx_pa1 &uart1_tx_pa2>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_cs_pb0 &spi1_sck_pb1 &spi1_miso_pb2 &spi1_mosi_pb3>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; +}; + +#endif + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_sck_pb5 &spi2_miso_pb6 &spi2_mosi_pb7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 4 GPIO_ACTIVE_LOW>; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_rx_pa1 &uart1_tx_pa2>; + pinctrl-names = "default"; +}; + +&em32_flash_controller { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + + #address-cells = <1>; + #size-cells = <1>; + + wp_ro: partition@0 { + label = "wp-ro"; + reg = <0x0 DT_SIZE_K(128)>; + read-only; + }; + + rollback_0: partition@10020000 { + label = "rollback-0"; + reg = <0x10020000 DT_SIZE_K(8)>; + }; + + rollback_1: partition@10022000 { + label = "rollback-1"; + reg = <0x10022000 DT_SIZE_K(8)>; + }; + + ec_rw: partition@10024000 { + label = "ec-rw"; + reg = <0x10024000 DT_SIZE_K(392)>; + }; + }; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&uid { + status = "okay"; +}; + +&bbram0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&crypto0 { + status = "okay"; +}; diff --git a/boards/elan/32f967_dv/32f967_dv.yaml b/boards/elan/32f967_dv/32f967_dv.yaml new file mode 100644 index 0000000000000..52422be57e3f7 --- /dev/null +++ b/boards/elan/32f967_dv/32f967_dv.yaml @@ -0,0 +1,11 @@ +identifier: 32f967_dv +name: ELAN EM32F967 dv Board +vendor: elan +type: mcu +arch: arm +toolchain: + - zephyr +supported: + - serial +ram: 272 +flash: 592 diff --git a/boards/elan/32f967_dv/32f967_dv_defconfig b/boards/elan/32f967_dv/32f967_dv_defconfig new file mode 100644 index 0000000000000..a6fa5436b0ef9 --- /dev/null +++ b/boards/elan/32f967_dv/32f967_dv_defconfig @@ -0,0 +1,16 @@ +CONFIG_PINCTRL=y +CONFIG_FLASH=y +CONFIG_FLASH_EM32=y +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_ELAN_ELANDEV=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 +CONFIG_SOC_PREP_HOOK=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_CONTROL_EM32_AHB=y +CONFIG_CLOCK_CONTROL_EM32_APB=y +CONFIG_UDC_DRIVER=y +CONFIG_DYNAMIC_INTERRUPTS=y diff --git a/boards/elan/32f967_dv/Kconfig b/boards/elan/32f967_dv/Kconfig new file mode 100644 index 0000000000000..79dfea0c644b9 --- /dev/null +++ b/boards/elan/32f967_dv/Kconfig @@ -0,0 +1,27 @@ +menu "Zephyr" + +config MAIN_STACK_SIZE + int "MAIN_STACK_SIZE" + default 4096 + +config ISR_STACK_SIZE + int "ISR_STACK_SIZE" + default 4096 + +config IDLE_STACK_SIZE + int "IDLE_STACK_SIZE" + default 1024 + +config UART_USE_RUNTIME_CONFIGURE + bool "UART_USE_RUNTIME_CONFIGURE" + default n + +config UART_INTERRUPT_DRIVEN + bool "UART_INTERRUPT_DRIVEN" + default n + +config UART_ASYNC_API + bool "UART_ASYNC_API" + default n + +endmenu diff --git a/boards/elan/32f967_dv/Kconfig.32f967_dv b/boards/elan/32f967_dv/Kconfig.32f967_dv new file mode 100644 index 0000000000000..1a0c5199556ab --- /dev/null +++ b/boards/elan/32f967_dv/Kconfig.32f967_dv @@ -0,0 +1,6 @@ +# Copyright (c) 2019-2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_32F967_DV + select SOC_EM32F967 diff --git a/boards/elan/32f967_dv/board.cmake b/boards/elan/32f967_dv/board.cmake new file mode 100644 index 0000000000000..6b01bab2aeea8 --- /dev/null +++ b/boards/elan/32f967_dv/board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(misc-flasher) +board_finalize_runner_args(misc-flasher) diff --git a/boards/elan/32f967_dv/board.yml b/boards/elan/32f967_dv/board.yml new file mode 100644 index 0000000000000..e84acdd440fa1 --- /dev/null +++ b/boards/elan/32f967_dv/board.yml @@ -0,0 +1,6 @@ +board: + name: 32f967_dv + full_name: ELAN EM32F967 + vendor: ELAN + socs: + - name: em32f967 diff --git a/dts/arm/elan/em32fxxx.dtsi b/dts/arm/elan/em32fxxx.dtsi new file mode 100644 index 0000000000000..72f8170ce2523 --- /dev/null +++ b/dts/arm/elan/em32fxxx.dtsi @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2024 ELAN Microelectronics Corp. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(448)>; + }; + + clocks { + #size-cells = <0>; + + clk_ahb: clk-ahb { + compatible = "elan,em32-ahb"; + #clock-cells = <0>; + clock-source = ; + clock-frequency = ; + clock-divider = ; + status = "disabled"; + }; + + clk_apb: clk-apb { + compatible = "elan,em32-apb"; + #clock-cells = <0>; + clocks = <&clk_ahb>; + status = "disabled"; + }; + }; + + soc { + /* Pin Controller */ + pinctrl: pin-controller@40030200 { + compatible = "elan,em32-pinctrl"; + reg = <0x40030200 0x100>; + reg-names = "iomux"; + #address-cells = <1>; + #size-cells = <1>; + #pinctrl-cells = <1>; + status = "okay"; + + + /* GPIO Controllers - EM32F967 hardware */ + gpioa: gpio@40020000 { + compatible = "elan,em32-gpio"; + reg = <0x40020000 0x1000>; + port-id = <0>; + interrupts = <0 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + clocks = <&clk_ahb>; + status = "disabled"; + }; + + gpiob: gpio@40021000 { + compatible = "elan,em32-gpio"; + reg = <0x40021000 0x1000>; + port-id = <1>; + interrupts = <1 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + clocks = <&clk_ahb>; + status = "disabled"; + }; + + uart0: serial@40002000 { + compatible = "elan,elandev-uart"; + reg = <0x40002000 0x4c>; + clocks = <&clk_apb>; + status = "disabled"; + }; + + spi2: spi@40013000 { + compatible = "elan,elandev-spi2"; + reg = <0x40013000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <25 0>; + clocks = <&clk_apb>; + status = "disabled"; + }; + }; + + em32_flash_controller: flash-controller@40034000 { + compatible = "elan,em32-flash-controller"; + reg = <0x40034000 DT_SIZE_K(4)>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@10000000 { + compatible = "soc-nv-flash"; + reg = <0x10000000 DT_SIZE_K(536)>; + erase-block-size = ; + write-block-size = <16>; + }; + + flash1: flash@10094000 { + compatible = "mcuboot"; + reg = <0x10094000 DT_SIZE_K(48)>; + }; + }; + + usbd: usbd@40038000 { + compatible = "elan,elandev-usbd"; + reg = <0x40038000 0x1000>; + num-bidir-endpoints = <5>; + }; + + uid: device_uid@40030f00 { + compatible = "elan,em32-uid"; + reg = <0x40030f00 0x4 /* Chip ID */ + 0x100A6020 0x4 /* Device ID */ + 0x100A6024 0x4 /* IC Version */>; + reg-names = "chip_id", "device_id", "ic_version"; + status = "disabled"; + }; + bbram0: bbram@40033000 { + compatible = "elan,em32-bbram"; + reg = <0x40033000 0x40>; + backup-regs-count = <16>; + status = "disabled"; + }; + trng0: trng@40018000 { + compatible = "elan,em32-trng"; + reg = <0x40018000 0x100>; + interrupts = <41 0>; + clocks = <&clk_apb>; + status = "disabled"; + }; + wdt0: watchdog@40035000 { + compatible = "elan,em32-wdt"; + reg = <0x40035000 0x1000>; + interrupts = <2 0>; + clocks = <&clk_apb>; + status = "disabled"; + }; + + crypto0: crypto@40016000 { + compatible = "elan,em32-crypto"; + reg = <0x40016000 0x1000>; + interrupts = <40 0>; + clocks = <&clk_apb>; + status = "disabled"; + }; + + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/soc/elan/em32f967/CMakeLists.txt b/soc/elan/em32f967/CMakeLists.txt new file mode 100644 index 0000000000000..b256f99dcd23d --- /dev/null +++ b/soc/elan/em32f967/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Elan Microelectronics Corp.. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/elan/em32f967/Kconfig b/soc/elan/em32f967/Kconfig new file mode 100644 index 0000000000000..fc58623dd8359 --- /dev/null +++ b/soc/elan/em32f967/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Elan Microelectronics Corps. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_EM32F967 + select ARM + select CPU_CORTEX_M4 + select CPU_HAS_ARM_MPU + diff --git a/soc/elan/em32f967/Kconfig.defconfig b/soc/elan/em32f967/Kconfig.defconfig new file mode 100644 index 0000000000000..da0644bb8e226 --- /dev/null +++ b/soc/elan/em32f967/Kconfig.defconfig @@ -0,0 +1,15 @@ +if SOC_EM32F967 + +config NUM_IRQS + default 64 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 60000000 + +config BUILD_OUTPUT_BIN + default y + +config BUILD_OUTPUT_HEX + default y + +endif # SOC_EM32F967 diff --git a/soc/elan/em32f967/Kconfig.soc b/soc/elan/em32f967/Kconfig.soc new file mode 100644 index 0000000000000..e31f4eb8f79f9 --- /dev/null +++ b/soc/elan/em32f967/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Elan Microelectronics Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_EM32F967 + bool + help + ELAN EM32F967 + +config SOC + default "em32f967" if SOC_EM32F967 diff --git a/soc/elan/em32f967/elan_em32.h b/soc/elan/em32f967/elan_em32.h new file mode 100644 index 0000000000000..9900501268bb7 --- /dev/null +++ b/soc/elan/em32f967/elan_em32.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ZEPHYR_SOC_ELAN_EM32F967_ELAN_EM32_H__ +#define __ZEPHYR_SOC_ELAN_EM32F967_ELAN_EM32_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Enumeration + */ + +typedef enum { + HCLKG_DMA = 0x00, + HCLKG_GPIOA = 0x01, + HCLKG_GPIOB = 0x02, + PCLKG_LPC = 0x03, + HCLKG_7816_1 = 0x04, + HCLKG_7816_2 = 0x05, + HCLKG_ENCRYPT = 0x06, + PCLKG_USART = 0x07, + PCLKG_TMR1 = 0x08, + PCLKG_TMR2 = 0x09, + PCLKG_TMR3 = 0x0a, + PCLKG_TMR4 = 0x0b, + PCLKG_UART1 = 0x0c, + PCLKG_UART2 = 0x0d, + PCLKG_RVD1 = 0x0e, + HCLKG_ESPI1 = 0x0f, + PCLKG_SSP2 = 0x10, + PCLKG_I2C1 = 0x11, + PCLKG_I2C2 = 0x12, + PCLKG_PWM = 0x13, + PCLKG_RVD2 = 0x14, + PCLKG_UDC = 0x15, + PCLKG_ATRIM = 0x16, + PCLKG_RTC = 0x17, + PCLKG_BKP = 0x18, + PCLKG_DWG = 0x19, + PCLKG_PWR = 0x1a, + PCLKG_CACHE = 0x1b, + PCLKG_AIP = 0x1c, + PCLKG_ECC = 0x1d, + PCLKG_TRNG = 0x1e, + HCLKG_EXTSPI = 0x1f, + HCLKG_GHM_ACC1 = 0x20, + HCLKG_GHM_ACC2 = 0x21, + HCLKG_GHM_ACC3 = 0x22, + HCLKF_GHM_IP = 0x23, + HCLKF_FLASH_BIST = 0x24, + HCLKF_GHM_RANSAC = 0x25, + HCLKF_SWSPI = 0x26, + HCLKF_GHM_DOUBLE = 0x27, + HCLKF_GHM_DISTINGUISH = 0x28, + HCLKF_GHM_LSE = 0x29, + HCLKF_GHM_SAD = 0x2a, + HCLKF_GHM_M2D = 0x2b, + PCLKG_SSP1 = 0x30, + PCLKG_ALL = 0xffff +} CLKGatingSwitch; + +/* + * Data Structure + */ + +typedef struct { + __IO uint32_t MIRCPD: 1; + __IO uint32_t HIRC_TESTV: 1; + __IO uint32_t MIRCRCM: 3; + __IO uint32_t MIRCCA: 6; + __IO uint32_t MIRCTBG: 2; + __IO uint32_t MIRCTCF: 2; + __IO uint32_t MIRCTV12: 3; + __IO uint32_t Reserved1: 14; +} MIRC_Type; + +typedef struct { + __IO uint32_t MIRCPD: 1; + __IO uint32_t HIRC_TESTV: 1; + __IO uint32_t MIRCRCM: 3; + __IO uint32_t MIRCTall: 10; + __IO uint32_t MIRCTV12: 3; + __IO uint32_t Reserved1: 14; +} MIRC_Type2; + +typedef struct { + __IO uint32_t WaitCount: 3; + __IO uint32_t WaitCountSet: 1; + __IO uint32_t WaitCountPass: 4; + __IO uint32_t Reserved: 18; + __IO uint32_t Remap_SYSR_Boot: 1; + __IO uint32_t Remap_IDR_Boot: 1; + __IO uint32_t Gating_CPU_CLK: 1; + __IO uint32_t Remap_Switch: 1; + __IO uint32_t CPUReady_SkipArbiter: 1; + __IO uint32_t SWRESTEN: 1; +} MISCReg_Type; + +typedef struct { + __IO uint32_t XTALHIRCSEL: 1; // [0] + __IO uint32_t XTALLJIRCSEL: 1; // [1] + __IO uint32_t HCLKSEL: 2; // [3:2] + __IO uint32_t USBCLKSEL: 1; // [4] + __IO uint32_t HCLKDIV: 3; // [7:5] + __IO uint32_t QSPICLK_SEL: 1; // [8] + __IO uint32_t ACC1CLK_SEL: 1; // [9] + __IO uint32_t ENCRYPT_SEL: 1; // [10] + __IO uint32_t Timer1_SEL: 1; // [11] + __IO uint32_t Timer2_SEL: 1; // [12] + __IO uint32_t Timer3_SEL: 1; // [13] + __IO uint32_t Timer4_SEL: 1; // [14] + __IO uint32_t QSPICLK_DIV: 1; // [15] + __IO uint32_t ACC1CLK_DIV: 1; // [16] + __IO uint32_t EncryptCLK_DIV: 1; // [17] + __IO uint32_t RTC_SEL: 1; // [18] + __IO uint32_t I2C1Reset_SEL: 1; // [19] + __IO uint32_t USBReset_SEL: 1; // [20] + __IO uint32_t HIRC_TESTV: 1; // [21] + __IO uint32_t SWRESTN: 1; // [22] + __IO uint32_t DEEPSLPCLKOFF: 1; // [23] + __IO uint32_t ClearECCKey: 1; // [24] + __IO uint32_t POWEN: 1; // [25] + __IO uint32_t RESETOP: 1; // [26] + __IO uint32_t PMUCTRL: 1; // [27] + __IO uint32_t REAMPMODE: 4; // [31:28] +} SysReg_Type; + +typedef struct { + __IO uint32_t SYSPLLPD: 1; + __IO uint32_t SYSPLLPSET: 2; + __IO uint32_t SYSPLLFSET: 4; + __I uint32_t SYSPLLSTABLECNT: 2; + __I uint32_t SYSPLLSTABLE: 1; + __IO uint32_t Reserved: 22; +} SYSPLL_Type; + +typedef struct { + __IO uint32_t PLLLDO_PD: 1; + __IO uint32_t PLLLDO_VP_SEL: 1; + __IO uint32_t PLLLDO_VS: 3; + __IO uint32_t PLLLDO_TV12: 4; + __IO uint32_t Reserved: 23; +} LDOPLL_Type; + +typedef struct { + __IO uint32_t LEVELRSTS: 1; + __IO uint32_t WDTRESETS: 1; + __IO uint32_t SWRESETS: 1; + __IO uint32_t SYSREQ_RST_STATUS: 1; + __IO uint32_t LOCKUP_RST_STATUS: 1; + __I uint32_t FLASHWCOUNTS: 3; + __IO uint32_t BORRESETS: 1; + __IO uint32_t LVDFlashRSTS: 1; + __IO uint32_t Reserved: 22; +} SysStatus_Type; + +typedef struct { + __IO uint32_t POWERSW: 3; + __IO uint32_t WARMUPCNT: 3; + __IO uint32_t PD_SW_ACK_EN: 1; + __IO uint32_t StandBy1_S: 1; + __IO uint32_t StandBy2_S: 1; + __IO uint32_t SIPPDEnable: 1; + __IO uint32_t LDOIdle: 1; + __IO uint32_t HIRCPD: 1; + __IO uint32_t SIRC32PD: 1; + __IO uint32_t BORPD: 1; + __IO uint32_t LDO2PD: 1; + __IO uint32_t RAMPDEnable: 1; + __IO uint32_t Reserved: 16; +} PowerSW_Type; + +// Flash Control Register +typedef struct +{ + + __IO uint32_t Reserved0 : 1; // [0] + __IO uint32_t Flash_Idle : 1; // [1] + __IO uint32_t Flash_BurstWrite : 1; // [2] + __IO uint32_t Flash_PageErase : 1; // [3] + __IO uint32_t Flash_Verify : 1; // [4] + __IO uint32_t Reserved1 : 2; // [6:5] + __IO uint32_t XYADDR : 9; // [15:7] 512 bytes address + //__IO uint32_t YADDR : 5; // [11:7] 32 * 128 bits buffer start addr + //__IO uint32_t XADDR0 : 4; // [15:12] 1 page = 8K = 16 * buffers' start + __IO uint32_t PageAddr : 7; // [22:16] total 86 pages + __IO uint32_t EraseEnable : 1; // [23] + __IO uint32_t BurstW_Length : 5; // [28:24] 32 (*128 bits ) + __IO uint32_t Reserved2 : 1; // [29] + __IO uint32_t FW_load : 1; // [30] + __IO uint32_t BurstW_Enable : 1; // [31] +} FLASHSR0_Type; + +/* + * Definition + */ + +#define CLKGATEREG (*(__IO uint32_t *)0x40030100) +#define CLKGATEREG2 (*(__IO uint32_t *)0x40030104) + +#define MIRCCTRL ((MIRC_Type *)0x40036000) +#define MIRCCTRL_2 ((MIRC_Type2 *)0x40036000) +#define MISCREGCTRL ((MISCReg_Type *)0x40030008) +#define SYSREGCTRL ((SysReg_Type *)0x40030000) +#define SYSPLLCTRL ((SYSPLL_Type *)0x40036404) +#define LDOPLL ((LDOPLL_Type *)0x4003630c) + +#define SYSSTATUSCTRL ((SysStatus_Type *)0x40030004) +#define POWERSWCTRL ((PowerSW_Type *)0x40031000) + +#define FLASHSR0_Ctrl ((FLASHSR0_Type *)0x40034010) +#define FLASH_SR0 (*( __IO uint32_t *)0x40034010) +#define FLASHKEY1 (*( __IO uint32_t *)0x40034000) +#define FLASHKEY2 (*( __IO uint32_t *)0x40034004) + +#ifdef __cplusplus +} +#endif + +#endif //__ZEPHYR_SOC_ELAN_EM32F967_ELAN_EM32_H__ diff --git a/soc/elan/em32f967/em32f967.h b/soc/elan/em32f967/em32f967.h new file mode 100644 index 0000000000000..352fef490dafb --- /dev/null +++ b/soc/elan/em32f967/em32f967.h @@ -0,0 +1,77 @@ +#ifndef _EM32F867_H +#define _EM32F867_H + +#define FLASH_BASE ((uint32_t)0x10000000) /*!< FLASH(up to 640K) base address in the alias region \ + */ +#define FLASHINFO_BASE \ + ((uint32_t)0x100A0000) /*!< Info area(32 KB) base address in the alias region */ +#define IDRAM_BASE ((uint32_t)0x20000000) /*!< IDRAM(64 KB) base address in the alias region */ +#define SRAM0_BASE ((uint32_t)0x20010000) /*!< SRAM0(176 KB) base address in the alias region */ +#define SRAM1_BASE ((uint32_t)0x2002C000) /*!< SRAM1(208 KB) base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ + +/* Legacy defines */ +#define SRAM_BASE IDRAM_BASE + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define APB3PERIPH_BASE (PERIPH_BASE + 0x00030000) + +/*!< APB1 peripherals */ +#define TIMER1_BASE (APB1PERIPH_BASE + 0x0000) +#define TIMER2_BASE (APB1PERIPH_BASE + 0x1000) +#define UART1_BASE (APB1PERIPH_BASE + 0x2000) +// #define SSP1_BASE (APB1PERIPH_BASE + 0x3000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x4000) +// #define USB_BASE (APB1PERIPH_BASE + 0x5000) +#define PWM_BASE (APB1PERIPH_BASE + 0x6000) +// #define UART3_BASE (APB1PERIPH_BASE + 0x7000) +// #define BLDC_BASE (APB1PERIPH_BASE + 0x8000) +// #define SPI1_BASE (APB1PERIPH_BASE + 0x9000) +#define ISO78161_BASE (APB1PERIPH_BASE + 0xA000) +#define SWSPI_BASE (APB1PERIPH_BASE + 0xB000) + +/*!< APB2 peripherals */ +#define TIMER3_BASE (APB2PERIPH_BASE + 0x0000) +#define TIMER4_BASE (APB2PERIPH_BASE + 0x1000) +#define UART2_BASE (APB2PERIPH_BASE + 0x2000) +#define SSP2_BASE (APB2PERIPH_BASE + 0x3000) +#define I2C2_BASE (APB2PERIPH_BASE + 0x4000) +// #define AES256_BASE (APB2PERIPH_BASE + 0x5000) +#define ENCRYPT_BASE (APB2PERIPH_BASE + 0x6000) +#define ECC256_BASE (APB2PERIPH_BASE + 0x7000) +#define TRNG_BASE (APB2PERIPH_BASE + 0x8000) +#define USART_BASE (APB2PERIPH_BASE + 0x9000) +#define ISO78162_BASE (APB2PERIPH_BASE + 0xA000) + +/*!< APB3 peripherals */ +#define SYSCFG_BASE (APB3PERIPH_BASE + 0x0000) +#define PWR_BASE (APB3PERIPH_BASE + 0x1000) +#define RTC_BASE (APB3PERIPH_BASE + 0x2000) +#define BACKUP_BASE (APB3PERIPH_BASE + 0x3000) +#define FLASHIFR_BASE (APB3PERIPH_BASE + 0x4000) +#define WDG_BASE (APB3PERIPH_BASE + 0x5000) +#define AIP_BASE (AHB3PERIPH_BASE + 0x6000) +#define CACHE_BASE (AHB3PERIPH_BASE + 0x7000) +#define USB_BASE (APB3PERIPH_BASE + 0x8000) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x1000) +#define DMA_BASE (AHB1PERIPH_BASE + 0x2000) +#define SYSCTRL_BASE (AHB1PERIPH_BASE + 0x3000) +#define QSPI_BASE (AHB1PERIPH_BASE + 0x4000) +#define SPI1_BASE (AHB1PERIPH_BASE + 0x7000) + +// WDT register +#define WDOGLOAD (*(__IO uint32_t *)0x40035000) +#define WDOGVALUE (*(__IO uint32_t *)0x40035004) +#define WDOGCONTROL (*(__IO uint32_t *)0x40035008) +#define WDOGINTCLR (*(__IO uint32_t *)0x4003500c) +#define WDOGRIS (*(__IO uint32_t *)0x40035010) +#define WDOGMIS (*(__IO uint32_t *)0x40035014) +#define WDOGLOCK (*(__IO uint32_t *)0x40035c00) + +#endif diff --git a/soc/elan/em32f967/soc.c b/soc/elan/em32f967/soc.c new file mode 100644 index 0000000000000..9afc9f7a128b2 --- /dev/null +++ b/soc/elan/em32f967/soc.c @@ -0,0 +1,428 @@ +#include "soc.h" + +#include +#include + +#define LOG_LEVEL LOG_LEVEL_DBG +#include +LOG_MODULE_REGISTER(elan_em32f967_soc); + +static void _z_nop_delay(uint32_t cnt) +{ + for (uint32_t i = 0; i < cnt; i++) { + __asm volatile("nop"); + } +} + +#if defined(CONFIG_SOC_PREP_HOOK) +void WatchDogEnable(WDTMode mode, uint32_t msec); +bool GPIO_ReadBit(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +// test PB8, if low, enter boot mode +void _test_boot_mode(void) +{ + bool bpb3; + int cnt, boot; + + // first, set PB3 INPUT, PULL HIGH + GPIO_SetInput(GPIOIPB, GPIO_PINSOURCE3, GPIO_PuPd_PullUp4_7K); + // wait to make sure PB3 is high + for (int i = 0; i < 50; i++) { + __asm volatile("nop"); + } + cnt = 0; + boot = 0; + do { + bpb3 = GPIO_ReadBit(GPIOIPB, GPIO_PIN_3); + if (!bpb3) { + bpb3 = false; + boot = 1; + break; + } + for (int i = 0; i < 50; i++) { + __asm volatile("nop"); + } + + cnt++; + } while (cnt < 10); + if (boot) { + CLKGatingDisable(PCLKG_BKP); + BACKUPREG0 = 0x56524553; + BACKUPREG1 = 0x00000000; + WatchDogEnable(WDTRESET, 10); + while (1) + ; //(WDT timeout reset ?boot ) + } + return; +} + +void soc_prep_hook(void) +{ + _test_boot_mode(); +} +#endif + +void GPIO_HighDrive_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOHDPACRTL |= GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOHDPBCRTL |= GPIOPin; + } +} + +void GPIO_HighDrive_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOHDPACRTL &= ~GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOHDPBCRTL &= ~GPIOPin; + } +} + +void GPIO_OpenDrain_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOODEPACTRL |= GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOODEPBCTRL |= GPIOPin; + } +} + +void GPIO_OpenDrain_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOODEPACTRL &= ~GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOODEPBCTRL &= ~GPIOPin; + } +} + +void GPIO_OpenSource_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOOSEPACTRL |= GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOOSEPBCTRL |= GPIOPin; + } +} + +void GPIO_OpenSource_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOOSEPACTRL &= ~GPIOPin; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOOSEPBCTRL &= ~GPIOPin; + } +} + +void GPIO_ToggleBits(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + + __disable_irq(); + if ((GPIOx->DATAOUT & GPIOPin) != (uint16_t)Bit_RESET) { + GPIOx->DATAOUT &= ~GPIOPin; + } else { + GPIOx->DATAOUT |= GPIOPin; + } + __enable_irq(); +} + +void GPIO_WriteBit(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin, BitAction BitVal) +{ + __disable_irq(); + if (BitVal != Bit_RESET) { + GPIOx->DATAOUT |= GPIOPin; + } else { + GPIOx->DATAOUT &= ~GPIOPin; + } + __enable_irq(); +} + +bool GPIO_ReadBit(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin) +{ + bool bitstatus; + + if ((GPIOx->DATA & GPIOPin) != (uint16_t)Bit_RESET) { + bitstatus = (bool)Bit_SET; + } else { + bitstatus = (bool)Bit_RESET; + } + return bitstatus; +} + +void GPIO_WritePort(GPIO_IPType *GPIOx, uint16_t PortVal) +{ + GPIOx->DATAOUT = PortVal; +} + +uint16_t GPIO_ReadPort(GPIO_IPType *GPIOx) +{ + return ((uint16_t)GPIOx->DATA); +} + +void GPIO_Init(GPIO_IPType *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct) +{ + uint32_t value_temp, value_mask; + + // pin_t = GPIO_InitStruct->GPIO_Pin; + + // set IO mux = 0x00 + if ((uint32_t)GPIOx == GPIOA_BASE) { + CLKGatingDisable(HCLKG_GPIOA); + if ((GPIO_InitStruct->GPIO_Pin == GPIO_PINSOURCE11) || + (GPIO_InitStruct->GPIO_Pin == GPIO_PINSOURCE12)) { + GPIOMUXSet(PORTA, GPIO_InitStruct->GPIO_Pin, GPIO_MUX01); + } else { + GPIOMUXSet(PORTA, GPIO_InitStruct->GPIO_Pin, GPIO_MUX00); + } + GPIOMUXSet(PORTANALOG, GPIO_InitStruct->GPIO_Pin, GPIO_MUX00); + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + CLKGatingDisable(HCLKG_GPIOB); + GPIOMUXSet(PORTB, GPIO_InitStruct->GPIO_Pin, GPIO_MUX00); + } + + // set IO mode + + value_mask = 0x01 << GPIO_InitStruct->GPIO_Pin; + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IN) { + GPIOx->DATAOUTCLR = value_mask; + } else { + GPIOx->DATAOUTSET = value_mask; + } + + // set IO PUPD + value_temp = (GPIO_InitStruct->GPIO_PuPd) << (GPIO_InitStruct->GPIO_Pin * 2); + value_mask = 0x03 << (GPIO_InitStruct->GPIO_Pin * 2); + if ((uint32_t)GPIOx == GPIOA_BASE) { + IOPUPDPACTRL = (IOPUPDPACTRL & ~value_mask) | value_temp; + } else if ((uint32_t)GPIOx == GPIOB_BASE) { + IOPUPDPBCTRL = (IOPUPDPBCTRL & ~value_mask) | value_temp; + } +} + +// PBx IO mux Swtich 3bits : 000~111 +// PB0[2:0],PB1[6:4],PB2[10:8],PB3[14:12],PB4[18:16],PB5[22:20],PB6[26:24],PB7[30:28] +// PBx IO mux Swtich 3bits : 000~111 +// PB8[2:0],PB9[6:4],PB10[10:8],PB11[14:12],PB12[18:16],PB13[22:20],PB14[26:24],PB15[30:28] + +void GPIOMUXSet(GPIOPortDef GPIOx, GPIOPinNameDef GPIOPin, GPIOMUXDef MUXNum) +{ + uint32_t MUXValue, MUXShift, GPIOPinR; + + MUXShift = 0x07; + MUXValue = MUXNum; + if (GPIOPin < 8) { + GPIOPinR = GPIOPin; + } else { + GPIOPinR = GPIOPin - 8; + } + + MUXValue <<= (GPIOPinR * 4); + MUXShift <<= (GPIOPinR * 4); + if (GPIOx == PORTA) { + if (GPIOPin < 8) { + IOMUXPACTRL = (IOMUXPACTRL & ~MUXShift) | MUXValue; + } else { + IOMUXPACTRL2 = (IOMUXPACTRL2 & ~MUXShift) | MUXValue; + } + } else if (GPIOx == PORTB) { + if (GPIOPin < 8) { + IOMUXPBCTRL = (IOMUXPBCTRL & ~MUXShift) | MUXValue; + } else { + IOMUXPBCTRL2 = (IOMUXPBCTRL2 & ~MUXShift) | MUXValue; + } + } else if (GPIOx == PORTANALOG) { + MUXShift = 0x03; + MUXValue = MUXNum; + MUXValue <<= (GPIOPin * 2); + MUXShift <<= (GPIOPin * 2); + IOANAENCTRL = (IOANAENCTRL & ~MUXShift) | MUXValue; + } +} + +void GPIO_SetOuput2(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = GPIOPin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_Floating; + + GPIO_Init(GPIOx, &GPIO_InitStructure); +} + +void GPIO_SetOutput(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin, GPIOPuPdDef GPIOAttr) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = GPIOPin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_PuPd = GPIOAttr; + + GPIO_Init(GPIOx, &GPIO_InitStructure); +} + +void GPIO_SetInput(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin, GPIOPuPdDef GPIOAttr) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = GPIOPin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIOAttr; + + GPIO_Init(GPIOx, &GPIO_InitStructure); +} + +void GPIO_SetInputFloat(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = GPIOPin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_Floating; + + GPIO_Init(GPIOx, &GPIO_InitStructure); +} + +void GPIO_SetInputPullDown(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = GPIOPin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_Pulldown15K; + + GPIO_Init(GPIOx, &GPIO_InitStructure); +} + +void GPIO_SetPB8Toggle(uint32_t us_31_25) +{ + PB8CLOCKRATE = us_31_25; + PDGPIOCTRL |= 0x04; // PB8 CLK OUT enable +} + +void GPIO_SetPB9Toggle(uint32_t us_31_25) +{ + PB9CLOCKRATE = us_31_25; + PDGPIOCTRL |= 0x08; // PB9 CLK OUT enable +} + +void GPIO_StopPB8Toggle(void) +{ + PDGPIOCTRL &= 0xfffffffb; // PB8 CLK OUT disable +} + +void GPIO_StopPB9Toggle(void) +{ + PDGPIOCTRL &= 0xfffffff7; // PB9 CLK OUT disable +} + +void GPIO_PD_SetOuput(GPIOPortDef Portx, GPIOPinBitDef GPIOPin, BitAction BitVal) +{ + if (Portx == PORTA) { + PDPAOE |= GPIOPin; + if (BitVal != Bit_RESET) { + PDPAOUT |= GPIOPin; + } else { + PDPAOUT &= ~GPIOPin; + } + PDGPIOCTRL |= 0x01; // PA pd enable + } else { + PDPBOE |= GPIOPin; + if (BitVal != Bit_RESET) { + PDPBOUT |= GPIOPin; + } else { + PDPBOUT &= ~GPIOPin; + } + PDGPIOCTRL |= 0x02; // PB pd enable + } +} + +void GPIO_PD_SetInput(GPIOPortDef Portx, GPIOPinBitDef GPIOPin) +{ + if (Portx == PORTA) { + PDPAOE &= ~GPIOPin; + PDGPIOCTRL |= 0x01; // PA pd enable + } else { + PDPBOE &= ~GPIOPin; + PDGPIOCTRL |= 0x02; // PB pd enable + } +} + +void GPIO_PD_Disable(GPIOPortDef Portx) +{ + if (Portx == PORTA) { + PDGPIOCTRL &= ~0x01; // PA pd disable + } else if (Portx == PORTB) { + PDGPIOCTRL &= ~0x02; // PB pd disable + } +} + +void CLKGatingEnable(CLKGatingSwitch GatingN) +{ + if (GatingN == PCLKG_ALL) { + CACHECTRL = 0x00; // disable cache + CLKGATEREG = 0xffffffff; + CLKGATEREG2 = 0xffffffff; + } else if (GatingN <= 31) { + CLKGATEREG |= 0x01 << GatingN; + } else { + CLKGATEREG2 |= 0x01 << GatingN; + } +} + +void CLKGatingDisable(CLKGatingSwitch GatingN) +{ + if (GatingN == PCLKG_ALL) { + CLKGATEREG = 0; + CLKGATEREG2 = 0; + } else if (GatingN <= 31) { + CLKGATEREG &= ~(0x01 << GatingN); + } else { + CLKGATEREG2 &= ~(0x01 << (GatingN - 32)); + } +} + +bool IsCLKGating(CLKGatingSwitch GatingN) +{ + if (GatingN <= 31) { + if (CLKGATEREG & (0x01 << GatingN)) { + return 1; + } else { + return 0; + } + } else if (CLKGATEREG2 & (0x01 << (GatingN - 32))) { + return 1; + } else { + return 0; + } +} + +void WatchDogEnable(WDTMode mode, uint32_t msec) +{ + CLKGatingDisable(PCLKG_DWG); + WDOGLOCK = 0x1acce551; + WDOGLOAD = 32 * msec; // use 32K CLK + if (mode) { + WDOGCONTROL = 0x03; // enable reset + } else { + WDOGCONTROL = 0x01; // just enable int + } + WDOGLOCK = 0; +} + +void SetCLKOut(int8_t ClkS, int8_t SourceSel, int16_t DIV) +{ + if (ClkS) { + TOPTEST->CLKOUT1DIV = DIV; + TOPTEST->CLKOUT1SEL = SourceSel; + GPIO_SetOuput2(GPIOIPA, GPIO_PINSOURCE15); + GPIOMUXSet(PORTA, GPIO_PINSOURCE15, GPIO_MUX07); + } else { + TOPTEST->CLKOUT0DIV = DIV; + TOPTEST->CLKOUT0SEL = SourceSel; + GPIO_SetOuput2(GPIOIPA, GPIO_PINSOURCE14); + GPIOMUXSet(PORTA, GPIO_PINSOURCE14, GPIO_MUX07); + } + _z_nop_delay(1); +} diff --git a/soc/elan/em32f967/soc.h b/soc/elan/em32f967/soc.h new file mode 100644 index 0000000000000..de6862788df37 --- /dev/null +++ b/soc/elan/em32f967/soc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Elan Microelectronics Corp.. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _EM32F967_SOC_H_ +#define _EM32F967_SOC_H_ + +#include +#include +#include + +#include "em32f967.h" +#include "soc_967.h" + +extern const struct device __device_dts_ord_DT_CHOSEN_zephyr_cortex_m_idle_timer_ORD; + +#endif diff --git a/soc/elan/em32f967/soc.yml b/soc/elan/em32f967/soc.yml new file mode 100644 index 0000000000000..efdeb46d8e68e --- /dev/null +++ b/soc/elan/em32f967/soc.yml @@ -0,0 +1,2 @@ +socs: +- name: em32f967 diff --git a/soc/elan/em32f967/soc_967.h b/soc/elan/em32f967/soc_967.h new file mode 100644 index 0000000000000..ec2505e1d7542 --- /dev/null +++ b/soc/elan/em32f967/soc_967.h @@ -0,0 +1,438 @@ +#ifndef __ELAN_SOC_967__ +#define __ELAN_SOC_967__ + +#include "elan_em32.h" + +typedef struct { + __IO uint32_t ESPI_S2: 2; // [1:0] + __IO uint32_t SSP_S2: 2; // [3:2] + __IO uint32_t ISO7816_1_S: 1; // [4] + __IO uint32_t ISO7816_2_S: 1; // [5] + __IO uint32_t UART1_S: 1; // [6] + __IO uint32_t UART2_S: 1; // [7] + __IO uint32_t I2C1_S: 1; // [8] + __IO uint32_t I2C2_S: 1; // [9] + __IO uint32_t USART_S: 1; // [10] + __IO uint32_t DMA_CS_S2: 2; // [12:11] + __IO uint32_t SSP_2_4_S: 1; // [13] + __IO uint32_t Flash_JTAG: 1; // [14] + __IO uint32_t PWM_D_A1_S: 1; // [15] + __IO uint32_t PWM_E_B1_S: 1; // [16] + __IO uint32_t PWM_F_C1_S: 1; // [17] + __IO uint32_t PWM_S: 1; // [18] + __IO uint32_t LPC_PWMAB8_S: 1; // [19] + __IO uint32_t LPC_PWMBB9_S: 1; // [20] + __IO uint32_t LPC_Test1_S: 2; // [22:21] + __IO uint32_t LPC_Test2_S: 2; // [24:23] + __IO uint32_t Reserved: 7; // [31:25] +} IOShare_Type; +#define IOShareCTRL ((IOShare_Type *)0x4003023c) + +typedef struct { + __IO uint32_t DATA; + union { + struct { + __IO uint32_t TXBUFFULL: 1; + __IO uint32_t RXBUFFULL: 1; + __IO uint32_t TXBUFOVERRUN: 1; + __IO uint32_t RXBUFOVERRUN: 1; + __IO uint32_t Reserved: 28; + } STATE_S; + __IO uint32_t STATE; + } STATE_U; + __IO uint32_t CTRL; + __IO uint32_t INTSTACLR; + __IO uint32_t BAUDDIV; + __IO uint32_t Reserved[3]; + __IO uint32_t DMALENGTHL; + __IO uint32_t DMALENGTHH; + __IO uint32_t DMAWAITCNT: 8; + __IO uint32_t ReservedBit0: 24; + __IO uint32_t DMAENANLE: 1; + __IO uint32_t TXNRX: 1; + __IO uint32_t ReservedBit: 30; +} UART_TypeDef; + +typedef enum { + PORTA = 0x00, + PORTB = 0x01, + PORTANALOG = 0x02 +} GPIOPortDef; + +typedef enum { + GPIO_PINSOURCE0 = 0x00, + GPIO_PINSOURCE1 = 0x01, + GPIO_PINSOURCE2 = 0x02, + GPIO_PINSOURCE3 = 0x03, + GPIO_PINSOURCE4 = 0x04, + GPIO_PINSOURCE5 = 0x05, + GPIO_PINSOURCE6 = 0x06, + GPIO_PINSOURCE7 = 0x07, + GPIO_PINSOURCE8 = 0x08, + GPIO_PINSOURCE9 = 0x09, + GPIO_PINSOURCE10 = 0x0a, + GPIO_PINSOURCE11 = 0x0b, + GPIO_PINSOURCE12 = 0x0c, + GPIO_PINSOURCE13 = 0x0d, + GPIO_PINSOURCE14 = 0x0e, + GPIO_PINSOURCE15 = 0x0f +} GPIOPinNameDef; + +typedef enum { + FALLING = 0x00, + RISING = 0x01, + LOWLEVEL = 0x02, + HIGHLEVEL = 0x03 +} GPIOINTDef; + +typedef enum { + GPIO_MUX00 = 0x00, + GPIO_MUX01 = 0x01, + GPIO_MUX02 = 0x02, + GPIO_MUX03 = 0x03, + GPIO_MUX04 = 0x04, + GPIO_MUX05 = 0x05, + GPIO_MUX06 = 0x06, + GPIO_MUX07 = 0x07 +} GPIOMUXDef; + +typedef enum { + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ +} GPIOModeDef; + +typedef enum { + GPIO_PuPd_Floating = 0x00, + GPIO_PuPd_PullUp66K = 0x01, + GPIO_PuPd_PullUp4_7K = 0x02, + GPIO_PuPd_Pulldown15K = 0x03 +} GPIOPuPdDef; + +typedef enum { + GPIO_OD02 = 0x00, + GPIO_OD04 = 0x01, + GPIO_OD06 = 0x02, + GPIO_OD08 = 0x03, +} GPIOODDef; + +typedef enum { + Bit_RESET = 0, + Bit_SET = 1 +} BitAction; +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + +typedef struct { + GPIOPinNameDef GPIO_Pin; + GPIOModeDef GPIO_Mode; + GPIOPuPdDef GPIO_PuPd; +} GPIO_InitTypeDef; + +typedef enum { + GPIO_PIN_0 = 0x0001, + GPIO_PIN_1 = 0x0002, + GPIO_PIN_2 = 0x0004, + GPIO_PIN_3 = 0x0008, + GPIO_PIN_4 = 0x0010, + GPIO_PIN_5 = 0x0020, + GPIO_PIN_6 = 0x0040, + GPIO_PIN_7 = 0x0080, + GPIO_PIN_8 = 0x0100, + GPIO_PIN_9 = 0x0200, + GPIO_PIN_10 = 0x0400, + GPIO_PIN_11 = 0x0800, + GPIO_PIN_12 = 0x1000, + GPIO_PIN_13 = 0x2000, + GPIO_PIN_14 = 0x4000, + GPIO_PIN_15 = 0x8000, + GPIO_PIN_ALL = 0xffff +} GPIOPinBitDef; + +typedef struct { + __IO uint16_t DATA; // 0x00 + __IO uint16_t dummy0; + __IO uint16_t DATAOUT; // 0x04 + __IO uint16_t dummy1; + __IO uint16_t Reserved0; + __IO uint16_t dummy2; + __IO uint16_t Reserved1; + __IO uint16_t dummy3; + __IO uint16_t DATAOUTSET; // 0x10 + __IO uint16_t dummy4; + __IO uint16_t DATAOUTCLR; // 0x14 + __IO uint16_t dummy5; + __IO uint16_t ALTFUNCSET; // 0x18 + __IO uint16_t dummy6; + __IO uint16_t ALTFUNCCLR; // 0x1c + __IO uint16_t dummy7; + __IO uint16_t INTENSET; // 0x20 + __IO uint16_t dummy8; + __IO uint16_t INTENCLR; // 0x24 + __IO uint16_t dummy9; + __IO uint16_t INTTYPEEDGESET; // 0x28 + __IO uint16_t dummy10; + __IO uint16_t INTTYPEEDGECLR; // 0x2c + __IO uint16_t dummy11; + __IO uint16_t INTPOLSET; // 0x30 + __IO uint16_t dummy12; + __IO uint16_t INTPOLCLR; // 0x34 + __IO uint16_t dummy13; + __IO uint16_t INTSTATUSANDCLR; // 0x38 + __IO uint16_t dummy14; +} GPIO_IPType; + +#define GPIOIPA ((GPIO_IPType *)GPIOA_BASE) +#define GPIOIPB ((GPIO_IPType *)GPIOB_BASE) + +typedef enum { + MOTOSPI_HO00 = 0x00, + TI = 0x01, + NATIONAL = 0x02, + MOTOSPI_HO01 = 0x40, + MOTOSPI_HO10 = 0x80, + MOTOSPI_HO11 = 0xc0, +} SSPType_Def; + +typedef enum { + SSP_MASTER = 0x00, /*!< SPI master Mode */ + SSP_SLAVE = 0x01, /*!< SPI slave Mode */ + SSP_MASTER_CS_IND = 0x02 /*!< CS by GPIO */ +} SPIMode_Def; + +typedef enum { + SPI_O0H0 = 0x00, // SPI SPO = 0, SPH = 0 + SPI_O0H1 = 0x01, // SPI SPO = 0, SPH = 1 + SPI_O1H0 = 0x02, // SPI SPO = 1, SPH = 0 + SPI_O1H1 = 0x03 // SPI SPO = 1, SPH = 1 +} SPIType_Def; + +typedef enum { + SPI_CS_IP = 0x00, // SPI_CS by IP + SPI_CS_IO_FLOAT = 0x01, // SPI_CS by GPIO no pull high + SPI_CS_IO_PU66K = 0x02, // SPI_CS by GPIO pull high 66K + SPI_CS_IO_PU4_7K = 0x03 // SPI_CS by GPIO pull high 4.7K +} CSType_Def; + +typedef struct { + SSPType_Def SSPType; + SPIMode_Def SSPMode; + uint8_t SSPBits; + uint8_t SpeedDIV; +} SSP_InitTypeDef; + +typedef struct { + uint32_t DSS: 4; + uint32_t FRF: 2; + uint32_t SPO: 1; + uint32_t SPH: 1; + uint32_t SCR: 8; + uint32_t Empty: 16; +} SSPCR0_TypeDef; + +typedef struct { + uint32_t LBM: 1; + uint32_t SSE: 1; + uint32_t MS: 1; + uint32_t SOD: 1; + uint32_t Reserved: 4; + uint32_t Empty: 16; +} SSPCR1_TypeDef; + +typedef struct { + uint32_t TFE: 1; + uint32_t TNF: 1; + uint32_t RNE: 1; + uint32_t RFF: 1; + uint32_t BSY: 1; + uint32_t Reserved: 11; + uint32_t Empty: 16; +} SSPSR_TypeDef; + +typedef struct { + uint32_t CPSDVSR: 8; + uint32_t Reserved: 8; + uint32_t Empty: 16; +} SSPCPSR_TypeDef; + +typedef struct { + uint32_t RORIM: 1; + uint32_t RTIM: 1; + uint32_t RXIM: 1; + uint32_t TXIM: 1; + uint32_t Reserved: 12; + uint32_t Empty: 16; +} SSPIMSC_TypeDef; + +typedef struct { + uint32_t RORMIS: 1; + uint32_t RTMIS: 1; + uint32_t RXMIS: 1; + uint32_t TXMIS: 1; + uint32_t Reserved: 12; + uint32_t Empty: 16; +} SSPMIS_TypeDef; + +typedef struct { + uint32_t SSP_MISO_DELAY: 4; + uint32_t FILLEEVEL_RX: 3; + uint32_t Reserved: 1; + uint32_t FILLEEVEL_TX: 3; + uint32_t Reserved1: 1; + uint32_t B_ENDIAN: 1; + uint32_t Reserved2: 2; + uint32_t DMA_CS_EN: 1; + uint32_t Reserved3: 16; +} SSPWRAP_TypeDef; + +typedef struct { + union { + __IO uint32_t SSPCR0; + __IO SSPCR0_TypeDef SSPCR0_S; + } SSPCR0_U; + union { + __IO uint32_t SSPCR1; + __IO SSPCR1_TypeDef SSPCR1_S; + } SSPCR1_U; + __IO uint32_t SSPDR; + union { + __IO uint32_t SSPSR; + __IO SSPSR_TypeDef SSPSR_S; + } SSPSR_U; + union { + __IO uint32_t SSPCPSR; + __IO SSPCPSR_TypeDef SSPCPSR_S; + } SSPCPSR_U; + union { + __IO uint32_t SSPIMSC; + __IO SSPIMSC_TypeDef SSPIMSC_S; + } SSPIMSC_U; + __IO uint32_t SSPRIS; + union { + __IO uint32_t SSPMIS; + __IO SSPIMSC_TypeDef SSPMIS_S; + } SSPMIS_U; + __IO uint32_t SSPICR; + __IO uint32_t SSPDMACR; + __IO SSPWRAP_TypeDef SSPWRAP_S; +} SSP_TypeDef; + +#define SSP1 ((SSP_TypeDef *)SSP1_BASE) +#define SSP2 ((SSP_TypeDef *)SSP2_BASE) + +#define SPI1 ((SSP_TypeDef *)SSP1_BASE) +#define SPI2 ((SSP_TypeDef *)SSP2_BASE) + +typedef struct { + __I uint32_t PageData: 13; + __IO uint32_t PageIndex: 7; + __IO uint32_t Reserved: 12; +} Cache_bound_Type; + +#define CACHECTRL (*(__IO uint32_t *)0x40037000) +#define CACHECTRL_Upper ((Cache_bound_Type *)0x40037004) +#define CACHECTRL_Lower ((Cache_bound_Type *)0x40037008) +#define CACHECOUNTBASE (*(__IO uint32_t *)0x4003700c) +#define CACHECOUNTHIT (*(__IO uint32_t *)0x40037010) + +#define IOMUXPACTRL (*(__IO uint32_t *)0x40030200) +#define IOMUXPACTRL2 (*(__IO uint32_t *)0x40030204) +#define IOMUXPBCTRL (*(__IO uint32_t *)0x40030208) +#define IOMUXPBCTRL2 (*(__IO uint32_t *)0x4003020c) +#define IOANAENCTRL (*(__IO uint32_t *)0x40030210) +#define IOPUPDPACTRL (*(__IO uint32_t *)0x40030214) +#define IOPUPDPBCTRL (*(__IO uint32_t *)0x40030218) +#define IOHDPACRTL (*(__IO uint32_t *)0x4003021c) +#define IOHDPBCRTL (*(__IO uint32_t *)0x40030220) +#define IOSMTPACTRL (*(__IO uint32_t *)0x40030224) +#define IOSMTPBCTRL (*(__IO uint32_t *)0x40030228) +#define IOODEPACTRL (*(__IO uint32_t *)0x4003022c) +#define IOODEPBCTRL (*(__IO uint32_t *)0x40030230) +#define IOOSEPACTRL (*(__IO uint32_t *)0x40030234) +#define IOOSEPBCTRL (*(__IO uint32_t *)0x40030238) + +#define PDGPIOCTRL (*(__IO uint32_t *)0x40030240) + +#define PDPAOE (*(__IO uint32_t *)0x40030244) +#define PDPBOE (*(__IO uint32_t *)0x40030248) +#define PDPAOUT (*(__IO uint32_t *)0x4003024c) +#define PDPBOUT (*(__IO uint32_t *)0x40030250) + +#define PB8CLOCKRATE (*(__IO uint32_t *)0x40030254) +#define PB9CLOCKRATE (*(__IO uint32_t *)0x40030258) + +#define IPGPIOADATA (*(__IO uint32_t *)0x40020000) +#define IPGPIOADATAOUT (*(__IO uint32_t *)0x40020004) +#define IPGPIOBDATA (*(__IO uint32_t *)0x40021000) +#define IPGPIOBDATAOUT (*(__IO uint32_t *)0x40021004) + +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT)) + +typedef enum { + WDTINT = 0, + WDTRESET = 1 +} WDTMode; +#define BACKUPREG0 (*(__IO uint32_t *)(BACKUP_BASE + 0)) +#define BACKUPREG1 (*(__IO uint32_t *)(BACKUP_BASE + 4)) + +typedef enum { + IRC12 = 0x00, + IRC16 = 0x01, + IRC20 = 0x02, + IRC24 = 0x03, + IRC28 = 0x04, + IRC32 = 0x05, + XTAL24 = 0x11, + XTAL12 = 0x13, + External = 0x20 +} FreqSource; + +typedef struct { + __IO uint32_t MIRC_Tall: 10; + __IO uint32_t MIRC_TV12: 3; + __IO uint32_t Reserved: 17; +} MIRCTRIM_Type2; +#define MIRC12M_R_2 ((MIRCTRIM_Type2 *)0x100a7f60) +#define MIRC16M_2 ((MIRCTRIM_Type2 *)0x100a6070) +#define MIRC20M_2 ((MIRCTRIM_Type2 *)0x100a6074) +#define MIRC24M_2 ((MIRCTRIM_Type2 *)0x100a6078) +#define MIRC28M_2 ((MIRCTRIM_Type2 *)0x100a607c) +#define MIRC32M_2 ((MIRCTRIM_Type2 *)0x100a6080) + +typedef struct { + __IO uint32_t CLKOUT0SEL: 4; + __IO uint32_t CLKOUT1SEL: 4; + __IO uint32_t CLKOUT0DIV: 7; + __IO uint32_t CLKOUT1DIV: 7; + __IO uint32_t Reserved: 10; +} TopTest_Type; +#define TOPTEST ((TopTest_Type *)0x40030300) + +bool GPIO_ReadBit(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +uint16_t GPIO_ReadPort(GPIO_IPType *GPIOx); +void GPIO_WritePort(GPIO_IPType *GPIOx, uint16_t PortVal); +void GPIOMUXSet(GPIOPortDef GPIOx, GPIOPinNameDef GPIOPin, GPIOMUXDef MUXNum); +void GPIO_WriteBit(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin, BitAction BitVal); +void GPIO_ToggleBits(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_Init(GPIO_IPType *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct); +void EnableGPIOINT(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin, GPIOINTDef TriggerType); +void DisableGPIOINT(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); + +void GPIO_HighDrive_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_HighDrive_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_OpenDrain_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_OpenDrain_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_OpenSource_Enable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); +void GPIO_OpenSource_Disable(GPIO_IPType *GPIOx, GPIOPinBitDef GPIOPin); + +void GPIO_SetOuput2(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin); +void GPIO_SetOutput(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin, GPIOPuPdDef GPIOAttr); +void GPIO_SetInputFloat(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin); +void GPIO_SetInput(GPIO_IPType *GPIOx, GPIOPinNameDef GPIOPin, GPIOPuPdDef GPIOAttr); + +void CLKGatingEnable(CLKGatingSwitch GatingN); +void CLKGatingDisable(CLKGatingSwitch GatingN); +bool IsCLKGating(CLKGatingSwitch GatingN); +void SetCLKOut(int8_t ClkS, int8_t SourceSel, int16_t DIV); + +void WatchDogEnable(WDTMode mode, uint32_t msec); + +#endif