From f7a6d3719bf6501f3aeea548bca8bc3e1e603294 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 16:52:14 +0800 Subject: [PATCH 1/8] west.yml: Add Realtek HAL as a new HAL module Realtek HAL (Hardware Abstraction Layer) provides a low level peripheral configuration function. Signed-off-by: zjian zhang --- west.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/west.yml b/west.yml index fc43ee8198522..e771b18a58551 100644 --- a/west.yml +++ b/west.yml @@ -23,6 +23,8 @@ manifest: url-base: https://github.com/zephyrproject-rtos - name: babblesim url-base: https://github.com/BabbleSim + - name: nuwa + url-base: https://github.com/zjian-zhang group-filter: [-babblesim, -optional] @@ -224,6 +226,12 @@ manifest: path: modules/hal/quicklogic groups: - hal + - name: hal_realtek + remote: nuwa + path: modules/hal/realtek + revision: fc06336f06f3f9ea38d72070f4b7d96b57e0f66b + groups: + - hal - name: hal_renesas path: modules/hal/renesas revision: 9b99067e29a1b44b53192c2c797db330f5703462 From ad169d9655b5e565abca9c378a381192759efac2 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Mon, 30 Sep 2024 23:29:56 +0800 Subject: [PATCH 2/8] dts: arm: introduce amebadplus SOC Devicetree add initial version of devicetree for amebadplus SOC. amebadplus devicetree file is main platform dtsi file, which should be included from board dts (e.g rtl872xda_evb.dts) Signed-off-by: zjian zhang --- dts/arm/realtek/amebadplus/amebadplus.dtsi | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 dts/arm/realtek/amebadplus/amebadplus.dtsi diff --git a/dts/arm/realtek/amebadplus/amebadplus.dtsi b/dts/arm/realtek/amebadplus/amebadplus.dtsi new file mode 100644 index 0000000000000..68246666cd129 --- /dev/null +++ b/dts/arm/realtek/amebadplus/amebadplus.dtsi @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m55"; + reg = <0>; + d-cache-line-size = <32>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + clocks { + clk_sys: clk_sys { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + }; + + soc { + sram0: memory@20010020 { + compatible = "mmio-sram"; + reg = <0x20010020 0x00030000>; + }; + + ram_image2_entry: memory@20004da0 { + compatible = "zephyr,memory-region"; + reg = <0x20004da0 0x20>; + zephyr,memory-region = "KM4_IMG2_ENTRY"; + }; + + pinctrl: pinctrl@41008800 { + compatible = "realtek,ameba-pinctrl"; + reg = <0x41008800 0x200>; + status = "disabled"; + }; + + loguart: serial@4100f000 { + compatible = "realtek,ameba-loguart"; + reg = <0x4100f000 0x100>; + interrupts = <27 0>; + current-speed = <1500000>; + status = "disabled"; + }; + + gpioa: gpio@41010000 { + compatible = "realtek,ameba-gpio"; + reg = <0x41010000 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <28 0>; + status = "disabled"; + }; + + gpiob: gpio@41010400 { + compatible = "realtek,ameba-gpio"; + reg = <0x41010400 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <29 0>; + status = "disabled"; + }; + + spic: flash-controller@40128000 { + compatible = "realtek,ameba-flash-controller"; + reg = <0x40128000 0x200>; + + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + flash0: flash@e000020 { + compatible = "soc-nv-flash"; + erase-block-size = ; + write-block-size = <4>; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; From e21fd8fbe9e9fbf6d33085f527453107d5661267 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Thu, 19 Sep 2024 21:27:27 +0800 Subject: [PATCH 3/8] soc: add realtek amebadplus SOC integration Add initial version of Amebadplus Soc integration Signed-off-by: zjian zhang --- soc/realtek/ameba/CMakeLists.txt | 7 + soc/realtek/ameba/Kconfig | 12 ++ soc/realtek/ameba/Kconfig.defconfig | 8 + soc/realtek/ameba/Kconfig.soc | 10 ++ soc/realtek/ameba/amebadplus/CMakeLists.txt | 10 ++ soc/realtek/ameba/amebadplus/Kconfig | 15 ++ .../ameba/amebadplus/Kconfig.defconfig | 15 ++ soc/realtek/ameba/amebadplus/Kconfig.soc | 13 ++ soc/realtek/ameba/amebadplus/boot_section.ld | 20 +++ soc/realtek/ameba/amebadplus/soc.c | 39 +++++ soc/realtek/ameba/amebadplus/soc.h | 17 +++ soc/realtek/ameba/common/CMakeLists.txt | 4 + .../ameba/common/os_wrapper/CMakeLists.txt | 4 + .../common/os_wrapper/include/os_wrapper.h | 47 ++++++ .../os_wrapper/include/os_wrapper_critical.h | 31 ++++ .../os_wrapper/include/os_wrapper_memory.h | 68 +++++++++ .../os_wrapper/include/os_wrapper_mutex.h | 138 +++++++++++++++++ .../os_wrapper/include/os_wrapper_queue.h | 90 ++++++++++++ .../os_wrapper/include/os_wrapper_semaphore.h | 122 +++++++++++++++ .../os_wrapper/include/os_wrapper_task.h | 139 ++++++++++++++++++ .../os_wrapper/include/os_wrapper_time.h | 51 +++++++ .../os_wrapper/include/os_wrapper_timer.h | 129 ++++++++++++++++ .../os_wrapper/include/platform_stdlib.h | 16 ++ soc/realtek/ameba/soc.yml | 4 + 24 files changed, 1009 insertions(+) create mode 100644 soc/realtek/ameba/CMakeLists.txt create mode 100644 soc/realtek/ameba/Kconfig create mode 100644 soc/realtek/ameba/Kconfig.defconfig create mode 100644 soc/realtek/ameba/Kconfig.soc create mode 100644 soc/realtek/ameba/amebadplus/CMakeLists.txt create mode 100644 soc/realtek/ameba/amebadplus/Kconfig create mode 100644 soc/realtek/ameba/amebadplus/Kconfig.defconfig create mode 100644 soc/realtek/ameba/amebadplus/Kconfig.soc create mode 100644 soc/realtek/ameba/amebadplus/boot_section.ld create mode 100644 soc/realtek/ameba/amebadplus/soc.c create mode 100644 soc/realtek/ameba/amebadplus/soc.h create mode 100644 soc/realtek/ameba/common/CMakeLists.txt create mode 100644 soc/realtek/ameba/common/os_wrapper/CMakeLists.txt create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_critical.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_memory.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_mutex.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_queue.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_semaphore.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_task.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_time.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/os_wrapper_timer.h create mode 100644 soc/realtek/ameba/common/os_wrapper/include/platform_stdlib.h create mode 100644 soc/realtek/ameba/soc.yml diff --git a/soc/realtek/ameba/CMakeLists.txt b/soc/realtek/ameba/CMakeLists.txt new file mode 100644 index 0000000000000..b770b597e60a6 --- /dev/null +++ b/soc/realtek/ameba/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(common) + +add_subdirectory(common) +add_subdirectory(${CONFIG_SOC}) diff --git a/soc/realtek/ameba/Kconfig b/soc/realtek/ameba/Kconfig new file mode 100644 index 0000000000000..b51759e890077 --- /dev/null +++ b/soc/realtek/ameba/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_REALTEK_AMEBA + select BUILD_OUTPUT_HEX + select SOC_EARLY_INIT_HOOK + +if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig" + +endif # SOC_FAMILY_REALTEK_AMEBA diff --git a/soc/realtek/ameba/Kconfig.defconfig b/soc/realtek/ameba/Kconfig.defconfig new file mode 100644 index 0000000000000..d4e73efa3d45d --- /dev/null +++ b/soc/realtek/ameba/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_REALTEK_AMEBA diff --git a/soc/realtek/ameba/Kconfig.soc b/soc/realtek/ameba/Kconfig.soc new file mode 100644 index 0000000000000..2c1a5f11b3160 --- /dev/null +++ b/soc/realtek/ameba/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_REALTEK_AMEBA + bool + +config SOC_FAMILY + default "realtek_ameba" if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig.soc" diff --git a/soc/realtek/ameba/amebadplus/CMakeLists.txt b/soc/realtek/ameba/amebadplus/CMakeLists.txt new file mode 100644 index 0000000000000..c6443d35e9197 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +zephyr_linker_sources(SECTIONS boot_section.ld) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/realtek/ameba/amebadplus/Kconfig b/soc/realtek/ameba/amebadplus/Kconfig new file mode 100644 index 0000000000000..e04024c092044 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_AMEBADPLUS + select ARM + select CPU_CORTEX_M55 + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select CPU_HAS_VFP + select ARMV8_M_DSP + select CPU_HAS_ARM_MPU + select ARM_MPU + select ARM_TRUSTZONE_M diff --git a/soc/realtek/ameba/amebadplus/Kconfig.defconfig b/soc/realtek/ameba/amebadplus/Kconfig.defconfig new file mode 100644 index 0000000000000..90bc7e72ca091 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_AMEBADPLUS + +config NUM_IRQS + default 96 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_sys,clock-frequency) + +config CACHE_MANAGEMENT + default y + +endif #SOC_AMEBADPLUS diff --git a/soc/realtek/ameba/amebadplus/Kconfig.soc b/soc/realtek/ameba/amebadplus/Kconfig.soc new file mode 100644 index 0000000000000..7ab8375b292fe --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig.soc @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_AMEBADPLUS + bool + select SOC_FAMILY_REALTEK_AMEBA + +config SOC + default "amebadplus" if SOC_AMEBADPLUS + +config ARM_CORE_CM4 + bool + default y if SOC_AMEBADPLUS diff --git a/soc/realtek/ameba/amebadplus/boot_section.ld b/soc/realtek/ameba/amebadplus/boot_section.ld new file mode 100644 index 0000000000000..07ea68312e6d9 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/boot_section.ld @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.ram_image2.entry,,SUBALIGN(32)) +{ + __image2_entry_func__ = .; + KEEP(*(SORT(.image2.entry.data*))) + . = ALIGN(32); +} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +SECTION_PROLOGUE(.psram_image2.text.data,,SUBALIGN(32)) +{ + . = ALIGN (32); + __ipc_table_start__ = .; + KEEP(*(*.ipc.table.data*)) + __ipc_table_end__ = .; +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/realtek/ameba/amebadplus/soc.c b/soc/realtek/ameba/amebadplus/soc.c new file mode 100644 index 0000000000000..959fa07a33e20 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/soc.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include + +void z_arm_reset(void); + +IMAGE2_ENTRY_SECTION +RAM_START_FUNCTION Img2EntryFun0 = {z_arm_reset, NULL, /* BOOT_RAM_WakeFromPG, */ + (uint32_t)NewVectorTable}; + +void soc_early_init_hook(void) +{ + /* + * Cache is enabled by default at reset, disable it before + * sys_cache*-functions can enable them. + */ + Cache_Enable(DISABLE); + sys_cache_instr_enable(); + sys_cache_data_enable(); + + XTAL_INIT(); + + if (SYSCFG_CHIPType_Get() == CHIP_TYPE_ASIC_POSTSIM) { /* Only Asic need OSC Calibration */ + OSC4M_Init(); + OSC4M_Calibration(30000); + if ((((BOOT_Reason()) & AON_BIT_RSTF_DSLP) == FALSE)) { + OSC131K_Calibration(30000); /* PPM=30000=3% */ /* 7.5ms */ + } + } +} diff --git a/soc/realtek/ameba/amebadplus/soc.h b/soc/realtek/ameba/amebadplus/soc.h new file mode 100644 index 0000000000000..be800319c1e5d --- /dev/null +++ b/soc/realtek/ameba/amebadplus/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ + +#ifndef _ASMLANGUAGE + +#include +#include "cmsis_cpu.h" + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ */ diff --git a/soc/realtek/ameba/common/CMakeLists.txt b/soc/realtek/ameba/common/CMakeLists.txt new file mode 100644 index 0000000000000..10252c5c3308a --- /dev/null +++ b/soc/realtek/ameba/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(os_wrapper) diff --git a/soc/realtek/ameba/common/os_wrapper/CMakeLists.txt b/soc/realtek/ameba/common/os_wrapper/CMakeLists.txt new file mode 100644 index 0000000000000..4a9540b9b93de --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(include) diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper.h new file mode 100644 index 0000000000000..92dde9d8cb3c7 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_H__ +#define __OS_WRAPPER_H__ + +/** + * @brief Necessary headers + */ +#include +#include +#include + +#include "platform_autoconf.h" +#include "ameba.h" +#include + +/** + * @brief Common header file + */ +#ifdef __cplusplus +extern "C" { +#endif +#include "os_wrapper_semaphore.h" +#include "os_wrapper_critical.h" +#include "os_wrapper_memory.h" +#include "os_wrapper_mutex.h" +#include "os_wrapper_queue.h" +#include "os_wrapper_semaphore.h" +#include "os_wrapper_task.h" +#include "os_wrapper_time.h" +#include "os_wrapper_timer.h" +#ifdef __cplusplus +} +#endif + +/** + * @brief General macro definition + */ + +#define RTOS_MAX_DELAY 0xFFFFFFFFUL +#define RTOS_MAX_TIMEOUT 0xFFFFFFFFUL + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_critical.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_critical.h new file mode 100644 index 0000000000000..d1534243cbd4c --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_critical.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_CRITCAL_H__ +#define __OS_WRAPPER_CRITCAL_H__ + +/** + * @brief Check if in task interrupt + * @retval 1: interrupt; 0: context + */ +int rtos_critical_is_in_interrupt(void); + +/** + * @brief Internally handles interrupt status (PRIMASK/CPSR) save + */ +void rtos_critical_enter(void); + +/** + * @brief Internally handles interrupt status(PRIMASK/CPSR) restore + */ +void rtos_critical_exit(void); + +/** + * @brief get task enter critical state + * @retval >0: in critical state; 0: exit critical state + */ +uint32_t rtos_get_critical_state(void); +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_memory.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_memory.h new file mode 100644 index 0000000000000..f52f2e0342cdd --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_memory.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_MEMORY_H__ +#define __OS_WRAPPER_MEMORY_H__ + +/** + * @brief Initialize dynamic memory pool + */ +void rtos_mem_init(void); + +/** + * @brief Allocate memory from the heap. The buffer value is random + * @note The return buffer size/address is cacheline size aligned + * @param size: buffer size in byte + * @retval Pointer to memory the caller can now use + */ +void *rtos_mem_malloc(uint32_t size); + +/** + * @brief Allocate memory from the heap. The buffer value is zero + * @note The return buffer size/address is cacheline size aligned + * @param size: buffer size in byte + * @retval Pointer to memory the caller can now use + */ +void *rtos_mem_zmalloc(uint32_t size); + +/** + * @brief Allocate memory from the heap. The buffer value is zero + * @note The return buffer size/address is cacheline size aligned + * @param elementNum: Number of elements, memory size is elementNum*elementSize + * @param elementSize: Size of each array element (in bytes). + * @retval Pointer to memory the caller can now use + */ +void *rtos_mem_calloc(uint32_t elementNum, uint32_t elementSize); + +/** + * @brief Reuse or extend memory previously allocated by the malloc(), calloc(), and realloc() + * functions + * @note The return buffer size/address is cacheline size aligned + * @param pbuf: Pointer containing the address + * @param size: The number of bytes of memory to be newly allocated. + * @retval Pointer to memory the caller can now use + */ +void *rtos_mem_realloc(void *pbuf, uint32_t size); + +/** + * @brief Deallocate memory from the heap. + * @param pbuf: a pointer to memory previously allocated + */ +void rtos_mem_free(void *pbuf); + +/** + * @brief Get free heap size. + * @retval Free heap size in byte + */ +uint32_t rtos_mem_get_free_heap_size(void); + +/** + * @brief Get minimum ever free heap size. + * @retval Minimum ever free heap size in byte + */ +uint32_t rtos_mem_get_minimum_ever_free_heap_size(void); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_mutex.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_mutex.h new file mode 100644 index 0000000000000..9f8bcc39d8c01 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_mutex.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_MUTEX_H__ +#define __OS_WRAPPER_MUTEX_H__ + +/** + * @brief mutex handle type + */ +typedef void *rtos_mutex_t; + +#define MUTEX_WAIT_TIMEOUT 0xFFFFFFFFU /* will be replaced by common max timeout later */ + +/** + * @brief Static memory allocation implementation of rtos_mutex_create + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_create_static(rtos_mutex_t *pp_handle); + +/** + * @brief Static memory allocation implementation of rtos_mutex_delete + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_delete_static(rtos_mutex_t p_handle); + +/** + * @brief Static memory allocation implementation of rtos_mutex_recursive_create + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_create_static(rtos_mutex_t *pp_handle); + +/** + * @brief Static memory allocation implementation of rtos_mutex_recursive_delete + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_delete_static(rtos_mutex_t p_handle); + +/** + * @brief Compared to semaphores, Mutex has a priority inheritance mechanism. + * Dynamic allocate memory. + * @note Usage example: + * Create: + * rtos_mutex_t mutex_handle; + * rtos_mutex_create(&mutex_handle); + * Give: + * rtos_mutex_give(mutex_handle); + * Take: + * rtos_mutex_take(mutex_handle, 100); + * Delete: + * rtos_mutex_delete(mutex_handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_create(rtos_mutex_t *pp_handle); + +/** + * @brief Delete a mutex. + * @note Do not delete mutex if held by a task + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_delete(rtos_mutex_t p_handle); + +/** + * @brief Take a mutex. + * The API internally determines whether it is in the interrupt state and calls the + * corresponding RTOS interface. + * @param p_handle: Address of the mutex + * @param wait_ms: The time in milliseconds to wait, 0xFFFFFFFF means Block infinitely until the + * semaphore taken. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_take(rtos_mutex_t p_handle, uint32_t wait_ms); + +/** + * @brief Give a semaphore. + * The API internally determines whether it is in the interrupt state and calls the + * corresponding RTOS interface. + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_give(rtos_mutex_t p_handle); + +/** + * @brief Creates a new recursive mutex, compared to semaphores, Mutex has a priority inheritance + * mechanism. Dynamic allocate memory. + * @note Usage example: + * Create: + * rtos_mutex_t mutex_handle; + * rtos_mutex_recursive_create(&mutex_handle); + * Give: + * rtos_mutex_recursive_give(mutex_handle); + * Take: + * rtos_mutex_recursive_take(mutex_handle, 100); + * Delete: + * rtos_mutex_recursive_delete(mutex_handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_create(rtos_mutex_t *pp_handle); + +/** + * @brief Delete a mutex. + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_delete(rtos_mutex_t p_handle); + +/** + * @brief Take a mutex. + * @note recursive mutexes cannot be used in interrupt service routines. + * @param p_handle: Address of the mutex + * @param wait_ms: The time in milliseconds to wait, 0xFFFFFFFF means Block infinitely until the + * semaphore taken. + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_take(rtos_mutex_t p_handle, uint32_t wait_ms); + +/** + * @brief Give a semaphore. + * @note Recursive mutexes cannot be used in interrupt service routines. + * @param p_handle: Address of the mutex + * @retval The status is SUCCESS or FAIL + */ +int rtos_mutex_recursive_give(rtos_mutex_t p_handle); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_queue.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_queue.h new file mode 100644 index 0000000000000..141e7a506d420 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_queue.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_QUEUE_H__ +#define __OS_WRAPPER_QUEUE_H__ + +/** + * @brief queue handle type + */ +typedef void *rtos_queue_t; + +/** + * @brief Creates a new queue instance + * @note Usage example: + * Create: + * rtos_queue_t queue_handle; + * rtos_queue_create(&queue_handle, 5, sizeof(uint32_t)); + * Send: + * rtos_queue_send(queue_handle, p_msg, portMAX_DELAY); + * Receive: + * rtos_queue_receive(queue_handle, p_msg, portMAX_DELAY); + * Delete: + * rtos_queue_delete(queue_handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param msg_num: Maximum number of messages that can be queued. + * @param msg_size: Message size (in bytes). + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_create(rtos_queue_t *pp_handle, uint32_t msg_num, uint32_t msg_size); + +/** + * @brief Delete a queue - freeing all the memory allocated for storing of items placed on the + * queue. + * @param p_handle: A handle to the queue to be deleted. + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_delete(rtos_queue_t p_handle); + +/** + * @brief Return the number of messages stored in a queue. + * @param p_handle: A handle to the queue being queried. + * @retval The number of messages available in the queue. + */ +uint32_t rtos_queue_message_waiting(rtos_queue_t p_handle); + +/** + * @brief Send a message to a message queue in a "first in, first out" manner. + * @param p_handle: Address of the message queue. + * @param p_msg: Pointer to the message. + * @param wait_ms: Waiting period to add the message, 0xFFFFFFFF means Block infinitely. + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_send(rtos_queue_t p_handle, void *p_msg, uint32_t wait_ms); + +/** + * @brief Send a message to the head of message queue in a "last in, first out" manner. + * @param p_handle: Address of the message queue. + * @param p_msg: Pointer to the message. + * @param wait_ms: Waiting period to add the message, 0xFFFFFFFF means Block infinitely. + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_send_to_front(rtos_queue_t p_handle, void *p_msg, uint32_t wait_ms); + +/** + * @brief Receive a message from a message queue in a "first in, first out" manner. + * Messages are received from the queue and removed from the queue, so the queue's state + * changes. + * @param p_handle: Address of the message queue. + * @param p_msg: Address of area to hold the received message. + * @param wait_ms: Waiting period to add the message, 0xFFFFFFFF means Block infinitely. + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_receive(rtos_queue_t p_handle, void *p_msg, uint32_t wait_ms); + +/** + * @brief Peek/read a message from a message queue in a "first in, first out" manner. + * Simply viewing the next message in the queue does not remove it from the queue, + * so the state of the queue remains unchanged. + * @param p_handle: Address of the message queue. + * @param p_msg: Address of area to hold the received message. + * @param wait_ms: Waiting period to add the message, 0xFFFFFFFF means Block infinitely. + * @retval The status is SUCCESS or FAIL + */ +int rtos_queue_peek(rtos_queue_t p_handle, void *p_msg, uint32_t wait_ms); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_semaphore.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_semaphore.h new file mode 100644 index 0000000000000..d2b3188e647b3 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_semaphore.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_SEMA_H__ +#define __OS_WRAPPER_SEMA_H__ + +#define RTOS_SEMA_MIN_COUNT 0x0UL +#define RTOS_SEMA_MAX_COUNT 0xFFFFFFFFUL + +/** + * @brief semaphore handle type + */ +typedef void *rtos_sema_t; + +/** + * @brief Static memory allocation implementation of rtos_sema_create + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param init_count: The count value assigned to the semaphore when it is created. + * @param max_count: The maximum count value that can be reached. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_create_static(rtos_sema_t *pp_handle, uint32_t init_count, uint32_t max_count); + +/** + * @brief Static memory allocation implementation of rtos_sema_create_binary + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_create_binary_static(rtos_sema_t *pp_handle); + +/** + * @brief Static memory allocation implementation of rtos_sema_delete + * @param p_handle: Address of the semaphore + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_delete_static(rtos_sema_t p_handle); + +/** + * @brief Creates a new counting semaphore instance + * Dynamic allocate memory. + * @note Usage example: + * Create: + * rtos_sema_t sema_handle; + * rtos_sema_create(&sema_handle, 0, 10); + * Give: + * rtos_sema_give(sema_handle); + * Take: + * rtos_sema_take(sema_handle, 100); + * Delete: + * rtos_sema_delete(sema_handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param init_count: The count value assigned to the semaphore when it is created. + * @param max_count: The maximum count value that can be reached. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_create(rtos_sema_t *pp_handle, uint32_t init_count, uint32_t max_count); + +/** + * @brief Creates a new binary semaphore instance + * Dynamic allocate memory. + * @note The semaphore must first be 'given' before it can be 'taken'. + * Usage example: + * Create: + * rtos_sema_t sema_handle; + * rtos_sema_create_binary(&sema_handle); + * Give: + * rtos_sema_give(sema_handle); + * Take: + * rtos_sema_take(sema_handle, 100); + * Delete: + * rtos_sema_delete(sema_handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_create_binary(rtos_sema_t *pp_handle); + +/** + * @brief Delete a semaphore. + * @param p_handle: A handle to the semaphore to be deleted. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_delete(rtos_sema_t p_handle); + +/** + * @brief Take a semaphore. + * The API internally determines whether it is in the interrupt state and calls the + * corresponding RTOS interface. + * + * @note If timeout_ms is set to the maximum value, + * then if the semaphore cannot be obtained consistently, the log will be printed every 10 + * seconds. + * @param p_handle: Address of the semaphore. + * @param timeout_ms: Waiting period to add the message, 0xFFFFFFFF means Block infinitely. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_take(rtos_sema_t p_handle, uint32_t timeout_ms); + +/** + * @brief Give a semaphore. + * The API internally determines whether it is in the interrupt state and calls the + * corresponding RTOS interface. + * @param p_handle: Address of the semaphore. + * @retval The status is SUCCESS or FAIL + */ +int rtos_sema_give(rtos_sema_t p_handle); + +/** + * @brief Get a semaphore's count. If the semaphore is a binary semaphore then returns 1 if the + * semaphore is available, and 0 if the semaphore is not available. + * @param p_handle: Address of the semaphore. + * @retval Current semaphore count. + */ +uint32_t rtos_sema_get_count(rtos_sema_t p_handle); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_task.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_task.h new file mode 100644 index 0000000000000..82ad32e331851 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_task.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_TASK_H__ +#define __OS_WRAPPER_TASK_H__ + +/* CONFIG_NUM_COOP_PRIORITIES shall be 0 */ +#define RTOS_TASK_MAX_PRIORITIES (CONFIG_NUM_PREEMPT_PRIORITIES) +#define RTOS_MINIMAL_STACK_SIZE (1024) +#define RTOS_MINIMAL_SECURE_STACK_SIZE (1024) + +#define RTOS_SCHED_SUSPENDED 0x0UL +#define RTOS_SCHED_NOT_STARTED 0x1UL +#define RTOS_SCHED_RUNNING 0x2UL + +/** + * @brief task handle and function type + */ +typedef void *rtos_task_t; +typedef void (*rtos_task_function_t)(void *); + +/** + * @brief Start os kernel scheduler + * @retval return SUCCESS Only + */ +int rtos_sched_start(void); + +/** + * @brief Stop os kernel scheduler + * @retval return SUCCESS Only + */ +int rtos_sched_stop(void); + +/** + * @brief Suspend os kernel scheduler + * @retval return SUCCESS Only + */ +int rtos_sched_suspend(void); + +/** + * @brief Resume os kernel scheduler + * @retval return SUCCESS Only + */ +int rtos_sched_resume(void); + +/** + * @brief Get scheduler status. + * @retval RTOS_SCHED_SUSPENDED / RTOS_SCHED_NOT_STARTED / RTOS_SCHED_RUNNING + */ +int rtos_sched_get_state(void); + +/** + * @brief Create os level task routine. + * @note Usage example: + * Create: + * rtos_task_t handle; + * rtos_task_create(&handle, "test_task", task, NULL, 1024, 2); + * Suspend: + * rtos_task_suspend(handle); + * Resume: + * rtos_task_resume(handle); + * Delete: + * rtos_task_delete(handle); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param p_name: A descriptive name for the task. + * @param p_routine: Pointer to the task entry function. Tasks must be implemented to never return + * (i.e. continuous loop). + * @param p_param: Pointer that will be used as the parameter + * @param stack_size_in_byte: The size of the task stack specified + * @param priority: The priority at which the task should run (higher value, higher priority) + * @retval SUCCESS(0) / FAIL(-1) + */ +int rtos_task_create(rtos_task_t *pp_handle, const char *p_name, rtos_task_function_t p_routine, + void *p_param, uint16_t stack_size_in_byte, uint16_t priority); + +/** + * @brief Delete os level task routine. + * @param p_handle: Task handle. If a null pointer is passed, the task itself is deleted. + * @retval return SUCCESS Only + */ +int rtos_task_delete(rtos_task_t p_handle); + +/** + * @brief Suspend os level task routine. + * @param p_handle: Task handle. + * @retval return SUCCESS Only + */ +int rtos_task_suspend(rtos_task_t p_handle); + +/** + * @brief Resume os level task routine. + * @param p_handle: Task handle. + * @retval return SUCCESS Only + */ +int rtos_task_resume(rtos_task_t p_handle); + +/** + * @brief Yield current os level task routine. + * @retval return SUCCESS Only + */ +int rtos_task_yield(void); + +/** + * @brief Get current os level task routine handle. + * @retval The task handle pointer + */ +rtos_task_t rtos_task_handle_get(void); + +/** + * @brief Get os level task routine priority. + * @param p_handle: Task handle. + * @retval Task priority value + */ +uint32_t rtos_task_priority_get(rtos_task_t p_handle); + +/** + * @brief Set os level task routine priority. + * @param p_handle: Task handle. + * @param priority: The priority at which the task should run (higher value, higher priority) + * @retval return SUCCESS Only + */ +int rtos_task_priority_set(rtos_task_t p_handle, uint16_t priority); + +/** + * @brief Print current task status + */ +void rtos_task_out_current_status(void); + +/** + * @brief Allocate a secure context for the task. + * @note trustzone is required. Otherwise it's just an empty implementation. + */ +void rtos_create_secure_context(uint32_t size); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_time.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_time.h new file mode 100644 index 0000000000000..4c08f10f0d88b --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_time.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_TIME_H__ +#define __OS_WRAPPER_TIME_H__ + +#define RTOS_TICK_RATE_HZ 1000UL +#define RTOS_TICK_RATE_MS (1000UL / RTOS_TICK_RATE_HZ) + +#define RTOS_TIME_GET_PASSING_TIME_MS(start) (rtos_time_get_current_system_time_ms() - (start)) + +#define RTOS_TIME_GET_TIME_INTERVAL_MS(start, end) ((end) - (start)) +#define RTOS_TIME_SET_MS_TO_SYSTIME(time) (time / RTOS_TICK_RATE_MS) + +/** + * @brief If the current system is in a scheduling and non-interrupted state, it will switch to + * other tasks. Otherwise, the nop instruction will be executed. + * @param ms: Delay time in milliseconds + */ +void rtos_time_delay_ms(uint32_t ms); + +/** + * @brief The system will execute the nop instruction without scheduling. + * @param us: Delay time in microseconds + */ +void rtos_time_delay_us(uint32_t us); + +/** + * @brief Get the count of ticks since rtos_sched_start was called, and convert the return value to + * milliseconds. + * @note This interface does not consider systick overflow issues. + */ +uint32_t rtos_time_get_current_system_time_ms(void); + +/** + * @brief Return value to in microseconds. + * @note This interface does not consider systick overflow issues. + */ +uint64_t rtos_time_get_current_system_time_us(void); + +/** + * @brief Return value to in nanoseconds. + * @note This interface does not consider systick overflow issues. The accuracy is the clk + * frequency of the CPU + */ +uint64_t rtos_time_get_current_system_time_ns(void); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_timer.h b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_timer.h new file mode 100644 index 0000000000000..3485619c15291 --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/os_wrapper_timer.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_TIMER_H__ +#define __OS_WRAPPER_TIMER_H__ + +#define RTOS_TIMER_MAX_DELAY 0xFFFFFFFFUL + +/** + * @brief timer handle type + */ +typedef void *rtos_timer_t; + +/** + * @brief Static memory allocation implementation of rtos_timer_create + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param p_timer_name: A descriptive name for the timer. + * @param timer_id: An identifier that is assigned to the timer being created. Typically this would + * be used in the timer callback function to identify which timer expired when the same callback + * function is assigned to more than one timer. + * @param interval_ms: The timer period in milliseconds. + * @param reload: Used to set the timer as a periodic or one-shot timer. + * @param p_timer_callback: The function to call when the timer expires. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_create_static(rtos_timer_t *pp_handle, const char *p_timer_name, uint32_t timer_id, + uint32_t interval_ms, uint8_t reload, + void (*p_timer_callback)(void *)); + +/** + * @brief Static memory allocation implementation of rtos_timer_delete + * @param p_handle: The handle of the timer being deleted. + * @param wait_ms: Specifies the time that the calling task should be held in the Blocked state + * to wait for the delete command to be successfully sent to the timer command + * queue. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_delete_static(rtos_timer_t p_handle, uint32_t wait_ms); + +/** + * @brief Create a new software timer instance. This allocates the storage required by the new + * timer, initializes the new timers internal state, and returns a handle by which the new timer can + * be referenced. + * @note Usage example: + * Create: + * rtos_timer_t timer_handle; + * rtos_timer_create(&timer_handle, "timer_test", timer_id, delay_ms, is_reload, + * timer_cb_function); Start: rtos_timer_start(timer_handle, wait_ms); Stop: + * rtos_timer_stop(timer_handle, wait_ms); + * Delete: + * rtos_timer_delete(timer_handle, wait_ms); + * @param pp_handle: The handle itself is a pointer, and the pp_handle means a pointer to the + * handle. + * @param p_timer_name: A descriptive name for the timer. + * @param timer_id: An identifier that is assigned to the timer being created. Typically this would + * be used in the timer callback function to identify which timer expired when the same callback + * function is assigned to more than one timer. + * @param interval_ms: The timer period in milliseconds. + * @param reload: Used to set the timer as a periodic or one-shot timer. + * @param p_timer_callback: The function to call when the timer expires. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_create(rtos_timer_t *pp_handle, const char *p_timer_name, uint32_t timer_id, + uint32_t interval_ms, uint8_t reload, void (*p_timer_callback)(void *)); + +/** + * @brief Delete a timer that was previously created using a call to rtos_timer_create. + * @param p_handle: The handle of the timer being deleted. + * @param wait_ms: Specifies the time that the calling task should be held in the Blocked state + * to wait for the delete command to be successfully sent to the timer command + * queue. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_delete(rtos_timer_t p_handle, uint32_t wait_ms); + +/** + * @brief Start a timer that was previously created using a call to rtos_timer_create. + * @param p_handle: The handle of the created timer + * @param wait_ms: Specifies the time that the calling task should be held in the Blocked state + * to wait for the start command to be successfully sent to the timer command + * queue. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_start(rtos_timer_t p_handle, uint32_t wait_ms); + +/** + * @brief Stopping a timer ensures the timer is not in the active state. + * @param p_handle: The handle of the created timer + * @param wait_ms: Specifies the time that the calling task should be held in the Blocked state + * to wait for the stop command to be successfully sent to the timer command queue. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_stop(rtos_timer_t p_handle, uint32_t wait_ms); + +/** + * @brief changes the period of a timer that was previously created using a call to + * rtos_timer_create. + * @param p_handle: The handle of the created timer + * @param interval_ms: The new period for xTimer. + * @param wait_ms: Specifies the time that the calling task should be held in the Blocked state + * to wait for the change command to be successfully sent to the timer command + * queue. + * @retval The status is SUCCESS or FAIL + */ +int rtos_timer_change_period(rtos_timer_t p_handle, uint32_t interval_ms, uint32_t wait_ms); + +/** + * @brief Queries a timer to see if it is active or dormant. A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * @note non-interrupt safety + * @param p_handle: The handle of the created timer + * @retval Timer is active or not. + */ +uint32_t rtos_timer_is_timer_active(rtos_timer_t p_handle); + +/** + * @brief Get the ID assigned to the timer when created. + * @note non-interrupt safety + * @param p_handle: Pointer to the created timer handle. + * @retval the ID assigned to the timer. + */ +uint32_t rtos_timer_get_id(rtos_timer_t p_handle); + +#endif diff --git a/soc/realtek/ameba/common/os_wrapper/include/platform_stdlib.h b/soc/realtek/ameba/common/os_wrapper/include/platform_stdlib.h new file mode 100644 index 0000000000000..84f34943284ba --- /dev/null +++ b/soc/realtek/ameba/common/os_wrapper/include/platform_stdlib.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __PLATFORM_STDLIB_H__ +#define __PLATFORM_STDLIB_H__ + +#include +#include +#include +#include +#include /* va_list */ + +#endif diff --git a/soc/realtek/ameba/soc.yml b/soc/realtek/ameba/soc.yml new file mode 100644 index 0000000000000..025cab1713461 --- /dev/null +++ b/soc/realtek/ameba/soc.yml @@ -0,0 +1,4 @@ +family: +- name: realtek_ameba + socs: + - name: amebadplus From 52a1f61bc43c9f23c8d120e4068885bba744001f Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 14:19:40 +0800 Subject: [PATCH 4/8] drivers: pinctrl: add amebadplus pin controller driver add amebadplus pin controller driver Signed-off-by: zjian zhang --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.ameba | 9 ++ drivers/pinctrl/pinctrl_ameba.c | 85 +++++++++++++++ .../pinctrl/realtek,ameba-pinctrl.yaml | 88 +++++++++++++++ .../dt-bindings/pinctrl/amebadplus-pinctrl.h | 101 ++++++++++++++++++ soc/realtek/ameba/common/pinctrl_soc.h | 54 ++++++++++ 7 files changed, 339 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.ameba create mode 100644 drivers/pinctrl/pinctrl_ameba.c create mode 100644 dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h create mode 100644 soc/realtek/ameba/common/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 839c288c394ef..9ed8e033b54c5 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -45,6 +45,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_AMEBA pinctrl_ameba.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCI_IO_MUX pinctrl_mci_io_mux.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ENE_KB1200 pinctrl_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e13c4e427ff71..13a2d4c6b0368 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -72,6 +72,7 @@ source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" +source "drivers/pinctrl/Kconfig.ameba" source "drivers/pinctrl/Kconfig.mci_io_mux" source "drivers/pinctrl/Kconfig.ene" source "drivers/pinctrl/Kconfig.zynqmp" diff --git a/drivers/pinctrl/Kconfig.ameba b/drivers/pinctrl/Kconfig.ameba new file mode 100644 index 0000000000000..3a168ee8467d0 --- /dev/null +++ b/drivers/pinctrl/Kconfig.ameba @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_AMEBA + bool "Pin controller driver for Realtek Ameba series SoC" + default y + depends on DT_HAS_REALTEK_AMEBA_PINCTRL_ENABLED + help + Enable pin controller driver for Realtek Ameba series SoC diff --git a/drivers/pinctrl/pinctrl_ameba.c b/drivers/pinctrl/pinctrl_ameba.c new file mode 100644 index 0000000000000..6ecb09efdd64e --- /dev/null +++ b/drivers/pinctrl/pinctrl_ameba.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include + +#define AMEBA_GET_PORT_NUM(pin_mux) ((pin_mux >> 13) & 0x03) +#define AMEBA_GET_PIN_NUM(pin_mux) ((pin_mux >> 8) & 0x1f) +#define AMEBA_GET_PIMNUX_ID(pin_mux) (pin_mux & 0xFF) + +#define AMEBA_GPIO_PINNAME(PORT, PIN) (((PORT) << 5) | ((PIN) & 0x1F)) + +static int ameba_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t port_idx, pin_idx; + uint8_t gpio_pin; + uint32_t function_id; + + port_idx = AMEBA_GET_PORT_NUM(pin->pinmux); + pin_idx = AMEBA_GET_PIN_NUM(pin->pinmux); + function_id = AMEBA_GET_PIMNUX_ID(pin->pinmux); + gpio_pin = AMEBA_GPIO_PINNAME(port_idx, pin_idx); + + Pinmux_Config(gpio_pin, function_id); + + if (pin->pull_up) { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_UP); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_UP); + } else if (pin->pull_down) { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_DOWN); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_DOWN); + } else { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_NOPULL); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_NOPULL); + } + + /* default slew rate fast */ + if (pin->slew_rate_slow) { + PAD_SlewRateCtrl(gpio_pin, PAD_SlewRate_Slow); + } + + /* Set the PAD driving strength to PAD_DRV_ABILITITY_LOW, default PAD_DRV_ABILITITY_HIGH */ + if (pin->drive_strength_low) { + PAD_DrvStrength(gpio_pin, PAD_DRV_ABILITITY_LOW); + } + + /* default enable digital path input. */ + if (pin->digital_input_disable) { + PAD_InputCtrl(gpio_pin, DISABLE); + } + + /* default enable schmitt */ + if (pin->schmitt_disable) { + PAD_SchmitCtrl(gpio_pin, DISABLE); + } + + if (pin->swd_off) { + Pinmux_Swdoff(); + } + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + int ret = 0; + + ARG_UNUSED(reg); + + for (int i = 0; i < pin_cnt; i++) { + ret = ameba_configure_pin(&pins[i]); + + if (ret < 0) { + return ret; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml b/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml new file mode 100644 index 0000000000000..bf9d285b88689 --- /dev/null +++ b/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml @@ -0,0 +1,88 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Realtek Ameba pinctrl is a singleton node responsible for controlling pin function selection + and pin properties. For example, you can use this node to route UART0 TX to pin PB_17 + and enable the pull-up resistor on the pin. + + All device pin configurations should be placed in child nodes of the 'pinctrl' node, + as shown in this example: + /* put this example in places like a board-pinctrl.dtsi file in your board directory, + * or a devicetree overlay in your application. + */ + &pinctrl { + /* configuration for uart0 device, default state */ + uart0_default: uart0_default { + /* 'group1' name is arbitrary, if pin's settings are not same, + * add other group like group2 {} + */ + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; + }; + + The 'uart0_default' child node encodes the pin configurations for a particular state of a device; + in this case, the default (that is, active) state. You would specify the low-power configuration + for the same device in a separate child node. + + As shown, pin configurations are organized in groups within each child node. Each group can + specify a list of pin function selections in the 'pinmux' property. The AMEBA_PINMUX macro is + used to specify a pin function selection and pin configuration. You could choose pinmux specified + function to specified pin. And you could configure driver direction, driver state and pull state + for the specified pad. + + To link this pin configuration with a device, use a pinctrl-N property for some number N, + like this example you could place in your board's DTS file: + &uart0 { + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; + }; + +compatible: "realtek,ameba-pinctrl" + +include: base.yaml + +properties: + reg: + required: true +child-binding: + description: | + Realtek Ameba pin controller pin group for a pinctrl state. + child-binding: + description: | + Realtek Ameba pin controller pin configuration node. + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - input-schmitt-disable + properties: + pinmux: + required: true + type: array + description: | + Pin mux selections for this group. An array of pins sharing the same group properties. + Each element of the array is an integer constructed from the pin number and + the alternative function of the pin. + slew-rate-slow: + type: boolean + description: | + Pin output slew rate.If not set, default value is fast. + drive-strength-low: + type: boolean + description: | + Drive strength of the output pin.If not set, default ability is high. + digital-input-disable: + type: boolean + description: | + Disable the digital input function. + swd-off: + type: boolean + description: | + Disable the SWD function. diff --git a/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h new file mode 100644 index 0000000000000..0d7f535e71cb3 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ + +/* PINMUX Function definitions */ +#define AMEBA_GPIO 0 +#define AMEBA_LOG_UART 1 +#define AMEBA_UART 1 +#define AMEBA_SPIC0_FLASH 2 +#define AMEBA_SPIC1_FLASH 3 +#define AMEBA_SPIC1_PSRAM 4 +#define AMEBA_OSPI 5 +#define AMEBA_QSPI 5 +#define AMEBA_ADC 6 +#define AMEBA_CAP_TOUCH 6 +#define AMEBA_SIC 7 +#define AMEBA_SPI 8 +#define AMEBA_SWD 9 +#define AMEBA_SDIO 10 +#define AMEBA_ANT_DIV 11 +#define AMEBA_EXT_BT 12 +#define AMEBA_BT_IO 13 +#define AMEBA_BT 14 +#define AMEBA_EXT_ZIGBEE 15 +#define AMEBA_TIMER 16 +#define AMEBA_USB 17 +#define AMEBA_DEBUG 18 +#define AMEBA_UART0_TXD 19 +#define AMEBA_UART0_RXD 20 +#define AMEBA_UART0_CTS 21 +#define AMEBA_UART0_RTS 22 +#define AMEBA_UART1_TXD 23 +#define AMEBA_UART1_RXD 24 +#define AMEBA_UART2_TXD 25 +#define AMEBA_UART2_RXD 26 +#define AMEBA_UART2_CTS 27 +#define AMEBA_UART2_RTS 28 +#define AMEBA_SPI1_CLK 29 +#define AMEBA_SPI1_MISO 30 +#define AMEBA_SPI1_MOSI 31 +#define AMEBA_SPI1_CS 32 +#define AMEBA_LEDC 33 +#define AMEBA_I2S0_MCLK 34 +#define AMEBA_I2S0_BCLK 35 +#define AMEBA_I2S0_WS 36 +#define AMEBA_I2S0_DIO0 37 +#define AMEBA_I2S0_DIO1 38 +#define AMEBA_I2S0_DIO2 39 +#define AMEBA_I2S0_DIO3 40 +#define AMEBA_I2S1_MCLK 41 +#define AMEBA_I2S1_BCLK 42 +#define AMEBA_I2S1_WS 43 +#define AMEBA_I2S1_DIO0 44 +#define AMEBA_I2S1_DIO1 45 +#define AMEBA_I2S1_DIO2 46 +#define AMEBA_I2S1_DIO3 47 +#define AMEBA_I2C0_SCL 48 +#define AMEBA_I2C0_SDA 49 +#define AMEBA_I2C1_SCL 50 +#define AMEBA_I2C1_SDA 51 +#define AMEBA_PWM0 52 +#define AMEBA_PWM1 53 +#define AMEBA_PWM2 54 +#define AMEBA_PWM3 55 +#define AMEBA_PWM4 56 +#define AMEBA_PWM5 57 +#define AMEBA_PWM6 58 +#define AMEBA_PWM7 59 +#define AMEBA_BT_UART_TXD 60 +#define AMEBA_BT_UART_RTS 61 +#define AMEBA_DMIC_CLK 62 +#define AMEBA_DMIC_DATA 63 +#define AMEBA_IR_TX 64 +#define AMEBA_IR_RX 65 +#define AMEBA_KEY_ROW0 66 +#define AMEBA_KEY_ROW1 67 +#define AMEBA_KEY_ROW2 68 +#define AMEBA_KEY_ROW3 69 +#define AMEBA_KEY_ROW4 70 +#define AMEBA_KEY_ROW5 71 +#define AMEBA_KEY_ROW6 72 +#define AMEBA_KEY_ROW7 73 +#define AMEBA_KEY_COL0 74 +#define AMEBA_KEY_COL1 75 +#define AMEBA_KEY_COL2 76 +#define AMEBA_KEY_COL3 77 +#define AMEBA_KEY_COL4 78 +#define AMEBA_KEY_COL5 79 +#define AMEBA_KEY_COL6 80 +#define AMEBA_KEY_COL7 81 + +/* Define pins number: bit[14:13] port, bit[12:8] pin, bit[7:0] function ID */ +#define AMEBA_PORT_PIN(port, line) ((((port) - 'A') << 5) + (line)) +#define AMEBA_PINMUX(port, line, funcid) (((AMEBA_PORT_PIN(port, line)) << 8) | (funcid)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ */ diff --git a/soc/realtek/ameba/common/pinctrl_soc.h b/soc/realtek/ameba/common/pinctrl_soc.h new file mode 100644 index 0000000000000..52bd8aab63ad0 --- /dev/null +++ b/soc/realtek/ameba/common/pinctrl_soc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_COMMON_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pin { + uint32_t pinmux: 15; + /* bit[14:13] port + * bit[12:8] pin + * bit[7:0] function ID + */ + uint32_t pull_down: 1; + uint32_t pull_up: 1; + uint32_t schmitt_disable: 1; + uint32_t slew_rate_slow: 1; + uint32_t drive_strength_low: 1; + uint32_t digital_input_disable: 1; + uint32_t swd_off: 1; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .pinmux = DT_PROP_BY_IDX(node_id, prop, idx), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .schmitt_disable = DT_PROP(node_id, input_schmitt_disable), \ + .slew_rate_slow = DT_PROP(node_id, slew_rate_slow), \ + .drive_strength_low = DT_PROP(node_id, drive_strength_low), \ + .digital_input_disable = DT_PROP(node_id, digital_input_disable), \ + .swd_off = DT_PROP(node_id, swd_off), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_COMMON_PINCTRL_SOC_H_ */ From c4cd77ec271703cbac51b1d02876fc6cd7093bc8 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 16:03:32 +0800 Subject: [PATCH 5/8] drivers: serial: add amebadplus loguart driver loguart driver for amebadplus Signed-off-by: zjian zhang --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.ameba_loguart | 10 + drivers/serial/uart_ameba_loguart.c | 327 ++++++++++++++++++ .../serial/realtek,ameba-loguart.yaml | 16 + 5 files changed, 355 insertions(+) create mode 100644 drivers/serial/Kconfig.ameba_loguart create mode 100644 drivers/serial/uart_ameba_loguart.c create mode 100644 dts/bindings/serial/realtek,ameba-loguart.yaml diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 9881217d5b009..916b0d475e297 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_AESC uart_aesc.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA uart_altera.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag.c) zephyr_library_sources_ifdef(CONFIG_UART_AMBIQ uart_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_UART_AMEBA_LOGUART uart_ameba_loguart.c) zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_BFLB uart_bflb.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ea3fbed123bac..82162de6795ec 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -161,6 +161,7 @@ rsource "Kconfig.aesc" rsource "Kconfig.altera" rsource "Kconfig.altera_jtag" rsource "Kconfig.ambiq" +rsource "Kconfig.ameba_loguart" rsource "Kconfig.apbuart" rsource "Kconfig.b91" rsource "Kconfig.bcm2711" diff --git a/drivers/serial/Kconfig.ameba_loguart b/drivers/serial/Kconfig.ameba_loguart new file mode 100644 index 0000000000000..93fb92c38738a --- /dev/null +++ b/drivers/serial/Kconfig.ameba_loguart @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config UART_AMEBA_LOGUART + bool "Ameba LOGUART driver" + default y + depends on DT_HAS_REALTEK_AMEBA_LOGUART_ENABLED + select SERIAL_HAS_DRIVER + help + This option enables the LOGUART driver for Realtek Ameba SoCs. diff --git a/drivers/serial/uart_ameba_loguart.c b/drivers/serial/uart_ameba_loguart.c new file mode 100644 index 0000000000000..b0124cf0f5193 --- /dev/null +++ b/drivers/serial/uart_ameba_loguart.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Realtek Ameba LOGUART + */ + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(loguart_ameba, CONFIG_UART_LOG_LEVEL); + +/* + * Extract information from devicetree. + * + * This driver only supports one instance of this IP block, so the + * instance number is always 0. + */ +#define DT_DRV_COMPAT realtek_ameba_loguart + +/* Device config structure */ +struct loguart_ameba_config { +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + uart_irq_config_func_t irq_config_func; +#endif +}; + +/* Device data structure */ +struct loguart_ameba_data { + struct uart_config config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t user_cb; + void *user_data; + bool tx_int_en; + bool rx_int_en; +#endif +}; + +/** + * @brief Poll the device for input. + * + * @param dev UART device struct + * @param c Pointer to character + * + * @return 0 if a character arrived, -1 if the input buffer if empty. + */ +static int loguart_ameba_poll_in(const struct device *dev, unsigned char *c) +{ + ARG_UNUSED(dev); + + if (!LOGUART_Readable()) { + return -1; + } + + *c = LOGUART_GetChar(false); + return 0; +} + +/** + * @brief Output a character in polled mode. + * + * @param dev UART device struct + * @param c Character to send + */ +static void loguart_ameba_poll_out(const struct device *dev, unsigned char c) +{ + ARG_UNUSED(dev); + LOGUART_PutChar(c); +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int loguart_ameba_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) +{ + ARG_UNUSED(dev); + + uint8_t num_tx = 0U; + unsigned int key; + + if (!LOGUART_Writable()) { + return num_tx; + } + + /* Lock interrupts to prevent nested interrupts or thread switch */ + + key = irq_lock(); + + while ((len - num_tx > 0) && LOGUART_Writable()) { + LOGUART_PutChar((uint8_t)tx_data[num_tx++]); + } + + irq_unlock(key); + + return num_tx; +} + +static int loguart_ameba_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + ARG_UNUSED(dev); + + uint8_t num_rx = 0U; + + while ((size - num_rx > 0) && LOGUART_Readable()) { + rx_data[num_rx++] = LOGUART_GetChar(false); + } + + /* Clear timeout int flag */ + if (LOGUART_GetStatus(LOGUART_DEV) & LOGUART_BIT_TIMEOUT_INT) { + LOGUART_INTClear(LOGUART_DEV, LOGUART_BIT_TOICF); + } + + return num_rx; +} + +static void loguart_ameba_irq_tx_enable(const struct device *dev) +{ + u32 sts; + struct loguart_ameba_data *data = dev->data; + + /* Disable IRQ Interrupts and Save Previous Status. */ + sts = irq_disable_save(); + + data->tx_int_en = true; + /* KM4: TX_PATH1 */ + LOGUART_INTConfig(LOGUART_DEV, LOGUART_TX_EMPTY_PATH_1_INTR, ENABLE); + + /* Enable IRQ Interrupts according to Previous Status. */ + irq_enable_restore(sts); +} + +static void loguart_ameba_irq_tx_disable(const struct device *dev) +{ + u32 sts; + struct loguart_ameba_data *data = dev->data; + + /* Disable IRQ Interrupts and Save Previous Status. */ + sts = irq_disable_save(); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_TX_EMPTY_PATH_1_INTR, DISABLE); + data->tx_int_en = false; + + /* Enable IRQ Interrupts according to Previous Status. */ + irq_enable_restore(sts); +} + +static int loguart_ameba_irq_tx_ready(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + /* KM4: TX_PATH1 */ + return (LOGUART_GetStatus(LOGUART_DEV) & LOGUART_BIT_TP1F_EMPTY) && data->tx_int_en; +} + +static int loguart_ameba_irq_tx_complete(const struct device *dev) +{ + return loguart_ameba_irq_tx_ready(dev); +} + +static void loguart_ameba_irq_rx_enable(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + data->rx_int_en = true; + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ERBI | LOGUART_BIT_ETOI, ENABLE); +} + +static void loguart_ameba_irq_rx_disable(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + data->rx_int_en = false; + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ERBI | LOGUART_BIT_ETOI, DISABLE); +} + +static int loguart_ameba_irq_rx_ready(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + return (LOGUART_GetStatus(LOGUART_DEV) & + (LOGUART_BIT_DRDY | LOGUART_BIT_RXFIFO_INT | LOGUART_BIT_TIMEOUT_INT)) && + data->rx_int_en; +} + +static void loguart_ameba_irq_err_enable(const struct device *dev) +{ + ARG_UNUSED(dev); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ELSI, ENABLE); +} + +static void loguart_ameba_irq_err_disable(const struct device *dev) +{ + ARG_UNUSED(dev); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ELSI, DISABLE); +} + +static int loguart_ameba_irq_is_pending(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + return ((LOGUART_GetStatus(LOGUART_DEV) & LOGUART_BIT_TP1F_EMPTY) && data->tx_int_en) || + ((LOGUART_GetStatus(LOGUART_DEV) & + (LOGUART_BIT_DRDY | LOGUART_BIT_RXFIFO_INT | LOGUART_BIT_TIMEOUT_INT)) && + data->rx_int_en); +} + +static int loguart_ameba_irq_update(const struct device *dev) +{ + return 1; +} + +static void loguart_ameba_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, void *cb_data) +{ + struct loguart_ameba_data *data = dev->data; + + data->user_cb = cb; + data->user_data = cb_data; +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +/** + * @brief Initialize UART channel + * + * This routine is called to reset the chip in a quiescent state. + * It is assumed that this function is called only once per UART. + * + * @param dev UART device struct + * + * @return 0 on success + */ +static int loguart_ameba_init(const struct device *dev) +{ + LOGUART_RxCmd(LOGUART_DEV, DISABLE); + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM0, DISABLE); + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM4, ENABLE); + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + const struct loguart_ameba_config *config = dev->config; + + config->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + LOGUART_RxCmd(LOGUART_DEV, ENABLE); + + return 0; +} + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#define AMEBA_LOGUART_IRQ_HANDLER_DECL \ + static void loguart_ameba_irq_config_func(const struct device *dev); +#define AMEBA_LOGUART_IRQ_HANDLER \ + static void loguart_ameba_irq_config_func(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), loguart_ameba_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQN(0)); \ + } +#define AMEBA_LOGUART_IRQ_HANDLER_FUNC .irq_config_func = loguart_ameba_irq_config_func, +#else +#define AMEBA_LOGUART_IRQ_HANDLER_DECL /* Not used */ +#define AMEBA_LOGUART_IRQ_HANDLER /* Not used */ +#define AMEBA_LOGUART_IRQ_HANDLER_FUNC /* Not used */ +#endif + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + +static void loguart_ameba_isr(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + if (data->user_cb) { + data->user_cb(dev, data->user_data); + } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api loguart_ameba_driver_api = { + .poll_in = loguart_ameba_poll_in, + .poll_out = loguart_ameba_poll_out, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = loguart_ameba_fifo_fill, + .fifo_read = loguart_ameba_fifo_read, + .irq_tx_enable = loguart_ameba_irq_tx_enable, + .irq_tx_disable = loguart_ameba_irq_tx_disable, + .irq_tx_ready = loguart_ameba_irq_tx_ready, + .irq_rx_enable = loguart_ameba_irq_rx_enable, + .irq_rx_disable = loguart_ameba_irq_rx_disable, + .irq_tx_complete = loguart_ameba_irq_tx_complete, + .irq_rx_ready = loguart_ameba_irq_rx_ready, + .irq_err_enable = loguart_ameba_irq_err_enable, + .irq_err_disable = loguart_ameba_irq_err_disable, + .irq_is_pending = loguart_ameba_irq_is_pending, + .irq_update = loguart_ameba_irq_update, + .irq_callback_set = loguart_ameba_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +AMEBA_LOGUART_IRQ_HANDLER_DECL +AMEBA_LOGUART_IRQ_HANDLER + +static const struct loguart_ameba_config loguart_config = {AMEBA_LOGUART_IRQ_HANDLER_FUNC}; + +static struct loguart_ameba_data loguart_data = {.config = { + .stop_bits = UART_CFG_STOP_BITS_1, + .data_bits = UART_CFG_DATA_BITS_8, + .baudrate = DT_INST_PROP(0, current_speed), + .parity = UART_CFG_PARITY_NONE, + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, + }}; + +DEVICE_DT_INST_DEFINE(0, loguart_ameba_init, NULL, &loguart_data, &loguart_config, PRE_KERNEL_1, + CONFIG_SERIAL_INIT_PRIORITY, &loguart_ameba_driver_api); diff --git a/dts/bindings/serial/realtek,ameba-loguart.yaml b/dts/bindings/serial/realtek,ameba-loguart.yaml new file mode 100644 index 0000000000000..68926503fc74a --- /dev/null +++ b/dts/bindings/serial/realtek,ameba-loguart.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: Ameba LOGUART +compatible: "realtek,ameba-loguart" + +include: [uart-controller.yaml, base.yaml, pinctrl-device.yaml] + +bus: uart + +properties: + reg: + required: true + + interrupts: + required: true From 2d9ed529d5d205648a2a55b4511f328f0367d0c9 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 17:51:08 +0800 Subject: [PATCH 6/8] drivers: gpio: add amebadplus gpio driver GPIO driver for amebadplus Signed-off-by: zjian zhang --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.ameba | 18 ++ drivers/gpio/gpio_ameba.c | 291 ++++++++++++++++++++++ dts/bindings/gpio/realtek,ameba-gpio.yaml | 22 ++ 5 files changed, 334 insertions(+) create mode 100644 drivers/gpio/Kconfig.ameba create mode 100644 drivers/gpio/gpio_ameba.c create mode 100644 dts/bindings/gpio/realtek,ameba-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 728a883e1093c..66311e543ac52 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_ADP5585 gpio_adp5585.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ADS1X4S0X gpio_ads1x4s0x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AMBIQ gpio_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_AMEBA gpio_ameba.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ANDES_ATCGPIO100 gpio_andes_atcgpio100.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AW9523B gpio_aw9523b.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AXP192 gpio_axp192.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e95aded5613a8..9339808d0f630 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -202,4 +202,6 @@ source "drivers/gpio/Kconfig.xlnx_ps" source "drivers/gpio/Kconfig.xmc4xxx" # zephyr-keep-sorted-stop +source "drivers/gpio/Kconfig.ameba" + endif # GPIO diff --git a/drivers/gpio/Kconfig.ameba b/drivers/gpio/Kconfig.ameba new file mode 100644 index 0000000000000..58a27a8f039bf --- /dev/null +++ b/drivers/gpio/Kconfig.ameba @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_AMEBA + bool "GPIO controller driver for Realtek Ameba series SoC" + default y + depends on DT_HAS_REALTEK_AMEBA_GPIO_ENABLED + help + Enable GPIO controller driver for Realtek Ameba series SoC + +config GPIO_DEBOUNCE_EN + bool "Ameba GPIO Interrupt Debounce Enable" + depends on GPIO_AMEBA + default y + help + When Enable GPIO Interrupt Debounce, the external signal can be debounced to + remove any spurious glitches that are less than one period(about 32us) of + the external debouncing clock. diff --git a/drivers/gpio/gpio_ameba.c b/drivers/gpio/gpio_ameba.c new file mode 100644 index 0000000000000..788d501da4140 --- /dev/null +++ b/drivers/gpio/gpio_ameba.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT realtek_ameba_gpio + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(gpio_ameba, CONFIG_GPIO_LOG_LEVEL); + +#define GPIO_PINNAME(PORT, PIN) (((PORT) << 5) | ((PIN) & 0x1F)) + +struct gpio_ameba_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + /* port base address */ + uint32_t base; + /* IO port */ + int port; +}; + +struct gpio_ameba_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +static int gpio_ameba_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_ameba_config *cfg = dev->config; + + *value = GPIO_PortRead(cfg->port, cfg->common.port_pin_mask); + + return 0; +} + +static int gpio_ameba_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortDirection(cfg->port, mask, GPIO_Mode_OUT); + GPIO_PortWrite(cfg->port, mask, value); + + return 0; +} + +static int gpio_ameba_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortWrite(cfg->port, mask, cfg->common.port_pin_mask); + + return 0; +} + +static int gpio_ameba_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortWrite(cfg->port, mask, 0); + + return 0; +} + +static int gpio_ameba_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + u32 gpio_pin; + u32 value; + uint8_t i; + + for (i = 0; i < 32; i++) { + if (mask & 0x1) { + gpio_pin = GPIO_PINNAME(cfg->port, i); + value = GPIO_ReadDataBit(gpio_pin); + GPIO_WriteBit(gpio_pin, (~value) & 0x1); + } + mask >>= 1; + if (mask == 0) { + break; + } + } + + return 0; +} + +static int gpio_ameba_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_InitTypeDef gpio_initstruct; + u32 gpio_pin; + + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; + } + + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == 0) { + return -ENOTSUP; + } + + gpio_pin = GPIO_PINNAME(cfg->port, pin); + gpio_initstruct.GPIO_Pin = gpio_pin; + + if (flags & GPIO_INPUT) { + gpio_initstruct.GPIO_Mode = GPIO_Mode_IN; + } else { + gpio_initstruct.GPIO_Mode = GPIO_Mode_OUT; + } + + if (flags & GPIO_PULL_UP) { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_UP; + } else if (flags & GPIO_PULL_DOWN) { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_DOWN; + } else { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + } + + GPIO_Init(&gpio_initstruct); + + if (flags & GPIO_OUTPUT) { + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + gpio_ameba_port_set_bits_raw(dev, BIT(pin)); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + gpio_ameba_port_clear_bits_raw(dev, BIT(pin)); + } + } + + return 0; +} + +static int gpio_ameba_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_ameba_config *cfg = dev->config; + u32 gpio_pin; + + gpio_pin = GPIO_PINNAME(cfg->port, pin); + GPIO_InitTypeDef gpio_initstruct; + + gpio_initstruct.GPIO_Pin = gpio_pin; + + GPIO_INTConfig(gpio_pin, DISABLE); + + LOG_DBG("Config GPIO int:%d-%d, mode:%x, flag:0x%x\n", cfg->port, pin, mode, trig); + gpio_initstruct.GPIO_Pin = gpio_pin; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_initstruct.GPIO_Mode = GPIO_Mode_INT; + gpio_initstruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_DISABLE; + + if (mode != GPIO_INT_MODE_DISABLED) { + if (mode & GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + break; + case GPIO_INT_TRIG_HIGH: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH; + break; + case GPIO_INT_TRIG_BOTH: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_BOTHEDGE; + break; + default: + LOG_ERR("GPIO Edge interrupt type invalid \r\n"); + return -ENOTSUP; + } + } else { + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL; + switch (trig) { + case GPIO_INT_TRIG_LOW: + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_UP; + break; + case GPIO_INT_TRIG_HIGH: + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_DOWN; + break; + default: + LOG_ERR("GPIO level interrupt doesn't support both high and low"); + return -ENOTSUP; + } + } + +#if defined(CONFIG_GPIO_DEBOUNCE_EN) + gpio_initstruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + /* GPIO_DebounceClock(cfg->port, DEBOUNCE_DIV_CNT); */ + GPIO_Init(&gpio_initstruct); + DelayUs(64); + GPIO_INTConfig(gpio_pin, ENABLE); +#else + GPIO_Init(&gpio_initstruct); + GPIO_INTConfig(gpio_pin, ENABLE); +#endif + } else { + GPIO_Direction(gpio_pin, GPIO_Mode_IN); + PAD_PullCtrl(gpio_pin, gpio_initstruct.GPIO_PuPd); + + GPIO_INTMode(gpio_pin, DISABLE, 0, 0, 0); + } + + return 0; +} + +static int gpio_ameba_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_ameba_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static uint32_t gpio_ameba_get_pending_int(const struct device *dev) +{ + uint32_t irq_status; + const struct gpio_ameba_config *cfg = dev->config; + uint32_t port = cfg->port; + + irq_status = GPIO_INTStatusGet(port); + + return irq_status; +} + +static void gpio_ameba_isr(const struct device *dev) +{ + uint32_t int_status; + struct gpio_ameba_data *data = dev->data; + const struct gpio_ameba_config *cfg = dev->config; + uint32_t port = cfg->port; + + /* Get the int status */ + int_status = GPIO_INTStatusGet(port); + + /* Clear pending edge interrupt */ + GPIO_INTStatusClearEdge(port); + + /* Call the registered callbacks */ + gpio_fire_callbacks(&data->callbacks, dev, int_status); +} + +static const struct gpio_driver_api gpio_ameba_driver_api = { + .pin_configure = gpio_ameba_configure, + .port_get_raw = gpio_ameba_port_get_raw, + .port_set_masked_raw = gpio_ameba_port_set_masked_raw, + .port_set_bits_raw = gpio_ameba_port_set_bits_raw, + .port_clear_bits_raw = gpio_ameba_port_clear_bits_raw, + .port_toggle_bits = gpio_ameba_port_toggle_bits, + .pin_interrupt_configure = gpio_ameba_pin_interrupt_configure, + .manage_callback = gpio_ameba_manage_callback, + .get_pending_int = gpio_ameba_get_pending_int, +}; + +#define GPIO_AMEBA_INIT(n) \ + static int gpio_ameba_port##n##_init(const struct device *dev) \ + { \ + const struct gpio_ameba_config *cfg = dev->config; \ + LOG_INF("GPIO%d INIT, IRQ %d\n", cfg->port, DT_INST_IRQN(n)); \ + \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_ameba_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + \ + return 0; \ + } \ + static struct gpio_ameba_data gpio_ameba_port##n##_data; \ + \ + static const struct gpio_ameba_config gpio_ameba_port##n##_config = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .base = DT_INST_REG_ADDR(n), \ + .port = n, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_ameba_port##n##_init, NULL, &gpio_ameba_port##n##_data, \ + &gpio_ameba_port##n##_config, POST_KERNEL, \ + CONFIG_GPIO_INIT_PRIORITY, &gpio_ameba_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_AMEBA_INIT) diff --git a/dts/bindings/gpio/realtek,ameba-gpio.yaml b/dts/bindings/gpio/realtek,ameba-gpio.yaml new file mode 100644 index 0000000000000..4eab82fd2316e --- /dev/null +++ b/dts/bindings/gpio/realtek,ameba-gpio.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: Realtek Ameba GPIO controller + +compatible: "realtek,ameba-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags From f4e0e89cc407c52e0215c7df582fdb8d6800edb2 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Wed, 28 Aug 2024 14:21:51 +0800 Subject: [PATCH 7/8] boards: add rtl872xda_evb board add initial version of rtl872xda_evb board Signed-off-by: zjian zhang --- .../rtl872xda_evb/Kconfig.rtl872xda_evb | 5 ++ boards/realtek/rtl872xda_evb/board.cmake | 6 ++ boards/realtek/rtl872xda_evb/board.yml | 5 ++ boards/realtek/rtl872xda_evb/doc/index.rst | 83 ++++++++++++++++++ .../rtl872xda_evb/doc/rtl872xda_evb.webp | Bin 0 -> 29540 bytes .../rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi | 20 +++++ .../realtek/rtl872xda_evb/rtl872xda_evb.dts | 31 +++++++ .../realtek/rtl872xda_evb/rtl872xda_evb.yaml | 16 ++++ .../rtl872xda_evb/rtl872xda_evb_defconfig | 9 ++ 9 files changed, 175 insertions(+) create mode 100644 boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb create mode 100644 boards/realtek/rtl872xda_evb/board.cmake create mode 100644 boards/realtek/rtl872xda_evb/board.yml create mode 100644 boards/realtek/rtl872xda_evb/doc/index.rst create mode 100644 boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb.dts create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig diff --git a/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb b/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb new file mode 100644 index 0000000000000..38a849f84d0cd --- /dev/null +++ b/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RTL872XDA_EVB + select SOC_AMEBADPLUS diff --git a/boards/realtek/rtl872xda_evb/board.cmake b/boards/realtek/rtl872xda_evb/board.cmake new file mode 100644 index 0000000000000..e63da5e6ab42c --- /dev/null +++ b/boards/realtek/rtl872xda_evb/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=Cortex-M55" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/realtek/rtl872xda_evb/board.yml b/boards/realtek/rtl872xda_evb/board.yml new file mode 100644 index 0000000000000..660e13a6b4b66 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/board.yml @@ -0,0 +1,5 @@ +board: + name: rtl872xda_evb + vendor: realtek + socs: + - name: amebadplus diff --git a/boards/realtek/rtl872xda_evb/doc/index.rst b/boards/realtek/rtl872xda_evb/doc/index.rst new file mode 100644 index 0000000000000..005de839f9859 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/doc/index.rst @@ -0,0 +1,83 @@ +.. zephyr:board:: rtl872xda_evb + +Overview +******** + +The Realtek RTL8721Dx Series is a Combo SoC that supports dual-band Wi-Fi 4 (2.4GHz + 5GHz) and +BLE 5.0 specifications. With excellent ultra-low power consumption, enhanced encryption strategy +(PSA Level 2), and abundant peripheral resources, it is widely used in smart home appliance, +line controller, smart door lock, battery camera, smart remote controller, Wi-Fi Speaker, Wi-Fi +Full MAC NIC, BLE gateway, and smart POS, etc. For more information, check `RTL872XDA-EVB`_. + +The features include the following: + +- Dual cores: Real-M300 and Real-M200 +- 512KB on-chip SRAM +- 802.11 a/b/g/n 1 x 1, 2.4GHz + 5GHz +- Supports BLE 5.0 +- Peripheral Interface: + + - Multi-communication interfaces: SPI x 2, UART x 4, I2C x 2 + - Hardware Key-Scan interface supports up to 8*8 (64) keys + - Hardware IR transceiver can easily adapt to various IR protocols + - Supports Real-Time Clock timer together with 10 basic timers + - Supports 8 channels of PWM timer and 1 capture timer + - Supports 7 channels of general 12-bit ADC and 1 channel of VBAT + - Supports 4 channels of touch pad + - Supports 8 independent channels of GDMA + - Supports USB 2.0 full-speed device mode + - Supports SDIO device with 1-bit and 4-bit mode + - Embeds a serial LEDC to control the external LED lamps + - Integrated Pixel Processing Engine (PPE) to process pixel data faster + - Integrated OSPI display interface supports screens with OSPI/QSPI/SPI interfaces + - Integrated audio codec supports 2 channels DMIC interface + - I2S x 2: up to 384kHz sampling rate + +- Cryptographic hardware acceleration (TRNG, ECC, SHA-2, AES) + +For more information, Get application note and datasheet at `RTL8721Dx Series`_ depending on chip you use. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Building +******** + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rtl872xda_evb + :goals: buil + +Flashing +******** + +When the build finishes, downloading images into flash by `AmebaImageTool`_: + +See the ApplicationNote chapter Image Tool from documentation links for more details. + +#. Environment Requirements: EX. WinXP, Win 7 or later, Microsoft .NET Framework 4.0. +#. Connect chip and PC with USB wire. +#. Choose the Device profiles according to the chip you use. +#. Select the corresponding serial port and transmission baud rate. The default baud rate is 1500000. +#. Select the images to be programmed and set the start address and end address according to the flash layout, refer to [ameba_flashcfg.c/Flash_layout]. +#. Click the Download button and start. The progress bar will show the download progress of each image and the log window will show the operation status. + +.. note:: + + For an empty chip, the bootloader and app image shall be downloaded. + +Debugging +********* + +Using SWD through PA30(SWD_CLK) and PA31(SWD_DAT). + +References +********** + +.. _`RTL872XDA-EVB`: https://www.realmcu.com/en/Home/Product/add965ea-d661-4a63-9514-d18b6912f8ab# +.. _`RTL8721Dx Series`: https://www.realmcu.com +.. _`AmebaImageTool`: https://github.com/Ameba-AIoT/ameba-rtos/blob/master/tools/ameba/ImageTool/AmebaImageTool.exe diff --git a/boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp b/boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp new file mode 100644 index 0000000000000000000000000000000000000000..dff4bf60705bed5f2a5d6d421607db4f1900954e GIT binary patch literal 29540 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 TFu<=giMTcUhNob?XaE2JxxIW$ literal 0 HcmV?d00001 diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi b/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi new file mode 100644 index 0000000000000..20c7c4f919ff4 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + compatible = "realtek,ameba-pinctrl"; + + /* PA30 is SWD_CLK, PA31 is SWD_DAT(both pull-up internally) */ + loguart_default: loguart_default { + group1 { + pinmux = , /* RXD */ + ; /* TXD */ + bias-pull-up; + }; + }; +}; diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts b/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts new file mode 100644 index 0000000000000..61197d1036fbd --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "rtl872xda_evb-pinctrl.dtsi" + +/ { + model = "RealTek AmebaDplus RTL872XDA EVB"; + compatible = "realtek,rtl872xda_evb"; + + chosen { + zephyr,console = &loguart; + zephyr,shell-uart = &loguart; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +/* 4MB flash */ +&flash0 { + reg = <0x0e000020 DT_SIZE_M(4)>; +}; + +&loguart { + status = "okay"; +}; diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml b/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml new file mode 100644 index 0000000000000..64e415c56c30b --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +identifier: rtl872xda_evb +name: Realtek rtl872xda evaluation board +vendor: realtek +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 512 +flash: 4096 +supported: + - pinctrl + - serial diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig b/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig new file mode 100644 index 0000000000000..6e5ed329d4a5c --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable LogUart +CONFIG_SERIAL=y From 8deea8d3916d99d61205a3f16862fb9d637e8ef3 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 16:47:15 +0800 Subject: [PATCH 8/8] MAINTAINERS: Add hal_realtek as a new HAL module This commit adds maintainers for hal_realtek repository Signed-off-by: zjian zhang --- MAINTAINERS.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8d7afd64b6386..de90238cf76e5 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3530,6 +3530,19 @@ Bouffalolab Platforms: labels: - "platform: bouffalolab" +realtek ameba Platforms: + status: maintained + maintainers: + - zjian-zhang + files: + - drivers/*/*ameba* + - boards/realtek/ + - soc/realtek/ + - dts/arm/realtek/ + - dts/bindings/*/*ameba* + labels: + - "platform: ameba" + Broadcom Platforms: status: odd fixes files: @@ -5000,6 +5013,14 @@ West: labels: - "platform: Ambiq" +"West project: hal_realtek": + status: maintained + maintainers: + - zjian-zhang + files: [] + labels: + - "platform: ameba" + "West project: hal_atmel": status: maintained maintainers: