diff --git a/CMakeLists.txt b/CMakeLists.txt index 18df549a..16b411ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,3 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 add_subdirectory_ifdef(CONFIG_SOC_FAMILY_REALTEK_AMEBA ameba) +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_REALTEK_BEE bee) diff --git a/Kconfig b/Kconfig index f1e0dae3..038bb213 100644 --- a/Kconfig +++ b/Kconfig @@ -2,3 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 rsource "ameba/Kconfig" +rsource "bee/Kconfig" diff --git a/README.rst b/README.rst index 609f7b1c..7740d30d 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,35 @@ -Important Information About This Repository -******************************************* -HAL Realtek (or `hal_realtek`) is a collection of tools, low-level APIs, and hardware access functions for Realtek Devices. +Realtek HAL Module (hal_realtek) +################################ -This repository is a copy (not a fork) of the [ameba-rtos repository](https://github.com/Ameba-AIoT/ameba-rtos) that contains Ameba SoCs. +HAL Realtek (or ``hal_realtek``) is a collection of tools, low-level APIs, and hardware access functions for Realtek Devices, enabling support within the Zephyr RTOS ecosystem. -After following the standard Zephyr guide for compilation, both app and bootloader images tailored for Ameba SoCs will be generated. [Refer to this tutorial](https://github.com/Ameba-AIoT/ameba-rtos/) for Flashing these images and running on Ameba SoCs. +Currently, the ``hal_realtek`` repository supports two primary SoC series: **Ameba** and **Bee**. + +Supported SoC Series +******************* + +Ameba Series (ameba) +==================== + +The ``ameba`` directory contains the HAL for Ameba series SoCs. + +This repository is a copy (not a fork) of the `ameba-rtos repository `_ that contains Ameba SoCs. + +After following the standard Zephyr guide for compilation, both app and bootloader images tailored for Ameba SoCs will be generated. Refer to this `tutorial `_ for Flashing these images and running on Ameba SoCs. + +Bee Series (bee) +================ + +The ``bee`` directory hosts the HAL for Bee series SoCs. The sources in this directory are extracted from their respective SDKs: + +* **RTL87x2G**: `rtkconnectivity/rtl87x2g_sdk `_ + +* **RTL8752H**: `rtkconnectivity/rtl8752h_sdk `_ + +Maintenance & Synchronization Strategy +************************************** + +Since the HALs for the **Ameba** and **Bee** series are maintained by different teams within Realtek, and additional SoC series may be added to ``hal_realtek`` in the future, there is no single upstream Git history for this repository. + +Therefore, this module adheres to the **"Updating modules with a diff from upstream"** practice as defined in the `Zephyr Project Documentation `_. \ No newline at end of file diff --git a/ameba/Kconfig b/ameba/Kconfig index a192b6fd..6f611486 100644 --- a/ameba/Kconfig +++ b/ameba/Kconfig @@ -10,5 +10,6 @@ config REALTEK_AMEBA_HAL_LIB This option enables the Realtek Ameba HAL library. rsource "ameba*/Kconfig" +rsource "common/wifi/Kconfig" endif # SOC_FAMILY_REALTEK_AMEBA diff --git a/ameba/amebaG2/source/fwlib/include/ameba_phy.h b/ameba/amebaG2/source/fwlib/include/ameba_phy.h deleted file mode 100644 index c4eb037e..00000000 --- a/ameba/amebaG2/source/fwlib/include/ameba_phy.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2024 Realtek Semiconductor Corp. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -enum eth_phy_type { - RTL_8721F, - RTL_8721G, -}; - -enum eth_mode { - ETH_MAC_MODE, - ETH_PHY_MODE, -}; - -enum phy_clk_mode { - EXTERNAL_50M, - EXTERNAL_25M, - INTERNAL_XTAL, -}; - -enum phy_MMD_type { - RTK_MMD_TYPE, - -}; - -enum phy_address { - PHYID_0, - PHYID_1, - PHYID_2, - PHYID_3, -}; - -#define RTK_EEEPC1R_DEVICE 0x3 -#define RTK_EEEPC1R_ADDRESS 0x0 - -#define RTK_EEEPS1R_DEVICE 0x3 -#define RTK_EEEPS1R_ADDRESS 0x1 - -#define RTK_EEECR_DEVICE 0x3 -#define RTK_EEECR_ADDRESS 0x14 - -#define RTK_EEEWER_DEVICE 0x3 -#define RTK_EEEWER_ADDRESS 0x16 - -#define RTK_EEEAR_DEVICE 0x7 -#define RTK_EEEAR_ADDRESS 0x3c -#define RTK_EEEAR_ADVERTISE_EEE 0x2 -#define RTK_EEEAR_NOT_ADVERTISE_EEE 0x0 - -#define RTK_EEELPAR_DEVICE 0x7 -#define RTK_EEELPAR_ADDRESS 0x3d - - -#define RTK8201F_EEE_CAPAB_PAGE 0x4 -#define RTK8201F_EEE_CAPAB_REG 0x10 -#define RTK8201F_EEE_CAPAB_EN 0x7377 - -#define RTK8201F_EEE_MODE_PAGE 0x7 -#define RTK8201F_EEE_MODE_REG 0x14 -#define RTK8201F_EEE_MAC_MODE_SET 0xD5 -#define RTK8201F_EEE_PHY_MODE_SET 0x10D5 - -#define RTK8201F_RMSR_MODE_PAGE 0x7 -#define RTK8201F_RMSR_MODE_REG 0x10 -#define RTK8201F_RMSR_MAC_OUTPUT 0x1ffa -#define RTK8201F_PMSR_MAC_INPUT 0xffa - -#define RTK_MACR_DATA BIT(14) - -void PHY_SW_RESET(void); -void PHY_RESTART_AN(void); -void PHY_SET_MMD_REG(u32 type, u32 device, u32 addr, u32 data); -u32 PHY_GET_MMD_REG(u32 type, u32 device, u32 addr); -void PHY_ENABLE_EEE(u32 type, u32 STATUS); -void PHY_SET_EEE_MODE(u32 type, u32 mode); -void PHY_SET_REFCLK_DIR(u32 type, u32 MACDIR); \ No newline at end of file diff --git a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_phy.c b/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_phy.c deleted file mode 100644 index 044dee40..00000000 --- a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_phy.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2024 Realtek Semiconductor Corp. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "ameba_soc.h" -// static const char *const TAG = "PHY"; - - -void PHY_SW_RESET(void) -{ - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_0, 0x8000); - DelayMs(150); -} - -void PHY_RESTART_AN(void) -{ - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_0, 0x1200); -} - - -void PHY_SET_MMD_REG(u32 type, u32 device, u32 addr, u32 data) -{ - switch (type) { - case RTK_MMD_TYPE: - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_13, device); - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_14, addr); - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_13, (device | RTK_MACR_DATA)); - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_14, data); - break; - - default: - break; - } -} - -u32 PHY_GET_MMD_REG(u32 type, u32 device, u32 addr) -{ - u32 rvalue = 0; - switch (type) { - case RTK_MMD_TYPE: - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_13, device); - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_14, addr); - Ethernet_Write_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_13, (device | RTK_MACR_DATA)); - rvalue = Ethernet_Read_PhyReg(FEPHY_REG_PAGE_0, FEPHY_REG_ADDR_14); - break; - - default: - break; - } - return rvalue; -} - -void PHY_ENABLE_EEE(u32 type, u32 STATUS) -{ - switch (type) { - case RTL_8721F: - if (STATUS) { - Ethernet_Write_PhyReg(RTK8201F_EEE_CAPAB_PAGE, RTK8201F_EEE_CAPAB_REG, RTK8201F_EEE_CAPAB_EN); - PHY_SET_MMD_REG(RTK_MMD_TYPE, RTK_EEEAR_DEVICE, RTK_EEEAR_ADDRESS, RTK_EEEAR_ADVERTISE_EEE); - PHY_RESTART_AN(); - } else { - - - } - break; - case RTL_8721G: - if (STATUS) { - - } else { - - } - break; - default: - break; - } -} - -void PHY_SET_EEE_MODE(u32 type, u32 mode) -{ - switch (type) { - case RTL_8721F: - if (mode == ETH_MAC_MODE) { - Ethernet_Write_PhyReg(RTK8201F_EEE_MODE_PAGE, RTK8201F_EEE_MODE_REG, RTK8201F_EEE_MAC_MODE_SET); - } else { - - - } - break; - case RTL_8721G: - break; - default: - break; - } -} - - -void PHY_SET_REFCLK_DIR(u32 type, u32 MACDIR) -{ - switch (type) { - case RTL_8721F: - if (MACDIR == ETH_REFCLK_ON) { - Ethernet_Write_PhyReg(RTK8201F_RMSR_MODE_PAGE, RTK8201F_RMSR_MODE_REG, RTK8201F_RMSR_MAC_OUTPUT); - } else { - Ethernet_Write_PhyReg(RTK8201F_RMSR_MODE_PAGE, RTK8201F_RMSR_MODE_REG, RTK8201F_PMSR_MAC_INPUT); - } - break; - case RTL_8721G: - break; - default: - break; - } -} \ No newline at end of file diff --git a/ameba/amebad/CMakeLists.txt b/ameba/amebad/CMakeLists.txt index c20f2462..25128f5e 100644 --- a/ameba/amebad/CMakeLists.txt +++ b/ameba/amebad/CMakeLists.txt @@ -1,5 +1,16 @@ # Copyright (c) 2024 Realtek Semiconductor Corp. # SPDX-License-Identifier: Apache-2.0 + +zephyr_link_libraries_ifdef(CONFIG_WIFI_AMEBA + -Wl,--start-group + ${LIB_PATH}/lib_wifi_rtk_app.a + ${LIB_PATH}/lib_wifi_single_core.a + -Wl,--end-group + ${LIB_PATH}/lib_wifi_api.a + ${LIB_PATH}/lib_rtw_event.a + ${LIB_PATH}/lib_wpa_lite.a + ${LIB_PATH}/lib_wifi_com_sec.a +) zephyr_compile_options(-mcmse) zephyr_include_directories( @@ -7,14 +18,18 @@ zephyr_include_directories( source/cmsis source/misc source/swlib + source/lib/include source/fwlib/include + source/usrcfg/include source/app/monitor/include ) # used by common zephyr_library_sources( source/fwlib/ram_hp/ameba_system.c + source/fwlib/ram_common/ameba_pll.c source/swlib/log.c + source/fwlib/ram_common/ameba_reset.c ) # used by driver, need use zephyr_library_sources_ifdef @@ -37,31 +52,3 @@ zephyr_link_libraries( gcc -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_acut.ld ) - -# west sign -if(CONFIG_SOC_AMEBA_NP_IMAGE) - file(GLOB blob_bin_file "${ZEPHYR_HAL_REALTEK_MODULE_DIR}/zephyr/blobs/${CONFIG_SOC_SERIES}/bin/*.bin") - - if(blob_bin_file) - set(python_script_args - --soc ${CONFIG_SOC_SERIES} - --bin-file ${ZEPHYR_BINARY_DIR}/${KERNEL_BIN_NAME} - --out-dir ${CMAKE_BINARY_DIR} - --module-dir ${ZEPHYR_HAL_REALTEK_MODULE_DIR} - ) - - add_custom_target(zephyr.raw.map ALL - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - ) - - add_custom_command( - OUTPUT ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_NM} ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} | sort > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_OBJDUMP} -d ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.asm - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/scripts/merge_bin.py ${python_script_args} - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${blob_bin_file} ${CMAKE_CURRENT_SOURCE_DIR}/manifest.json5 - ) - else() - message(WARNING "Missing Realtek blobs. Run: `west blobs fetch hal_realtek`") - endif() -endif() diff --git a/ameba/amebad/Kconfig b/ameba/amebad/Kconfig index d3687b53..fce66f25 100644 --- a/ameba/amebad/Kconfig +++ b/ameba/amebad/Kconfig @@ -4,3 +4,6 @@ config ARM_CORE_CM4 bool default y if SOC_SERIES_AMEBAD + +config SOC_SERIES_AMEBAD + select SINGLE_CORE_WIFI if WLAN diff --git a/ameba/amebad/include/platform_autoconf.h b/ameba/amebad/include/platform_autoconf.h index 120e64d2..4a67a5f5 100644 --- a/ameba/amebad/include/platform_autoconf.h +++ b/ameba/amebad/include/platform_autoconf.h @@ -9,6 +9,7 @@ #define CONFIG_IMG2_FLASH 1 #define CONFIG_SUPPORT_ATCMD 1 #define CONFIG_ATCMD_LOGUART 1 +#define CONFIG_VFS_LITTLEFS_INCLUDED 1 #define CONFIG_LINK_ROM_SYMB 1 #define CONFIG_CPU_HAS_FPU 1 #define CONFIG_ARM_CORE_CM4 1 @@ -18,3 +19,4 @@ #define CONFIG_AMEBAD_B_CUT 1 #define CONFIG_SOC_PS_EN 1 #define CONFIG_SOC_PS_MODULE 1 +#include diff --git a/ameba/amebad/source/fwlib/include/ameba.h b/ameba/amebad/source/fwlib/include/ameba.h index 3c2e5527..7f75ed09 100644 --- a/ameba/amebad/source/fwlib/include/ameba.h +++ b/ameba/amebad/source/fwlib/include/ameba.h @@ -51,7 +51,7 @@ #else #include "ameba_rcc_lp.h" #endif -// #include "sscanf_minimal.h" +#include "sscanf_minimal.h" #include "ameba_trustzone.h" #include "ameba_arch.h" diff --git a/ameba/amebad/source/fwlib/include/ameba_efuse.h b/ameba/amebad/source/fwlib/include/ameba_efuse.h index 51ccdff2..63cba7a1 100644 --- a/ameba/amebad/source/fwlib/include/ameba_efuse.h +++ b/ameba/amebad/source/fwlib/include/ameba_efuse.h @@ -159,7 +159,7 @@ int OTP_LogicalMap_Write(u32 addr, u32 cnts, u8 *data); int OTPSetCRC(void); int OTP_Read8(u32 Addr, u8 *Data); int OTP_Write8(u32 Addr, u8 Data); - +void EFUSE_GetUUID(u32 *UUID); /** * @} */ diff --git a/ameba/amebad/source/fwlib/include/ameba_gdma.h b/ameba/amebad/source/fwlib/include/ameba_gdma.h index 063360e0..d87a4fa6 100644 --- a/ameba/amebad/source/fwlib/include/ameba_gdma.h +++ b/ameba/amebad/source/fwlib/include/ameba_gdma.h @@ -459,7 +459,7 @@ _LONG_CALL_ void GDMA_SetChnlPriority(u8 GDMA_Index, u8 GDMA_ChNum, u32 ChnlPrio _LONG_CALL_ void GDMA_Suspend(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ void GDMA_Resume(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ u8 GDMA_Abort(u8 GDMA_Index, u8 GDMA_ChNum); - +_LONG_CALL_ u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum); /** * @} diff --git a/ameba/amebad/source/fwlib/include/ameba_reset.h b/ameba/amebad/source/fwlib/include/ameba_reset.h index b60db37e..60214b6c 100644 --- a/ameba/amebad/source/fwlib/include/ameba_reset.h +++ b/ameba/amebad/source/fwlib/include/ameba_reset.h @@ -12,6 +12,12 @@ /* AUTO_GEN_END */ +#define AON_BIT_RSTF_DSLP BIT_BOOT_DSLP_RESET_HAPPEN +#define AON_BIT_RSTF_BOR BIT_BOOT_BOD_RESET_HAPPEN + +#define IS_WDG_RESET(reason) ((reason) & (BIT_BOOT_WDG_RESET_HAPPEN | BIT_BOOT_KM4WDG_RESET_HAPPEN)) +#define IS_SYS_RESET(reason) ((reason) & (BIT_BOOT_SYS_RESET_HAPPEN | BIT_BOOT_KM4SYS_RESET_HAPPEN)) + extern void System_Reset(void); #endif diff --git a/ameba/amebad/source/fwlib/include/ameba_ssi.h b/ameba/amebad/source/fwlib/include/ameba_ssi.h index 8a421958..1dcec3e1 100644 --- a/ameba/amebad/source/fwlib/include/ameba_ssi.h +++ b/ameba/amebad/source/fwlib/include/ameba_ssi.h @@ -660,6 +660,11 @@ extern const SPI_DevTable SPI_DEV_TABLE[2]; #define SPI_BIT_RXFIS BIT_ISR_RXFIS #define SPI_BIT_TXEIS BIT_ISR_TXEIS +/* SPI_SR */ +#define SPI_BIT_DCOL BIT_SR_DCOL +#define SPI_BIT_TFE BIT_SR_TFE +#define SPI_BIT_BUSY BIT_SR_BUSY + /* SPI_IMR */ #define SPI_BIT_RXFIM BIT_IMR_RXFIM #define SPI_BIT_RXOIM BIT_IMR_RXOIM diff --git a/ameba/amebad/source/fwlib/include/ameba_trustzone.h b/ameba/amebad/source/fwlib/include/ameba_trustzone.h index 2c6ca635..b58bdf8f 100644 --- a/ameba/amebad/source/fwlib/include/ameba_trustzone.h +++ b/ameba/amebad/source/fwlib/include/ameba_trustzone.h @@ -28,8 +28,8 @@ typedef struct { */ #define SAU_INIT_CTRL_ALLNS 0 -#define SAU_ENTRYS_NUM 8 -#define IDAU_ENTRYS_NUM 8 +#define SAU_ENTRY_NUM 8 +#define IDAU_ENTRY_NUM 8 void BOOT_RAM_TZCfg(void); diff --git a/ameba/amebad/source/fwlib/ram_common/ameba_efuse.c b/ameba/amebad/source/fwlib/ram_common/ameba_efuse.c index cd6132b2..0f65c683 100644 --- a/ameba/amebad/source/fwlib/ram_common/ameba_efuse.c +++ b/ameba/amebad/source/fwlib/ram_common/ameba_efuse.c @@ -6,4 +6,18 @@ #include "ameba_soc.h" +#define OTP_UUID 0x1F4 + +void EFUSE_GetUUID(u32 *UUID) +{ + u8 index, ID[4]; + + for (index = 0; index < 4; index++) { + OTP_Read8(OTP_UUID + index, &ID[index]); + } + + UUID[0] = (ID[3] << 24) | (ID[2] << 16) | (ID[1] << 8) | ID[0]; + UUID[1] = 0; +} + /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/ diff --git a/ameba/amebad/source/fwlib/ram_common/ameba_gdma_ram.c b/ameba/amebad/source/fwlib/ram_common/ameba_gdma_ram.c index ce8ed193..938069f2 100644 --- a/ameba/amebad/source/fwlib/ram_common/ameba_gdma_ram.c +++ b/ameba/amebad/source/fwlib/ram_common/ameba_gdma_ram.c @@ -267,3 +267,27 @@ u8 GDMA_Abort(u8 GDMA_Index, u8 GDMA_ChNum) return TRUE; } +/** + * @brief Check if the channel is active + * + * @param GDMA_Index 0 + * @param GDMA_ChNum 0 ~ 7 + * @retval TRUE/FALSE + */ +__weak +u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum) +{ + GDMA_TypeDef *GDMA = ((GDMA_TypeDef *) GDMA_BASE); + if (TrustZone_IsSecure()) { + GDMA = ((GDMA_TypeDef *) GDMA0S_REG_BASE); + } + /* Check the parameters */ + assert_param(IS_GDMA_Index(GDMA_Index)); + assert_param(IS_GDMA_ChannelNum(GDMA_ChNum)); + + if ((GDMA->ChEnReg & BIT(GDMA_ChNum)) && \ + ((GDMA->CH[GDMA_ChNum].CFG_LOW & BIT_CFGx_L_INACTIVE) == 0)) { + return TRUE; + } + return FALSE; +} diff --git a/ameba/amebad/source/fwlib/ram_common/ameba_gpio.c b/ameba/amebad/source/fwlib/ram_common/ameba_gpio.c index 99b7057f..1c3c8abd 100644 --- a/ameba/amebad/source/fwlib/ram_common/ameba_gpio.c +++ b/ameba/amebad/source/fwlib/ram_common/ameba_gpio.c @@ -6,6 +6,30 @@ #include "ameba_soc.h" +/** + * @brief Reads the specified GPIO pins. + * @param GPIO_Port: Specifies port number + * This parameter can be one of the following values: + * @arg GPIO_PORT_A: port number is A + * @arg GPIO_PORT_B: port number is B + * @param GPIO_Mask: One bit one GPIO pin, PortA/B:0x00000000 ~0xFFFFFFFF. + * @note It can config multiple pins of one port by parameter GPIO_Mask + * @retval The value of the specified port pins + */ +u32 GPIO_PortRead(u32 GPIO_Port, u32 GPIO_Mask) +{ + GPIO_TypeDef *GPIO = NULL; + u32 RegValue; + + GPIO = PORT_AB[GPIO_Port]; + + RegValue = GPIO->EXT_PORT[0]; + + RegValue &= GPIO_Mask; + + return RegValue; +} + static GPIO_TypeDef *GPIO_PortAddrGet(u32 GPIO_Port) { GPIO_TypeDef *GPIO = NULL; diff --git a/ameba/amebad/source/fwlib/ram_common/ameba_pll.c b/ameba/amebad/source/fwlib/ram_common/ameba_pll.c index 32111365..4a22aea8 100644 --- a/ameba/amebad/source/fwlib/ram_common/ameba_pll.c +++ b/ameba/amebad/source/fwlib/ram_common/ameba_pll.c @@ -319,4 +319,42 @@ void PLL3_Set(u32 BitMask, u32 NewState) RTK_LOGW(TAG, "%s Please check this function \n", __func__); } + +/** + * @brief Check whether the APB peripheral's clock has been enabled or not + * @param APBPeriph_Clock_in: specifies the APB peripheral to check. + * This parameter can be one of @ref APBPeriph_UART0_CLOCK, APBPeriph_ATIM_CLOCK and etc. + * @retval TRUE: The APB peripheral's clock has been enabled + * FALSE: The APB peripheral's clock has not been enabled + */ +u8 RCC_PeriphClockEnableChk(u32 APBPeriph_Clock_in) +{ + u8 ret; + u32 TempVal, CkeRegOffset = 0; + u32 ClkRegIndx = (APBPeriph_Clock_in >> 30) & 0x03; + u32 APBPeriph_Clock = APBPeriph_Clock_in & (~(BIT(31) | BIT(30))); + assert_param((ClkRegIndx == 0x1) || (ClkRegIndx == 0x2) || (ClkRegIndx == 0x3)); + + switch (ClkRegIndx) { + case SYS_CLK_CTRL1: + CkeRegOffset = REG_HS_PERI_CLK_CTRL1; + break; + case SYS_CLK_CTRL2: + CkeRegOffset = REG_HS_PERI_CLK_CTRL2; + break; + case SYS_CLK_CTRL3: + CkeRegOffset = REG_HS_PERI_CLK_CTRL3; + break; + } + + TempVal = HAL_READ32(SYSTEM_CTRL_BASE, CkeRegOffset); + if (TempVal & APBPeriph_Clock) { + ret = TRUE; + } else { + ret = FALSE; + } + + return ret; +} + /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/ diff --git a/ameba/amebad/source/swlib/sscanf_minimal.c b/ameba/amebad/source/swlib/sscanf_minimal.c new file mode 100644 index 00000000..02cb7cd6 --- /dev/null +++ b/ameba/amebad/source/swlib/sscanf_minimal.c @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +#include +#include + +#define USHRT_MAX_INTERNAL ((u16)(~0U)) +#define BUF_MAX ((s16)(USHRT_MAX_INTERNAL>>1)) +#define STR_STORE_MAX_LEN 24 +#define KSTRTOX_OVERFLOW (1U << 31) + +#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',') + + +/** + * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder + * + * This is commonly provided by 32bit archs to provide an optimized 64bit + * divide. + */ +static u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +{ + *remainder = (u32)dividend % divisor; + return (u32)dividend / divisor; +} + +/** + * div_s64_rem - signed 64bit divide with 32bit divisor with remainder + */ +static s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) +{ + *remainder = (s32)dividend % divisor; + return (s32)dividend / divisor; +} + +/** + * div_u64 - unsigned 64bit divide with 32bit divisor + * + * This is the most common 64bit divide and should be used if possible, + * as many 32bit archs can optimize this variant better than a full 64bit + * divide. + */ + +static u64 div_u64(u64 dividend, u32 divisor) +{ + u32 remainder; + return div_u64_rem(dividend, divisor, &remainder); +} + +/** + * div_s64 - signed 64bit divide with 32bit divisor + */ + +static s64 div_s64(s64 dividend, s32 divisor) +{ + s32 remainder; + return div_s64_rem(dividend, divisor, &remainder); +} + + +static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) +{ + if (*base == 0) { + if (s[0] == '0') { + if (_tolower(s[1]) == 'x' && isxdigit(s[2])) { + *base = 16; + } else { + *base = 8; + } + } else { + *base = 10; + } + } + if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') { + s += 2; + } + return s; +} + +static char *skip_spaces(const char *str) +{ + while (isspace(*str)) { + ++str; + } + + return (char *)str; +} +static int skip_atoi(const char **s) +{ + int i = 0; + + while (isdigit(**s)) { + i = i * 10 + *((*s)++) - '0'; + } + + return i; +} + +static int judge_digit_width(const char *str, unsigned int base) +{ + + int width = 0; + + if ((base == 16 || base == 0) && str[0] == '0' && _tolower(str[1]) == 'x') { + str += 2; + width += 2; + + while (isxdigit(*str)) { + width++; + str++; + } + } else if (base == 16) { + while (isxdigit(*str)) { + width++; + str++; + } + } else if (base == 8 || (base == 0 && str[0] == '0')) { + while (isdigit(*str) && (*str) < '8') { + width++; + str++; + } + } else { + while (isdigit(*str)) { + width++; + str++; + } + } + + return width; +} + +//_OPTIMIZE_NONE_ +int _vsscanf_minimal(const char *buf, const char *fmt, va_list args) +{ + const char *str = buf; + char *next; + char digit; + int num = 0; + int i = 0; + u8 qualifier; + unsigned int base; + union { + long long s; + unsigned long long u; + } val; + s16 field_width; + bool is_sign; + + char str_store[STR_STORE_MAX_LEN] = {0}; + + while (*fmt) { + /* skip any white space in format */ + /* white space in format matchs any amount of + * white space, including none, in the input. + */ + if (isspace(*fmt)) { + fmt = skip_spaces(++fmt); + str = skip_spaces(str); + } + + /* anything that is not a conversion must match exactly */ + if (*fmt != '%' && *fmt) { + if (*fmt++ != *str++) { + break; + } + + continue; + } + + if (!*fmt) { + break; + } + + ++fmt; + + /* skip this conversion. + * advance both strings to next white space + */ + if (*fmt == '*') { + if (!*str) { + break; + } + + while (!isspace(*fmt) && *fmt != '%' && *fmt) { + fmt++; + } + while (!isspace(*str) && *str) { + str++; + } + + continue; + } + + /* get field width */ + field_width = -1; + + if (isdigit(*fmt)) { + + field_width = skip_atoi(&fmt); + + if (field_width <= 0) { + break; + } + } + + /* get conversion qualifier */ + qualifier = -1; + + if (*fmt == 'h' || _tolower(*fmt) == 'l' || _tolower(*fmt) == 'z') { + qualifier = *fmt++; + + if (qualifier == *fmt) { + if (qualifier == 'h') { + qualifier = 'H'; + fmt++; + } else if (qualifier == 'l') { + qualifier = 'L'; + fmt++; + } + } + } + + if (!*fmt) { + break; + } + + if (*fmt == 'n') { + /* return number of characters read so far */ + *va_arg(args, int *) = str - buf; + ++fmt; + continue; + } + + if (!*str) { + break; + } + + base = 10; + is_sign = 0; + + switch (*fmt++) { + case 'c': { + char *s = (char *)va_arg(args, char *); + + if (field_width == -1) { + field_width = 1; + } + + do { + *s++ = *str++; + } while (--field_width > 0 && *str); + + num++; + } + + continue; + + case 's': { + char *s = (char *)va_arg(args, char *); + if (field_width == -1) { + field_width = SHRT_MAX; + } + /* first, skip leading white space in buffer */ + str = skip_spaces(str); + + /* now copy until next white space */ + while (*str && !isspace(*str) && field_width--) { + *s++ = *str++; + } + + *s = '\0'; + num++; + } + continue; + + case 'o': + base = 8; + break; + + case 'x': + case 'X': + base = 16; + break; + + case 'i': + base = 0; + is_sign = 1; + break; + + case 'd': + is_sign = 1; + break; + + case 'u': + break; + + case '%': + /* looking for '%' in str */ + if (*str++ != '%') { + return num; + } + continue; + + default: + /* invalid format; stop here */ + return num; + } + + /* have some sort of integer conversion. + * first, skip white space in buffer. + */ + str = skip_spaces(str); + + digit = *str; + + if (is_sign && digit == '-') { + if (field_width == -1) { + field_width = judge_digit_width(str + 1, base); + field_width++; + } else { + field_width = (judge_digit_width(str + 1, base) + 1) < field_width ? + (judge_digit_width(str + 1, base) + 1) : + field_width; + } + digit = *(str + 1); + } else if (field_width == -1) { + field_width = judge_digit_width(str, base); + } else { + field_width = judge_digit_width(str, base) < field_width ? + judge_digit_width(str, base) : + field_width; + } + + if (!digit + || (base == 16 && !isxdigit(digit)) + || (base == 10 && !isdigit(digit)) + || (base == 8 && (!isdigit(digit) || digit > '7')) + || (base == 0 && !isdigit(digit))) { + break; + } + + //assert_param (field_width <= STR_STORE_MAX_LEN); + for (i = 0; i < field_width ; i++) { + str_store[i] = str[i]; + } + + if (is_sign) { + val.s = qualifier != 'L' ? + strtol(str_store, &next, base) : + strtoll(str_store, &next, base); + } else { + val.u = qualifier != 'L' ? + _strtoul(str_store, &next, base) : + strtoull(str_store, &next, base); + } + + /* standard strtoul need this */ + next = (char *)str + field_width; + + for (i = 0; i < STR_STORE_MAX_LEN ; i++) { + str_store[i] = 0; + } + + + //判断转换的字符串的宽度是否大于 %2d + if (field_width > 0 && next - str > field_width) { + if (base == 0) { + _parse_integer_fixup_radix(str, &base); + } + + while (next - str > field_width) { + if (is_sign) { + val.s = div_s64(val.s, base); + } else { + val.u = div_u64(val.u, base); + } + + --next; + } + } + + switch (qualifier) { + case 'H': /* that's 'hh' in format */ + if (is_sign) { + *va_arg(args, signed char *) = val.s; + } else { + *va_arg(args, unsigned char *) = val.u; + } + break; + + case 'h': + if (is_sign) { + memcpy(va_arg(args, short *), &(val.s), sizeof(short)); + } else { + memcpy(va_arg(args, unsigned short *), &(val.u), sizeof(unsigned short)); + } + break; + + case 'l': + if (is_sign) { + memcpy(va_arg(args, long *), &(val.s), sizeof(long)); + } else { + memcpy(va_arg(args, unsigned long *), &(val.u), sizeof(unsigned long)); + } + break; + + case 'L': + if (is_sign) { + memcpy(va_arg(args, long long *), &(val.s), sizeof(long long)); + } else { + memcpy(va_arg(args, unsigned long long *), &(val.u), sizeof(unsigned long long)); + } + break; + + case 'Z': + case 'z': + memcpy(va_arg(args, size_t *), &(val.u), sizeof(size_t)); + break; + + default: + if (is_sign) { + memcpy(va_arg(args, int *), &(val.s), sizeof(int)); + } else { + memcpy(va_arg(args, unsigned int *), &(val.u), sizeof(unsigned int)); + } + break; + } + + num++; + + if (!next) { + break; + } + + str = next; + } + + return num; +} + +/** +* sscanf - Unformat a buffer into a list of arguments +* @buf: input buffer +* @fmt: formatting of buffer +* @...: resulting arguments +*/ +/* support %* %x %c %s %o %x %i %d %u %h %z and %l(within len 24) */ +/* for internal use, not support [] and ^ */ +int _sscanf_ss(const char *buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = _vsscanf_minimal(buf, fmt, args); + va_end(args); + + return i; +} diff --git a/ameba/amebaG2/source/fwlib/include/rom/sscanf_minimal.h b/ameba/amebad/source/swlib/sscanf_minimal.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/sscanf_minimal.h rename to ameba/amebad/source/swlib/sscanf_minimal.h diff --git a/ameba/amebadplus/CMakeLists.txt b/ameba/amebadplus/CMakeLists.txt index d6f51ef9..9faba7e5 100644 --- a/ameba/amebadplus/CMakeLists.txt +++ b/ameba/amebadplus/CMakeLists.txt @@ -3,23 +3,42 @@ zephyr_compile_options(-mcmse) +set(LIB_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/blobs/ameba/${CONFIG_SOC_SERIES}/lib) + +zephyr_link_libraries_ifdef(CONFIG_WIFI_AMEBA + ${LIB_PATH}/lib_wifi_whc_ap.a + ${LIB_PATH}/lib_wifi_api.a + ${LIB_PATH}/lib_rtw_event.a + ${LIB_PATH}/lib_wpa_lite.a + ${LIB_PATH}/lib_wifi_com_sec.a + ${LIB_PATH}/lib_coex_api.a + ${LIB_PATH}/lib_wifi_rtk_app.a +) zephyr_include_directories( include + source/cmsis + source/misc source/swlib source/fwlib/include + source/usrcfg/include + source/app/monitor/include ) # used by common zephyr_library_sources( - source/fwlib/ram_common/ameba_loguart.c + source/fwlib/ram_common/ameba_rtc_io.c source/fwlib/ram_common/ameba_reset.c source/fwlib/ram_common/ameba_clk.c source/swlib/log.c + source/fwlib/ram_common/ameba_adc.c + source/fwlib/ram_common/ameba_loguart.c + source/fwlib/ram_common/ameba_arch.c + source/fwlib/ram_common/ameba_ipc_api.c + source/fwlib/ram_common/ameba_ipc_ram.c ) # used by driver, need use zephyr_library_sources_ifdef zephyr_library_sources_ifdef(CONFIG_GPIO_AMEBA source/fwlib/ram_common/ameba_gpio.c) -zephyr_library_sources_ifdef(CONFIG_ADC_AMEBA source/fwlib/ram_common/ameba_adc.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CTC_AMEBA source/fwlib/ram_common/ameba_captouch.c) zephyr_library_sources_ifdef(CONFIG_I2S_AMEBA source/fwlib/ram_common/ameba_audio_clock.c) zephyr_library_sources_ifdef(CONFIG_I2S_AMEBA source/fwlib/ram_common/ameba_pll.c) @@ -39,49 +58,3 @@ zephyr_link_libraries( -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_acut_s.ld -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_stdlib.ld ) - -zephyr_link_libraries( - "-Wl,-wrap,memchr" - "-Wl,-wrap,memcmp" - "-Wl,-wrap,memcpy" - "-Wl,-wrap,memmove" - "-Wl,-wrap,memset" - "-Wl,-wrap,strcmp" - "-Wl,-wrap,strlen" - "-Wl,-wrap,strtoul" - "-Wl,-wrap,strupr" - "-Wl,-wrap,stricmp" - "-Wl,-wrap,rand" - "-Wl,-wrap,strchr" - "-Wl,-wrap,strncmp" - "-Wl,-wrap,strstr" - "-Wl,-wrap,strncpy" -) - -# west sign -if(CONFIG_SOC_AMEBA_NP_IMAGE) - file(GLOB blob_bin_file "${ZEPHYR_HAL_REALTEK_MODULE_DIR}/zephyr/blobs/${CONFIG_SOC_SERIES}/bin/*.bin") - - if(blob_bin_file) - set(python_script_args - --soc ${CONFIG_SOC_SERIES} - --bin-file ${ZEPHYR_BINARY_DIR}/${KERNEL_BIN_NAME} - --out-dir ${CMAKE_BINARY_DIR} - --module-dir ${ZEPHYR_HAL_REALTEK_MODULE_DIR} - ) - - add_custom_target(zephyr.raw.map ALL - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - ) - - add_custom_command( - OUTPUT ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_NM} ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} | sort > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_OBJDUMP} -d ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.asm - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/scripts/merge_bin.py ${python_script_args} - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${blob_bin_file} ${CMAKE_CURRENT_SOURCE_DIR}/manifest.json5 - ) - else() - message(WARNING "Missing Realtek blobs. Run: `west blobs fetch hal_realtek`") - endif() -endif() diff --git a/ameba/amebadplus/Kconfig b/ameba/amebadplus/Kconfig index b5dc19d0..978ec72f 100644 --- a/ameba/amebadplus/Kconfig +++ b/ameba/amebadplus/Kconfig @@ -4,3 +4,6 @@ config ARM_CORE_CM4 bool default y if SOC_SERIES_AMEBADPLUS + +config SOC_SERIES_AMEBADPLUS + select AS_INIC_AP if WLAN diff --git a/ameba/amebadplus/include/platform_autoconf.h b/ameba/amebadplus/include/platform_autoconf.h index f09ba2a7..45a5f175 100644 --- a/ameba/amebadplus/include/platform_autoconf.h +++ b/ameba/amebadplus/include/platform_autoconf.h @@ -3,12 +3,26 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define CONFIG_AMEBADPLUS 1 #define CONFIG_IMG1_FLASH 1 #define CONFIG_IMG2_FLASH 1 +#define CONFIG_SUPPORT_ATCMD 1 +#define CONFIG_ATCMD_MANUAL_TEST 1 +#define CONFIG_ATCMD_NETWORK 1 +#define CONFIG_BACK_TRACE_DEPTH_LIMIT 8 +#define CONFIG_WHC_INTF_IPC_MENU 1 #define CONFIG_CORE_AS_AP 1 - +#define CONFIG_WLAN_MENU 1 +#define CONFIG_NORMAL_SDK 1 +#define CONFIG_WLAN 1 +#define CONFIG_WHC_INTF_IPC 1 +#define CONFIG_WHC_HOST 1 +//#define CONFIG_LWIP_LAYER 1 // not set in zephyr +#define CONFIG_LWIP_NETCONN_SEM_PER_THREAD_MENU 1 +#define CONFIG_LWIP_NETCONN_SEM_PER_THREAD 1 #define CONFIG_LINK_ROM_SYMB 1 #define CONFIG_CPU_HAS_FPU 1 #define CONFIG_ARM_CORE_CM4 1 #define CONFIG_AMEBADPLUS_B_CUT 1 +#include diff --git a/ameba/amebadplus/source/fwlib/include/ameba.h b/ameba/amebadplus/source/fwlib/include/ameba.h index f373f077..69978cb9 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba.h +++ b/ameba/amebadplus/source/fwlib/include/ameba.h @@ -78,9 +78,9 @@ #include "ameba_aontimer.h" #include "ameba_rcc.h" #include "ameba_rom_patch.h" -// #include "ameba_usrcfg.h" +#include "ameba_usrcfg.h" #include "log.h" -// #include "sscanf_minimal.h" +#include "sscanf_minimal.h" #define IMAGE_HEADER_LEN 0x20 typedef struct { diff --git a/ameba/amebadplus/source/fwlib/include/ameba_clk.h b/ameba/amebadplus/source/fwlib/include/ameba_clk.h index 9db53829..8aab6132 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba_clk.h +++ b/ameba/amebadplus/source/fwlib/include/ameba_clk.h @@ -176,6 +176,16 @@ #define PERI_CLK_LIMIT (100 * MHZ_TICK_CNT) #define SRAM_CLK_LIMIT (200 * MHZ_TICK_CNT) +/** @defgroup HS_RCC_definitions + * @{ + */ +struct Rcc_ClkDiv { + u32 CkdGroupOfs; + u32 BitMask; + u32 DivShift; + u32 DivVal; /* Note in some IP, the real work divider equals (regval + 1) */ +}; + /** * @} */ @@ -236,6 +246,11 @@ _LONG_CALL_ bool PLL_State(void); _LONG_CALL_ void PLL_ClkSet(u32 PllClk); _LONG_CALL_ void OSC131K_Reset(void); +/** + * @}defgroup HS_RCC_Exported_Functions HS_RCC Exported Functions + */ +_LONG_CALL_ void RCC_PeriphClockDivSet(const struct Rcc_ClkDiv *pdiv); +_LONG_CALL_ u8 RCC_PeriphClockEnableChk(u32 APBPeriph_Clock_in); /* Registers Definitions --------------------------------------------------------*/ /**************************************************************************//** diff --git a/ameba/amebadplus/source/fwlib/include/ameba_gdma.h b/ameba/amebadplus/source/fwlib/include/ameba_gdma.h index c1c6efbb..6ec98f68 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba_gdma.h +++ b/ameba/amebadplus/source/fwlib/include/ameba_gdma.h @@ -612,6 +612,6 @@ _LONG_CALL_ void GDMA_SetChnlPriority(u8 GDMA_Index, u8 GDMA_ChNum, u32 ChnlPrio _LONG_CALL_ void GDMA_Suspend(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ void GDMA_Resume(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ u8 GDMA_Abort(u8 GDMA_Index, u8 GDMA_ChNum); +_LONG_CALL_ u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum); - -#endif //_AMEBA_GDMA_H_ \ No newline at end of file +#endif //_AMEBA_GDMA_H_ diff --git a/ameba/amebadplus/source/fwlib/include/ameba_reset.h b/ameba/amebadplus/source/fwlib/include/ameba_reset.h index 9b4226cb..fb5a74e6 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba_reset.h +++ b/ameba/amebadplus/source/fwlib/include/ameba_reset.h @@ -83,6 +83,9 @@ enum CHIPEN_WORK_MODE { #define SYS_RESET_KEY 0x96969696 #define SYS_RESET_TRIG 0x69696969 +#define IS_WDG_RESET(reason) ((reason) & (AON_BIT_RSTF_IWDG | AON_BIT_RSTF_WDG0 | \ + AON_BIT_RSTF_WDG1 | AON_BIT_RSTF_WDG2)) +#define IS_SYS_RESET(reason) ((reason) & (AON_BIT_RSTF_KM0_SYS | AON_BIT_RSTF_KM4_SYS)) extern void CHIPEN_WorkMode(enum CHIPEN_WORK_MODE mode); extern void CHIPEN_DebounceSet(u32 Debounce); diff --git a/ameba/amebadplus/source/fwlib/include/ameba_rom_patch.h b/ameba/amebadplus/source/fwlib/include/ameba_rom_patch.h index 92012748..5c1d27b8 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba_rom_patch.h +++ b/ameba/amebadplus/source/fwlib/include/ameba_rom_patch.h @@ -12,27 +12,18 @@ * @{ */ +// add your constants here + /** @defgroup ROM_PATCH_Structure_Type Structure Type * @{ */ -struct Rcc_ClkDiv { - u32 CkdGroupOfs; - u32 BitMask; - u32 DivShift; - u32 DivVal; /* Note in some IP, the real work divider equals (regval + 1) */ -}; -/** @} */ -/** @} */ - /* Exported functions -------------------------------------------------------- */ /** @defgroup ROM_PATCH_Exported_Functions ROM_PATCH Exported Functions * @{ */ // add your function statements here -_LONG_CALL_ void RCC_PeriphClockDivSet(const struct Rcc_ClkDiv *pdiv); -_LONG_CALL_ u8 RCC_PeriphClockEnableChk(u32 APBPeriph_Clock_in); _LONG_CALL_ void RCC_PeriphClockSource_UART(UART_TypeDef *UARTx, u32 Source); _LONG_CALL_ void RCC_PeriphClockSource_LOGUART(u32 Source); _LONG_CALL_ void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct); diff --git a/ameba/amebadplus/source/fwlib/include/ameba_trustzone.h b/ameba/amebadplus/source/fwlib/include/ameba_trustzone.h index 77a65446..cd9f36c3 100644 --- a/ameba/amebadplus/source/fwlib/include/ameba_trustzone.h +++ b/ameba/amebadplus/source/fwlib/include/ameba_trustzone.h @@ -99,8 +99,8 @@ typedef enum { */ #define SAU_INIT_CTRL_ALLNS 0 -#define SAU_ENTRYS_NUM 8 -#define MPC_ENTRYS_NUM 8 +#define SAU_ENTRY_NUM 8 +#define MPC_ENTRY_NUM 8 #define MPC_CNT 2 @@ -156,4 +156,4 @@ __STATIC_INLINE u32 TrustZone_IsSecure(void) } -#endif \ No newline at end of file +#endif diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_arch.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_arch.c index 5b031694..5cefbd9b 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_arch.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_arch.c @@ -143,4 +143,3 @@ void irq_enable_restore(u32 PrevStatus) { __set_PRIMASK(PrevStatus); } - diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_bor.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_bor.c new file mode 100644 index 00000000..a31bdbf9 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_bor.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" + +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup BOR + * @brief BOR driver modules + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup BOR_Exported_Functions BOR Exported Functions + * @{ + */ + +/** + * @brief Set BOR rising and falling threshold. + * @param Thres_Fall BOR falling threshold. + * This parameter can be one of the following values: + * @arg 00010: 2.82 + * @arg 00011: 2.78 + * @arg 00100: 2.74 + * @arg 00101: 2.69 + * @arg 00110: 2.65 + * @arg 00111: 2.61 + * @arg 01000: 2.56 + * @arg 01001: 2.53 + * @arg 01010: 2.49 + * @arg 01011: 2.45 + * @arg 01100: 2.41 + * @arg 01101: 2.37 + * @arg 01110: 2.32 + * @arg 01111: 2.21 + * @arg 10000: 2.16 + * @arg 10001: 2.12 + * @arg 10010: 2.08 + * @arg 10011: 2.04 + * @arg 10100: 2.00 + * @arg 10101: 1.96 + * @arg 10110: 1.93 + * @arg 10111: 1.88 + * @arg 11000: 1.83 + * @arg 11001: 1.79 + * @arg 11010: 1.75 + * @arg 11011: 1.71 + * @arg 11100: 1.69 + * @arg 11101: 1.65 + * @arg 11110: 1.61 + * @arg 11111: 1.58 + * @param Thres_Rise: BOR rising threshold. + * This parameter can be one of the following values: + * @arg 00000: 2.94 + * @arg 00001: 2.86 + * @arg 00010: 2.83 + * @arg 00011: 2.79 + * @arg 00100: 2.75 + * @arg 00101: 2.71 + * @arg 00110: 2.66 + * @arg 00111: 2.62 + * @arg 01000: 2.58 + * @arg 01001: 2.54 + * @arg 01010: 2.50 + * @arg 01011: 2.46 + * @arg 01100: 2.42 + * @arg 01101: 2.38 + * @arg 01110: 2.33 + * @arg 01111: 2.22 + * @arg 10000: 2.17 + * @arg 10001: 2.13 + * @arg 10010: 2.09 + * @arg 10011: 2.05 + * @arg 10100: 2.01 + * @arg 10101: 1.97 + * @arg 10110: 1.94 + * @arg 10111: 1.89 + * @arg 11000: 1.85 + * @arg 11001: 1.80 + * @arg 11010: 1.77 + * @arg 11011: 1.73 + * @arg 11100: 1.70 + * @arg 11101: 1.66 + * @note For chip to work normally, it is advised to make rising threshold 200mV larger than falling threshold at least. + * @return None + */ +void BOR_ThresholdSet(u32 Thres_Fall, u32 Thres_Rise) +{ + u32 temp; + assert_param(IS_BOR_TH_FALL(Thres_Fall)); + assert_param(IS_BOR_TH_RISE(Thres_Rise)); + + temp = LDO_BASE->LDO_BOD; + temp &= ~(LDO_MASK_REG_BOD_F | LDO_MASK_REG_BOD_R); + temp |= LDO_REG_BOD_F(Thres_Fall) | LDO_REG_BOD_R(Thres_Rise); + LDO_BASE->LDO_BOD = temp; +} + +/** + * @brief Enable BOD or not. + * @param newstatus This parameter can be one of the following values: + * @arg ENABLE: Enable bod. + * @arg DISABLE: Disable bod. + * @return None + */ +void BOR_Enable(u32 newstatus) +{ + if (newstatus == ENABLE) { + LDO_BASE->LDO_BOD |= LDO_BIT_REG_BOD_R_EN; + } else { + LDO_BASE->LDO_BOD &= ~LDO_BIT_REG_BOD_R_EN; + } +} + +/** + * @brief Set BOR interrupt mode debounce cycle. + * @param Option BOR mode. This parameter can be one of the following values: + * @arg BOR_RESET: BOR reset mode + * @arg BOR_INTR: BOR interrupt mode + * @param Dbnc_Value Debounce cycle in unit of ANA4M clock cycles. + * @arg 000: 0us + * @arg 001: 100us + * @arg 010: 500us + * @arg 011: 1000us + * @arg 100: 2000us + * @arg 101: 4000us + * @arg 110: 8000us + * @arg 111: 16000us + * @return None + */ +void BOR_DbncSet(u32 Option, u32 Dbnc_Value) +{ + u32 temp = 0; + if (BOR_INTR == Option) { + assert_param(IS_BOR_INTR_DBNC_THRES(Dbnc_Value)); + temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL); + temp &= ~AON_MASK_BOR_TDBC; + temp |= AON_BOR_TDBC(Dbnc_Value); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL, temp); + } +} + +/** + * @brief Clear BOR interrupt. + * @return None + */ +void BOR_ClearINT(void) +{ + u32 temp = 0; + + temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_AON_BOR_ISR); + temp |= AON_BIT_BOR_ISR; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_AON_BOR_ISR, temp); +} + +/** + * @brief Enable BOR. + * @param Option BOR mode. This parameter can be one of the following values: + * @arg BOR_RESET: BOR reset mode + * @arg BOR_INTR: BOR interrupt mode + * @return None + */ +void BOR_ModeSet(u32 Option) +{ + u32 temp = 0; + + if (BOR_INTR == Option) { + temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL); + temp |= AON_BIT_BOR_INTR_MODE; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL, temp); + + temp = HAL_READ32(PMC_BASE, WAK_MASK0_NP); + temp |= PMC_WAK_KM0_IMR_31_0(WAKE_SRC_BOR); + HAL_WRITE32(PMC_BASE, WAK_MASK0_NP, temp); + } else { + temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL); + temp &= ~AON_BIT_BOR_INTR_MODE; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_AON_BOR_CTRL, temp); + } +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_clk.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_clk.c index 414d4551..424551cf 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_clk.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_clk.c @@ -176,10 +176,10 @@ u32 OSC131K_Calibration(u32 ppm_limit) } cur_ppm = delta * 1000000 / target_40m_counter; - RTK_LOGI(TAG, "[CAL131K]: delta:%d target:%d PPM: %d PPM_Limit:%d \n", delta, target_40m_counter, cur_ppm, ppm_limit); + RTK_LOGI(TAG, "[CAL131K]: delta:%lu target:%lu PPM: %lu PPM_Limit:%lu \n", delta, target_40m_counter, cur_ppm, ppm_limit); if (cur_ppm >= ppm_limit) { - RTK_LOGE(TAG, "[CAL131K]: !!! cal fail !!! PPM: %d PPM_Limit:%d \n", cur_ppm, ppm_limit); + RTK_LOGE(TAG, "[CAL131K]: !!! cal fail !!! PPM: %lu PPM_Limit:%lu \n", cur_ppm, ppm_limit); assert_param(0); } @@ -354,10 +354,10 @@ u32 OSC4M_Calibration(u32 ppm_limit) cal_end: cur_ppm = delta * 1000000 / target_40m_counter; - RTK_LOGI(TAG, "[CAL4M]: delta:%d target:%d PPM: %d PPM_Limit:%d \n", delta, target_40m_counter, cur_ppm, ppm_limit); + RTK_LOGI(TAG, "[CAL4M]: delta:%lu target:%lu PPM: %lu PPM_Limit:%lu \n", delta, target_40m_counter, cur_ppm, ppm_limit); if (cur_ppm >= ppm_limit) { - RTK_LOGW(TAG, "[CAL4M]: PPM: %d PPM_Limit:%d \n", cur_ppm, ppm_limit); + RTK_LOGW(TAG, "[CAL4M]: PPM: %lu PPM_Limit:%lu \n", cur_ppm, ppm_limit); assert_param(0); } @@ -441,4 +441,67 @@ void OSC131K_Reset(void) /*reset osc 131k counter, only for RTL6845*/ LDO_BASE->LDO_32_OSC_XTAL_POW &= ~LDO_BIT_POW_32KOSC; LDO_BASE->LDO_32_OSC_XTAL_POW |= LDO_BIT_POW_32KOSC; -} \ No newline at end of file +} + +/** + * @brief Set specific APB peripheral's clock divider + * @param pdiv: Specifies the peripheral's cke offset address, divider, shift, and mask field. + * @note In some IP, the real work divider equals (regval + 1). + * @retval None + */ +void RCC_PeriphClockDivSet(const struct Rcc_ClkDiv *pdiv) +{ + u32 Regtmp; + + u32 GroupOffset = pdiv->CkdGroupOfs; + u32 DivMask = pdiv->BitMask; + + assert_param((GroupOffset == REG_LSYS_CKD_GRP0) || (GroupOffset == REG_LSYS_CKD_GRP1)); + + Regtmp = HAL_READ32(SYSTEM_CTRL_BASE, GroupOffset); + Regtmp &= (~DivMask); + Regtmp |= (((pdiv->DivVal) << (pdiv->DivShift)) & DivMask); + + HAL_WRITE32(SYSTEM_CTRL_BASE, GroupOffset, Regtmp); + +} + +/** + * @brief Check whether the APB peripheral's clock has been enabled or not + * @param APBPeriph_Clock_in: specifies the APB peripheral to check. + * This parameter can be one of @ref APBPeriph_UART0_CLOCK, APBPeriph_ATIM_CLOCK and etc. + * @retval TRUE: The APB peripheral's clock has been enabled + * FALSE: The APB peripheral's clock has not been enabled + */ +u8 RCC_PeriphClockEnableChk(u32 APBPeriph_Clock_in) +{ + u8 ret; + u32 CkeRegVal, CkeBitMask; + u32 CkeRegOffset = 0; + + u32 ClkRegIndx = (APBPeriph_Clock_in >> 30) & 0x03; + assert_param((ClkRegIndx == 0x0) || (ClkRegIndx == 0x1) || (ClkRegIndx == 0x3)); + + switch (ClkRegIndx) { + case 0x0: + CkeRegOffset = REG_LSYS_CKE_GRP0; + break; + case 0x1: + CkeRegOffset = REG_LSYS_CKE_GRP1; + break; + case 0x3: + CkeRegOffset = REG_AON_CLK; + break; + } + + CkeRegVal = HAL_READ32(SYSTEM_CTRL_BASE, CkeRegOffset); + CkeBitMask = APBPeriph_Clock_in & (~(BIT(31) | BIT(30))); + + if (CkeRegVal & CkeBitMask) { + ret = TRUE; + } else { + ret = FALSE; + } + + return ret; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_comparator.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_comparator.c new file mode 100644 index 00000000..3c6a17a3 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_comparator.c @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" + +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @addtogroup ADC + * @brief Comparator driver modules + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup COMP_Exported_Functions COMP Exported Functions + * @{ + */ + +/** + * @brief Initializes the parameters in the CMP_InitStruct with default value. + * @param CMP_InitStruct: pointer to a CMP_InitTypeDef structure that contains + * the configuration information for the Comparator peripheral. + * @retval None + */ +void CMP_StructInit(CMP_InitTypeDef *CMP_InitStruct) +{ + u8 i; + + for (i = 0; i < COMP_CH_NUM; i++) { + CMP_InitStruct->CMP_ChanCtrl[i].CMP_ChIndex = i; + CMP_InitStruct->CMP_ChanCtrl[i].CMP_Ref0 = 0; // Vref0 = 0.1*0=0v + CMP_InitStruct->CMP_ChanCtrl[i].CMP_Ref1 = 0x1F; // Vref1 = 0.1*31=3.1v + CMP_InitStruct->CMP_ChanCtrl[i].CMP_WakeType = COMP_WK_NONE; + CMP_InitStruct->CMP_ChanCtrl[i].CMP_WakeSysCtrl = COMP_WITHIN_REF0_AND_REF1; + CMP_InitStruct->CMP_ChanCtrl[i].CMP_WakeADCCtrl = COMP_WITHIN_REF0_AND_REF1; + } +} + +/** + * @brief Initializes the Comparator according to the specified parameters in CMP_InitStruct. + * @param CMP_InitStruct: pointer to a CMP_InitTypeDef structure that contains + * the configuration for the Comparator peripheral. + * @retval None + */ +void CMP_Init(CMP_InitTypeDef *CMP_InitStruct) +{ + u8 i, index; + u32 tmp, val_ch = 0; + + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + CMP_CHTypeDef *compChan = CMP_InitStruct->CMP_ChanCtrl; + + CMP_Cmd(DISABLE); + + tmp = comparator->COMP_INTR_CTRL; + + for (i = 0; i < COMP_CH_NUM; i++) { + index = compChan[i].CMP_ChIndex; + + val_ch |= (u32)(index << COMP_SHIFT_CHSW(i)); + + comparator->COMP_REF_CHx[index] = (u32)(COMP_REF0_CHx(compChan[i].CMP_Ref0) | COMP_REF1_CHx(compChan[i].CMP_Ref1)); + + if (compChan[i].CMP_WakeType & COMP_WK_ADC) { + tmp &= ~ COMP_MASK_WK_ADC_CTRL(index); + tmp |= (compChan[i].CMP_WakeADCCtrl << COMP_SHIFT_WK_ADC_CTRL(index)) | \ + COMP_WK_ADC_EN(index); + } + + if (compChan[i].CMP_WakeType & COMP_WK_SYS) { + tmp &= ~ COMP_MASK_WK_SYS_CTRL(index); + tmp |= (compChan[i].CMP_WakeSysCtrl << COMP_SHIFT_WK_SYS_CTRL(index)) | \ + COMP_WK_SYS_EN(index); + } + } + + comparator->COMP_INTR_CTRL = tmp; + comparator->COMP_CHSW_LIST = val_ch; + comparator->COMP_AUTO_SHUT = COMP_BIT_AUTO_SHUT; + + tmp = PLL_BASE->PLL_LPSD; + tmp |= PLL_BIT_SD_POSEDGE; + PLL_BASE->PLL_LPSD = tmp; +} + +/** + * @brief Enable or Disable the Comparator peripheral. + * @param NewState: new state of the Comparator peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CMP_Cmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + comparator->COMP_EN_TRIG |= COMP_BIT_ENABLE; + } else { + comparator->COMP_EN_TRIG &= ~COMP_BIT_ENABLE; + } +} + +/** + * @brief Indicate the Comparator is busy or not . + * @param None + * @retval busy status value: + * - 1: Busy + * - 0: Not Busy. + */ +u32 CMP_Busy(void) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (comparator->COMP_BUSY_STS & COMP_BIT_BUSY_STS) { + return 1; + } else { + return 0; + } +} + +/** + * @brief ENABLE/DISABLE the comparator's interrupt bits. + * @param Cmp_IT: specifies the interrupt bits to be configured. + * This parameter can be one or combinations of the following values: + * @arg COMP_IT_CTN_VS: Rising edge interrupt of hysteresis cmp result at continuous mode. + * @arg COMP_IT_CTN_VH: Rising edge interrupt of vref1 cmp result at continuous mode. + * @arg COMP_IT_CTN_VL: Rising edge interrupt of vref0 cmp result at continuous mode. + * @param NewState: ENABLE or DISABLE + * @note None + * @retval None + */ +void CMP_INTConfig(u32 Cmp_IT, u32 NewState) +{ + /* Check the parameters */ + assert_param(IS_COMP_IT(Cmp_IT)); + + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + /* Enable the Interrupt sources */ + comparator->COMP_INTR_CTRL |= COMP_IT_CONFIG(Cmp_IT); + } else { + /* Disable the Interrupt sources */ + comparator->COMP_INTR_CTRL &= ~COMP_IT_CONFIG(Cmp_IT); + } +} + +/** + * @brief Set the comparator's comparison detection mode. + * @param det_mode: can be one of the following values: + * @arg COMP_LEVEL_DETECT: Level detection mode. When the comparison criterion matches, bit_comp_wkx will send interrupt continuously. + * @arg COMP_EDGE_DETECT: Edge detection mode. When the comparison criterion matches, bit_comp_wkx will send interrupt once at the time of matching. + * @retval None + */ +void CMP_SetCompMode(u8 det_mode) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (COMP_LEVEL_DETECT == det_mode) { + comparator->COMP_INTR_CTRL &= ~COMP_BIT_IT_DET_MOD; + } else { + comparator->COMP_INTR_CTRL |= COMP_BIT_IT_DET_MOD; + } +} + +/** + * @brief Get value of Comparator Wakeup ADC/SYS Status Register . + * @param None + * @retval Current Comparator Wakeup ADC/SYS and cmp result's rising edge interrupt status + */ +u32 CMP_GetISR(void) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + return comparator->COMP_WK_STS; +} + +/** + * @brief Clear pending bit in Comparator Wakeup ADC/SYS Status Register. + * @param Cmp_IT: specifies the interrupt bits to be cleared. + * This parameter can be one or combinations of the following values: + * @arg COMP_IT_CTN_VS: Rising edge interrupt of hysteresis cmp result at continuous mode. + * @arg COMP_IT_CTN_VH: Rising edge interrupt of vref1 cmp result at continuous mode. + * @arg COMP_IT_CTN_VL: Rising edge interrupt of vref0 cmp result at continuous mode. + * @arg COMP_WK_SYS_EN(3): Channel3 wakeup system + * @arg COMP_WK_SYS_EN(2): Channel2 wakeup system + * @arg COMP_WK_SYS_EN(1): Channel1 wakeup system + * @arg COMP_WK_SYS_EN(0): Channel0 wakeup system + * @arg COMP_WK_ADC_EN(3): Channel3 wakeup ADC + * @arg COMP_WK_ADC_EN(2): Channel2 wakeup ADC + * @arg COMP_WK_ADC_EN(1): Channel1 wakeup ADC + * @arg COMP_WK_ADC_EN(0): Channel0 wakeup ADC + * @retval None + */ +void CMP_INTClearPendingBit(u32 Cmp_IT) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + comparator->COMP_WK_STS = Cmp_IT; +} + +/** + * @brief Get the comparison result . + * @param channel : the Comparator channel index + * @retval The comparison result of specified channel index. The return value can be: + * -0: when Vin < Vref0 + * -2: when Vin > Vref0 & Vin < Vref1 + * -3: when Vin > Vref1 + */ +u32 CMP_GetCompStatus(u8 channel) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + u32 value = (comparator->COMP_CH_STS & COMP_MASK_CH_STS(channel)) >> \ + COMP_SHIFT_CH_STS(channel); + + return value; +} + +/** + * @brief Reset the channel switch to default state. + * @param None + * @retval None + */ +void CMP_ResetCSwList(void) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + comparator->COMP_RST_LIST = COMP_BIT_RST_LIST; + comparator->COMP_RST_LIST = 0; +} + +/** + * @brief Enable or disable automatic shut after the analog conversion is done. + * @param NewState: can be one of the following value: + * @arg ENABLE: The analog module and mux will be disabled automatically after the analog conversion is done. + * @arg DISABLE: The analog module and mux will not be disabled. + * @retval None. + */ +void CMP_AutoShutCmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + comparator->COMP_AUTO_SHUT |= COMP_BIT_AUTO_SHUT; + } else { + comparator->COMP_AUTO_SHUT &= ~COMP_BIT_AUTO_SHUT; + } +} + +/** + * @brief Controls the automatic channel swtich enabled or disabled in Comparator Automatic Mode. + * @param NewState: can be one of the following value: + * @arg ENABLE: Enable the automatic channel switch. + * When setting this bit, an automatic channel switch starts from the first channel in the channel switch list. + * @arg DISABLE: Disable the automatic channel switch. + * If an automatic channel switch is in progess, writing 0 will terminate the automatic channel switch. + * @retval None. + */ +void CMP_AutoCSwCmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + comparator->COMP_AUTOSW_EN = COMP_BIT_AUTOSW_EN; + comparator->COMP_EN_TRIG |= COMP_BIT_EN_TRIG; + } else { + comparator->COMP_AUTOSW_EN = 0; + comparator->COMP_EN_TRIG &= ~COMP_BIT_EN_TRIG; + } +} + +/** + * @brief Enabled or disabled software-trigger channel switch in Comparator Software-Trigger Mode. + * @param NewState: can be one of the following value: + * @arg ENABLE: Enable the software-trigger channel switch. + * When setting this bit, do one channel switch in the channel switch list. + * @arg DISABLE: Disable the software-trigger channel switch. + * @retval None. + */ +void CMP_SwTrigCmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + comparator->COMP_EN_TRIG |= COMP_BIT_EN_TRIG; + } else { + comparator->COMP_EN_TRIG &= ~COMP_BIT_EN_TRIG; + } +} + +/** + * @brief Initialize the trigger timer when in Comparator Timer-Trigger Mode. + * @param Tim_Idx: The timer index would be used to make the Comparator module do a comparison. + * @param PeriodMs: Indicate the period of trigger timer. + * @param NewState: can be one of the following value: + * @arg ENABLE: Enable the Comparator timer trigger mode. + * @arg DISABLE: Disable the Comparator timer trigger mode. + * @retval None. + * @note Used in Comparator Timer-Trigger Mode, period range: 1ms ~ 131071ms. + */ +void CMP_TimerTrigCmd(u8 Tim_Idx, u32 PeriodMs, u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + RTIM_TimeBaseInitTypeDef TIM_InitStruct; + + assert_param(IS_ADC_VALID_TIM(Tim_Idx)); + assert_param(PeriodMs > 0 && PeriodMs < 131072); // avoid overflow + + comparator->COMP_EXT_TRIG_TIMER_SEL = Tim_Idx; + + if (NewState != DISABLE) { + RTIM_TimeBaseStructInit(&TIM_InitStruct); + TIM_InitStruct.TIM_Idx = Tim_Idx; + TIM_InitStruct.TIM_Period = (PeriodMs * 32768) / 1000; //ms to tick + + RTIM_TimeBaseInit(TIMx[Tim_Idx], &TIM_InitStruct, TIMx_irq[Tim_Idx], (IRQ_FUN)NULL, (u32)NULL); + RTIM_Cmd(TIMx[Tim_Idx], ENABLE); + + comparator->COMP_EXT_TRIG_CTRL = COMP_BIT_EXT_WK_TIMER; + } else { + RTIM_Cmd(TIMx[Tim_Idx], DISABLE); + comparator->COMP_EXT_TRIG_CTRL = 0; + } +} + +/** + * @brief Enable or disable continuous sample function in autoswitch mode. + * @param NewState: can be one of the following value: + * @arg ENABLE: Enable continuous sample function. + * @arg DISABLE: Disable continuous sample function. + * @note Continuous sample function can only take effect in autoswitch mode with autoshut disabled meanwhile. + * @retval None. + */ +void CMP_ContinousCmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + if (NewState != DISABLE) { + comparator->COMP_CONTINUOUS_CTRL_0 |= COMP_BIT_CONTINUOUS_EN; + } else { + comparator->COMP_CONTINUOUS_CTRL_0 &= ~COMP_BIT_CONTINUOUS_EN; + } +} + +/** + * @brief Enable or disable hysteresis circuit function in continuous function. + * @param NewState: can be one of the following value: + * @arg ENABLE: Enable hysteresis circuit function. + * @arg DISABLE: Disable hysteresis circuit function. + * @note Hysteresis circuit function can only take effect in continuous function. + * @retval None. + */ +void CMP_HystCmd(u32 NewState) +{ + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + u32 reg_chsw = comparator->COMP_CHSW_LIST; + + if (NewState != DISABLE) { + /* check whether in continuous mode */ + assert_param(comparator->COMP_CONTINUOUS_CTRL_0 & COMP_BIT_CONTINUOUS_EN); + assert_param(comparator->COMP_AUTOSW_EN & COMP_BIT_AUTOSW_EN); + assert_param((comparator->COMP_AUTO_SHUT & COMP_BIT_AUTO_SHUT) == 0); + assert_param(COMP_GET_CHSW_0(reg_chsw) == COMP_GET_CHSW_1(reg_chsw)); + assert_param(COMP_GET_CHSW_1(reg_chsw) == COMP_GET_CHSW_2(reg_chsw)); + assert_param(COMP_GET_CHSW_2(reg_chsw) == COMP_GET_CHSW_3(reg_chsw)); + + comparator->COMP_CONTINUOUS_CTRL_0 |= COMP_BIT_HYST_EN; + } else { + comparator->COMP_CONTINUOUS_CTRL_0 &= ~COMP_BIT_HYST_EN; + } +} + +/** + * @brief Select specified comparison result as ZCD output. + * @param Src_Type: Comparison result type. + * This parameter can be one of the following values: + * @arg COMP_ZCD_SRC_NONE: None. + * @arg COMP_ZCD_SRC_VHOUT: ZCD out is from high level Vref1 cmp. + * @arg COMP_ZCD_SRC_VLOUT: ZCD out is from low level Vref0 cmp. + * @arg COMP_ZCD_SRC_VSOUT: ZCD out is from Hysteresis cmp. + * @note Make sure hysteresis function is enabled when select COMP_ZCD_SRC_VSOUT. + * @retval None. + */ +void CMP_SetZcdSrc(u32 Src_Type) +{ + /* Check the parameters */ + assert_param(IS_COMP_ZCD_SRC_TYPE(Src_Type)); + + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + u32 temp = comparator->COMP_CONTINUOUS_CTRL_0; + temp &= ~ COMP_MASK_ZCD_SEL; + temp |= COMP_ZCD_SEL(Src_Type); + comparator->COMP_CONTINUOUS_CTRL_0 = temp; + +} + +/** + * @brief Set debounce counter for comparison output of different types. + * @param Dbc_Type: Indicate the comparison type. + * This parameter can be one of the following values: + * @arg COMP_DBC_VS: Debounce result of hysteresis cmp. + * @arg COMP_DBC_VH: Debounce result of high level Vref1 cmp. + * @arg COMP_DBC_VL: Debounce result of lov level Vref0 cmp. + * @param Dbc_Cnt: Debounce counter to be set. + * @note Dbc_Cnt = 0 means debounce function is disabled. + * @retval None. + */ +void CMP_SetDbcCnt(u8 Dbc_Type, u32 Dbc_Cnt) +{ + /* Check the parameters */ + assert_param(IS_COMP_DBC_TYPE(Dbc_Type)); + + CMP_TypeDef *comparator = CMP_DEV; + + if (TrustZone_IsSecure()) { + comparator = CMP_DEV_S; + } + + /* Set debounce counter for Hysterisis comparison result S_out */ + if (COMP_DBC_VS == Dbc_Type) { + /* Check the parameters */ + assert_param(IS_COMP_VS_BC_CNT(Dbc_Cnt)); + + u32 temp = comparator->COMP_CONTINUOUS_CTRL_0; + temp &= ~ COMP_MASK_VS_DBC_CNT; + temp |= COMP_VS_DBC_CNT(Dbc_Cnt); + comparator->COMP_CONTINUOUS_CTRL_0 = temp; + /* Set debounce counter for Vref1 comparison result H_out */ + } else if (COMP_DBC_VH == Dbc_Type) { + /* Check the parameters */ + assert_param(IS_COMP_VH_BC_CNT(Dbc_Cnt)); + + u32 temp = comparator->COMP_CONTINUOUS_CTRL_1; + temp &= ~ COMP_MASK_VH_DBC_CNT; + temp |= COMP_VH_DBC_CNT(Dbc_Cnt); + comparator->COMP_CONTINUOUS_CTRL_1 = temp; + /* Set debounce counter for Vref0 comparison result L_out */ + } else if (COMP_DBC_VL == Dbc_Type) { + /* Check the parameters */ + assert_param(IS_COMP_VL_BC_CNT(Dbc_Cnt)); + + u32 temp = comparator->COMP_CONTINUOUS_CTRL_1; + temp &= ~ COMP_MASK_VL_DBC_CNT; + temp |= COMP_VL_DBC_CNT(Dbc_Cnt); + comparator->COMP_CONTINUOUS_CTRL_1 = temp; + } + +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_fault_handle.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_fault_handle.c new file mode 100644 index 00000000..6b585827 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_fault_handle.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +#include "ameba_v8m_crashdump.h" +#include "ameba_fault_handle.h" + +static const char *const TAG = "FAULT"; + +#if defined(CONFIG_ARM_CORE_CM4) +/* Redefine secure fault handler and replace old INT_SecureFault in rom code. */ +void HANDLER_SecureFault(void) +{ + __ASM volatile( + "MRS R0, MSP_NS \n\t" + "MRS R1, PSP_NS \n\t" + "MOV R2, LR \n\t" + "MRS R3, MSP_NS \n\t" + "STMDB R3!, {R4-R11} \n\t" //Note: [MSPLIM_NS, MSP_NS] may overflow, MSP_NS is not update. + "MOV R3, #4 \n\t" + "B Fault_Handler \n\t" + ); +} + +void HANDLER_MemFault(void) +{ + __ASM volatile( + "MRS R0, MSP \n\t" + "MRS R1, PSP \n\t" + "MOV R2, LR \n\t" + "MOV R3, #3 \n\t" + "PUSH {R4-R11} \n\t" + "B Fault_Handler \n\t" + ); +} + +void HANDLER_BusFault(void) +{ + __ASM volatile( + "MRS R0, MSP \n\t" + "MRS R1, PSP \n\t" + "MOV R2, LR \n\t" + "MOV R3, #2 \n\t" + "PUSH {R4-R11} \n\t" + "B Fault_Handler \n\t" + ); +} + +void HANDLER_UsageFault(void) +{ + __ASM volatile( + "MRS R0, MSP \n\t" + "MRS R1, PSP \n\t" + "MOV R2, LR \n\t" + "MOV R3, #1 \n\t" + "PUSH {R4-R11} \n\t" + "B Fault_Handler \n\t" + ); +} + +void HANDLER_HardFault(void) +{ + __ASM volatile( + "MRS R0, MSP \n\t" + "MRS R1, PSP \n\t" + "MOV R2, LR \n\t" + "MOV R3, #0 \n\t" + "PUSH {R4-R11} \n\t" + "B Fault_Handler \n\t" + ); +} +void Fault_Handler(uint32_t mstack[], uint32_t pstack[], uint32_t lr_value, uint32_t fault_id) +{ + uint32_t *cstack; + + uint32_t *extra_regs = mstack; + + uint32_t control_ns = 0; + + uint32_t regs[17] = {0x0}; + + u8 is_psp = 0; + + enum { + REG_EXCR = 0, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8, REG_R9, REG_R10, REG_R11, \ + REG_R0, REG_R1, REG_R2, REG_R3, REG_R12, REG_LR, REG_EPC, REG_xPSR, REG_END + }; + /* If Bit[0] is 1, here is Secure world. */ + if (lr_value & EXC_RETURN_ES) { + /* 1.1 Exception cames from secure world. */ + if (lr_value & EXC_RETURN_S) { + /* Whether PSP_S has been used*/ + if ((lr_value & EXC_RETURN_MODE) && (lr_value & EXC_RETURN_SPSEL)) { + is_psp = 1; + } + /* 1.2 Exception cames from non-secure world.*/ + } else { + /* what stack was used according to control_ns[1] in non-secure world!*/ + control_ns = __TZ_get_CONTROL_NS(); + if ((lr_value & EXC_RETURN_MODE) && (control_ns & CONTROL_SPSEL_Msk)) { + is_psp = 1; + } + } + + } else { + /* 2.1 Non-Secure world cannot dump registers about exception from secure world. */ + if (lr_value & EXC_RETURN_S) { + RTK_LOGA(TAG, "\nNon-Secure world cannot dump registers about exception from secure world!\n"); + while (1); + /* 2.2 Non-secure exception from non-secure world!*/ + } else { + if ((lr_value & EXC_RETURN_MODE) && (lr_value & EXC_RETURN_SPSEL)) { + is_psp = 1; + } + } + } + + regs[REG_EXCR] = lr_value; + /* put r4-r11 to mstack before + High addr -> | xxx | <--- &extra_regs[0] is mstack; + ^ | R11 | <--- extra_regs[-1] + | | R10 | + | | ... | + Low addr -> | R4 | <--- extra_regs[-8]*/ + + extra_regs--; //point to R11 + for (int i = REG_R4; i <= REG_R11; i++) { + regs[i] = extra_regs[-REG_R11 + i]; + } + + cstack = is_psp ? pstack : mstack; + + for (int i = REG_R0; i < REG_END; i++) { + regs[i] = cstack[i - REG_R0]; + } + + crash_dump((uint32_t *)cstack[REG_EPC], cstack, regs); + + if (fault_id == SECUREFAULT_ID) { + RTK_LOGA(TAG, "SFSR = 0x%08lx\r\n", SAU->SFSR); + RTK_LOGA(TAG, "SFAR = 0x%08lx\r\n", SAU->SFAR); + } + if (control_ns) { + RTK_LOGA(TAG, "CONTROL_NS = 0x%08lX\r\n", control_ns); + } + RTK_LOGA(TAG, "SHCSR = 0x%08lx\r\n", SCB->SHCSR); + RTK_LOGA(TAG, "AIRCR = 0x%08lx\r\n", SCB->AIRCR); + RTK_LOGA(TAG, "CONTROL = 0x%08lx\r\n", __get_CONTROL()); + + extern void INT_HardFault_C(uint32_t mstack[], uint32_t pstack[], uint32_t lr_value, uint32_t fault_id); + INT_HardFault_C(mstack, pstack, lr_value, fault_id); +} +#else +void HANDLER_HardFault(void) +{ + __ASM volatile( + "MRS R0, MSP \n\t" + "MRS R1, PSP \n\t" + "MOV R2, LR \n\t" /* Third parameter is LR current value */ + "MOV R3, #0 \n\t" + "PUSH {R4-R7} \n\t" + "MOV R6, #16 \n\t" + "ADD R4, R0, R6 \n\t" /* Skip R4-R7, and point to top of mstack*/ + "MOV R5, R8 \n\t" + "STR R5, [R4, #0] \n\t" + "MOV R5, R9 \n\t" + "STR R5, [R4, #4] \n\t" + "MOV R5, R10 \n\t" + "STR R5, [R4, #8] \n\t" + "MOV R5, R11 \n\t" + "STR R5, [R4, #12] \n\t" + "B Fault_Handler \n\t" + ); +} + +void Fault_Handler(uint32_t mstack[], uint32_t pstack[], uint32_t lr_value, uint32_t fault_id) +{ + RTK_LOGA(TAG, "Hard Fault Patch (KM0)\r\n"); + if (fault_id == 0) { + RTK_LOGA(TAG, "Hard Fault: \r\n"); + } else { + RTK_LOGA(TAG, "Unsupported faults\r\n"); + while (1); + } + uint32_t *cstack; + + uint32_t *extra_regs = mstack; + + uint32_t regs[17] = {0x0}; + + u8 is_psp = 0; + + enum { + REG_EXCR = 0, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8, REG_R9, REG_R10, REG_R11, \ + REG_R0, REG_R1, REG_R2, REG_R3, REG_R12, REG_LR, REG_EPC, REG_xPSR, REG_END + }; + + if (lr_value & BIT(3)) { //Thread Mode + if (lr_value & BIT(2)) { //PSP + is_psp = 1; + } + } + regs[REG_EXCR] = lr_value; + /* MSP stack + High addr -> | xxx | <--- &extra_regs[0] is mstack; + ^ | R7 | <--- extra_regs[-1] + | | ... | + | | R4 | + | | R8 | + | | ... | + Low addr -> | R11 | <--- extra_regs[-8]*/ + + //point to R7, R8 ~ R11 were not saved. + extra_regs--; + for (int i = REG_R4; i <= REG_R7; i++) { + regs[i] = extra_regs[-REG_R7 + i]; + } + for (int i = REG_R8; i <= REG_R11; i++) { + regs[i] = extra_regs[-i]; + } + cstack = is_psp ? pstack : mstack; + + for (int i = REG_R0; i < REG_END; i++) { + regs[i] = cstack[i - REG_R0]; + } + + crash_dump((uint32_t *)cstack[REG_EPC], cstack, regs); + + RTK_LOGA(TAG, "MSP = %p\r\n", mstack); + RTK_LOGA(TAG, "PSP = %p\r\n", pstack); + RTK_LOGA(TAG, "CONTROL = 0x%08lX\r\n", __get_CONTROL()); + RTK_LOGA(TAG, "SVC priority: %lu\r\n", __NVIC_GetPriority(SVCall_IRQn)); + RTK_LOGA(TAG, "PendSVC priority: %lu\r\n", __NVIC_GetPriority(PendSV_IRQn)); + RTK_LOGA(TAG, "Systick priority: %lu\r\n", __NVIC_GetPriority(SysTick_IRQn)); + RTK_LOGA(TAG, "\r\n"); + + extern void INT_HardFault_C(u32 * stack); + INT_HardFault_C(cstack); +} +#endif + +void Fault_Hanlder_Redirect(crash_on_task crash_on_task_func) +{ + crash_task_info = crash_on_task_func; +#ifdef CONFIG_ARM_CORE_CM4 + NewVectorTable[3] = (HAL_VECTOR_FUN)HANDLER_HardFault; + NewVectorTable[4] = (HAL_VECTOR_FUN)HANDLER_MemFault; + NewVectorTable[5] = (HAL_VECTOR_FUN)HANDLER_BusFault; + NewVectorTable[6] = (HAL_VECTOR_FUN)HANDLER_UsageFault; + NewVectorTable[7] = (HAL_VECTOR_FUN)HANDLER_SecureFault; +#else + NewVectorTable[3] = (HAL_VECTOR_FUN)HANDLER_HardFault; +#endif +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_memcpy.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_memcpy.c new file mode 100644 index 00000000..9cfe7888 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_memcpy.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" + +struct gdma_memcopy_s { + u32 ch_num; + volatile u32 dma_done; + GDMA_InitTypeDef GDMA_InitStruct; +}; + +TIMESENSITIVE_DATA_SECTION +struct gdma_memcopy_s gdma_memcpy; +//rtos_sema_t dma_memcpy_sema = NULL; + +TIMESENSITIVE_TEXT_SECTION +static u32 memcpy_gdma_int(void *pData) +{ + /* To avoid gcc warnings */ + UNUSED(pData); + + /* Clear Pending ISR */ + GDMA_ClearINT(0, gdma_memcpy.ch_num); + GDMA_Cmd(0, gdma_memcpy.ch_num, DISABLE); + + gdma_memcpy.dma_done = 1; + //rtos_sema_give(dma_memcpy_sema); + return TRUE; +} + +TIMESENSITIVE_TEXT_SECTION +void memcpy_gdma_init(void) +{ + gdma_memcpy.dma_done = 1; + gdma_memcpy.ch_num = GDMA_ChnlAlloc(0, (IRQ_FUN)memcpy_gdma_int, (u32)NULL, INT_PRI_MIDDLE); + + GDMA_StructInit(&(gdma_memcpy.GDMA_InitStruct)); + gdma_memcpy.GDMA_InitStruct.GDMA_ChNum = gdma_memcpy.ch_num; + gdma_memcpy.GDMA_InitStruct.GDMA_Index = 0; + gdma_memcpy.GDMA_InitStruct.GDMA_IsrType = (TransferType | ErrType); + + gdma_memcpy.GDMA_InitStruct.GDMA_SrcMsize = MsizeEight; + gdma_memcpy.GDMA_InitStruct.GDMA_DstMsize = MsizeEight; + + //rtos_sema_create_binary(&dma_memcpy_sema); +} + +TIMESENSITIVE_TEXT_SECTION +static inline u32 memcpy_use_cpu(void *dest, void *src, u32 size) +{ + /* To avoid gcc warnings */ + (void) dest; + (void) src; + + if (size < 128) { + return TRUE; + } + + if (gdma_memcpy.dma_done == 0) { + return TRUE; + } + + return FALSE; +} + +TIMESENSITIVE_TEXT_SECTION +int memcpy_gdma(void *dest, void *src, u32 size) +{ + u32 size_4byte = size & ~(0x03); + u32 left = size & (0x03); + + if (memcpy_use_cpu(dest, src, size) == TRUE) { + _memcpy(dest, src, size); + + return 0; + } + gdma_memcpy.dma_done = 0; + + if (((u32)(src) & 0x03) || ((u32)(dest) & 0x03)) { + gdma_memcpy.GDMA_InitStruct.GDMA_SrcDataWidth = TrWidthOneByte; + gdma_memcpy.GDMA_InitStruct.GDMA_DstDataWidth = TrWidthOneByte; + gdma_memcpy.GDMA_InitStruct.GDMA_BlockSize = size; + } else { + /* 4-bytes aligned, move 4 bytes each transfer */ + gdma_memcpy.GDMA_InitStruct.GDMA_SrcDataWidth = TrWidthFourBytes; + gdma_memcpy.GDMA_InitStruct.GDMA_DstDataWidth = TrWidthFourBytes; + gdma_memcpy.GDMA_InitStruct.GDMA_BlockSize = size_4byte >> 2; + + if (left != 0) { + char *dst0 = (char *) dest + size_4byte; + char *src0 = (char *) src + size_4byte; + while (left--) { + *dst0++ = *src0++; + } + } + } + + gdma_memcpy.GDMA_InitStruct.GDMA_SrcAddr = (u32)(src); + gdma_memcpy.GDMA_InitStruct.GDMA_DstAddr = (u32)(dest); + GDMA_Init(0, gdma_memcpy.ch_num, &(gdma_memcpy.GDMA_InitStruct)); + GDMA_Cmd(0, gdma_memcpy.ch_num, ENABLE); + + //rtos_sema_take(dma_memcpy_sema, portMAX_DELAY); + while (gdma_memcpy.dma_done == 0); + + return 0; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_ram.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_ram.c index 3b4ce012..8663b208 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_ram.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_gdma_ram.c @@ -868,15 +868,27 @@ GDMA_Abort(u8 GDMA_Index, u8 GDMA_ChNum) return TRUE; } - -/** - * @} - */ - /** - * @} - */ + * @brief Check if the channel is active + * + * @param GDMA_Index 0 + * @param GDMA_ChNum 0 ~ 7 + * @retval TRUE/FALSE + */ +__weak +u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum) +{ + GDMA_TypeDef *GDMA = ((GDMA_TypeDef *) GDMA_BASE); + if (TrustZone_IsSecure()) { + GDMA = ((GDMA_TypeDef *) GDMA0_REG_BASE_S); + } + /* Check the parameters */ + assert_param(IS_GDMA_Index(GDMA_Index)); + assert_param(IS_GDMA_ChannelNum(GDMA_ChNum)); -/** - * @} - */ + if ((GDMA->ChEnReg & BIT(GDMA_ChNum)) && \ + ((GDMA->CH[GDMA_ChNum].CFG_LOW & BIT_CFGx_L_INACTIVE) == 0)) { + return TRUE; + } + return FALSE; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_gpio.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_gpio.c index 71fc7e89..542e41ac 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_gpio.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_gpio.c @@ -6,6 +6,34 @@ #include "ameba_soc.h" +void GPIO_Init(GPIO_InitTypeDef *GPIO_InitStruct) +{ + /* open gpio function and clock */ + //RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + + assert_param(GPIO_InitStruct->GPIO_Mode <= GPIO_Mode_INT); + + /* GPIO Pad shouddown control: Turn on the corresponding GPIO Pad and pinmux to GPIO */ + Pinmux_Config(GPIO_InitStruct->GPIO_Pin, PINMUX_FUNCTION_GPIO); + + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_INT) { + GPIO_Direction(GPIO_InitStruct->GPIO_Pin, GPIO_Mode_IN); + PAD_PullCtrl(GPIO_InitStruct->GPIO_Pin, GPIO_InitStruct->GPIO_PuPd); + + GPIO_INTMode(GPIO_InitStruct->GPIO_Pin, ENABLE, GPIO_InitStruct->GPIO_ITTrigger, + GPIO_InitStruct->GPIO_ITPolarity, GPIO_InitStruct->GPIO_ITDebounce); + } else { + GPIO_INTMode(GPIO_InitStruct->GPIO_Pin, DISABLE, 0, 0, 0); + + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) { + GPIO_Direction(GPIO_InitStruct->GPIO_Pin, GPIO_Mode_OUT); + } else if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IN) { + GPIO_Direction(GPIO_InitStruct->GPIO_Pin, GPIO_Mode_IN); + PAD_PullCtrl(GPIO_InitStruct->GPIO_Pin, GPIO_InitStruct->GPIO_PuPd); + } + } +} + static GPIO_TypeDef *GPIO_PortAddrGet(u32 GPIO_Port) { GPIO_TypeDef *GPIO = NULL; diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_api.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_api.c index b130395a..095d7d6c 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_api.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_api.c @@ -181,4 +181,4 @@ PIPC_MSG_STRUCT ipc_get_message(u32 IPC_Dir, u8 IPC_ChNum) DCache_Invalidate((u32)&IPC_MSG[msg_idx], sizeof(IPC_MSG_STRUCT)); return &IPC_MSG[msg_idx]; -} \ No newline at end of file +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_ram.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_ram.c index ac97e82d..ea89bfd6 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_ram.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ipc_ram.c @@ -208,4 +208,4 @@ IPC_TypeDef *IPC_GetDevById(u32 cpu_id) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ir.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ir.c new file mode 100644 index 00000000..056b0268 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ir.c @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" + +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup IR +* @brief IR driver modules +* @{ +*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup IR_Exported_Functions IR Exported Functions + * @{ + */ + +/** + * @brief Deinitialize the IR peripheral registers to their default values. + * @param None. + * @retval None + */ +void IR_DeInit(void) +{ + //1TODO: + // RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE); +} + + +/** + * @brief Initialize the IR peripheral according to the specified + * parameters in the IR_InitStruct + * @param IR_InitStruct: pointer to a IR_InitTypeDef structure that + * contains the configuration information for the specified IR peripheral + * @retval None + */ +void IR_Init(IR_TypeDef *IRx, IR_InitTypeDef *IR_InitStruct) +{ + /* Configure IR clock divider. Formula: IR_CLK = IO_CLK/(1+IR_CLK_DIV) */ + IRx->IR_CLK_DIV = (IR_InitStruct->IR_Clock) / (IR_InitStruct->IR_Freq) - 1; + + if (IR_InitStruct->IR_Mode == IR_MODE_TX) { + /* Check the parameters in TX mode */ + assert_param(IS_IR_FREQUENCY(IR_InitStruct->IR_Freq)); + + /* save IR TX interrupt configuration */ + IRx->IR_TX_CONFIG &= 0x3F; + + /* Configure TX mode parameters and disable all TX interrupt */ + IRx->IR_TX_CONFIG |= (IR_TX_DUTY_NUM((IRx->IR_CLK_DIV + 1) / (IR_InitStruct->IR_DutyCycle))) | \ + (IR_TX_DATA_TYPE_SET(IR_InitStruct->IR_TxInverse)) | \ + (IR_TX_FIFO_LEVEL_TH(IR_InitStruct->IR_TxFIFOThrLevel)); + if (IR_InitStruct->IR_TxIdleLevel) { + IRx->IR_TX_CONFIG |= IR_BIT_TX_IDLE_STATE; + } else { + IRx->IR_TX_CONFIG &= ~IR_BIT_TX_IDLE_STATE; + } + + /* Clear all TX interrupt and TX FIFO */ + IRx->IR_TX_INT_CLR = IR_TX_INT_ALL_CLR | IR_BIT_TX_FIFO_CLR; + + /* Configure IR tx compensation clock divisor. */ + IRx->IR_TX_COMPE_DIV = (IR_InitStruct->IR_Clock) / (IR_InitStruct->IR_TxCOMP_CLK) - 1; + } else { + /* Check the parameters in RX mode */ + assert_param(IS_IR_RX_TRIGGER_EDGE(IR_InitStruct->IR_RxTriggerMode)); + + /* Enable RX mode */ + IRx->IR_TX_CONFIG |= IR_BIT_MODE_SEL; + /* Configure RX mode parameters and disable all RX interrupt */ + if (IR_InitStruct->IR_RxStartMode) + IRx->IR_RX_CONFIG = IR_BIT_RX_START_MODE | \ + (IR_RX_TRIGGER_MODE(IR_InitStruct->IR_RxTriggerMode)) | \ + (IR_RX_FILTER_STAGETX(IR_InitStruct->IR_RxFilterTime)) | \ + (IR_RX_FIFO_LEVEL_TH(IR_InitStruct->IR_RxFIFOThrLevel)); + else + IRx->IR_RX_CONFIG = (IR_RX_TRIGGER_MODE(IR_InitStruct->IR_RxTriggerMode)) | \ + (IR_RX_FILTER_STAGETX(IR_InitStruct->IR_RxFilterTime)) | \ + (IR_RX_FIFO_LEVEL_TH(IR_InitStruct->IR_RxFIFOThrLevel)); + + if (IR_InitStruct->IR_RxFIFOFullCtrl) { + IRx->IR_RX_CONFIG |= IR_BIT_RX_FIFO_DISCARD_SET; + } else { + IRx->IR_RX_CONFIG &= ~IR_BIT_RX_FIFO_DISCARD_SET; + } + + /* Configure IR RX counter threshold parameters */ + if (IR_InitStruct->IR_RxCntThrType) { + IRx->IR_RX_CNT_INT_SEL = IR_BIT_RX_CNT_THR_TRIGGER_LV | IR_RX_CNT_THR(IR_InitStruct->IR_RxCntThr); + } else { + IRx->IR_RX_CNT_INT_SEL = IR_RX_CNT_THR(IR_InitStruct->IR_RxCntThr); + } + + /* Clear all RX interrupt and RX FIFO */ + IRx->IR_RX_INT_CLR = IR_RX_INT_ALL_CLR | IR_BIT_RX_FIFO_CLR; + } +} + +/** + * @brief Fill each IR_InitStruct member with its default value. + * @param IR_InitStruct: pointer to an IR_InitTypeDef structure which will be initialized. + * @retval None + */ +void IR_StructInit(IR_InitTypeDef *IR_InitStruct) +{ + IR_InitStruct->IR_Clock = 100000000; /*100MHz*/ + IR_InitStruct->IR_Freq = 38000; + IR_InitStruct->IR_DutyCycle = 3; + IR_InitStruct->IR_Mode = IR_MODE_TX; + IR_InitStruct->IR_TxIdleLevel = IR_IDLE_OUTPUT_LOW; + IR_InitStruct->IR_TxInverse = IR_TX_DATA_NORMAL_CARRIER_NORMAL; + IR_InitStruct->IR_TxFIFOThrLevel = 0; + IR_InitStruct->IR_TxCOMP_CLK = 1000000; /*1M*/ + IR_InitStruct->IR_RxStartMode = IR_RX_AUTO_MODE; + IR_InitStruct->IR_RxFIFOThrLevel = 0; + IR_InitStruct->IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST; + IR_InitStruct->IR_RxTriggerMode = IR_RX_DOUBLE_EDGE; + IR_InitStruct->IR_RxFilterTime = IR_RX_FILTER_TIME_50NS; + IR_InitStruct->IR_RxCntThrType = IR_RX_COUNT_LOW_LEVEL; + IR_InitStruct->IR_RxCntThr = 0x23a; /* This value can be 0 to 0x7fffffff */ +} + +/** + * @brief Enable or disable the selected IR mode. + * @param mode: selected IR operation mode. + * This parameter can be the following values: + * @arg IR_MODE_TX: Transmission mode. + * @arg IR_MODE_RX: Receiving mode. + * @param NewState: new state of the operation mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_Cmd(IR_TypeDef *IRx, u32 mode, u32 NewState) +{ + if (NewState == ENABLE) { + if (mode == IR_MODE_TX) { + IRx->IR_TX_CONFIG |= IR_BIT_TX_START; + } else { + IRx->IR_RX_CONFIG |= IR_BIT_RX_START; + } + + } else if (NewState == DISABLE) { + if (mode == IR_MODE_TX) { + IRx->IR_TX_CONFIG &= ~IR_BIT_TX_START; + } else { + IRx->IR_RX_CONFIG &= ~IR_BIT_RX_START; + } + + } +} + +/** + * @brief Configure counter threshold value in receiving mode.You can use it to stop receiving IR data. + * @param IR_RxCntThrType: + * This parameter can be the following values: + * @arg IR_RX_Count_Low_Level: Low level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * @arg IR_RX_Count_High_Level: High level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * @param IR_RxCntThr: Configure IR Rx counter threshold value which can be 0 to 0x7fffffffUL. + * @retval None + */ +void IR_SetRxCounterThreshold(IR_TypeDef *IRx, u32 IR_RxCntThrType, u32 IR_RxCntThr) +{ + /* Configure IR RX counter threshold parameters */ + IRx->IR_RX_CNT_INT_SEL = (IR_RxCntThrType) | IR_RX_CNT_THR(IR_RxCntThr); +} + +/** + * @brief Send data. + * @param buf: data buffer to send. + * @param length: buffer length. + * @param IsLastPacket: + * This parameter can be the following values: + * @arg ENABLE: The last data in IR packet and there is no continous data.In other words, An infrared data transmission is completed. + * @arg DISABLE: There is data to be transmitted continuously. + * @retval None + */ +void IR_SendBuf(IR_TypeDef *IRx, u32 *pBuf, u32 len, u32 IsLastPacket) +{ + if (len == 0) { + return; + } + + while (--len) { + IRx->IR_TX_FIFO = *pBuf++; + } + + /* If send the last IR packet, SET the following bit */ + if (IsLastPacket == TRUE) { + IRx->IR_TX_FIFO = *pBuf | IR_BIT_TX_DATA_END_FLAG; + } else { + IRx->IR_TX_FIFO = *pBuf; + } + +} + +/** + * @brief Read data From RX FIFO. + * @param buf: buffer address to receive data. + * @param length: read data length. + * @retval None + */ +void IR_ReceiveBuf(IR_TypeDef *IRx, u32 *pBuf, u32 len) +{ + while (len--) { + *pBuf++ = IRx->IR_RX_FIFO; + } + +} + +/** + * @brief Enables or disables the specified IR interrupts. + * @param IR_INT: specifies the IR interrupts sources to be enabled or disabled. + * This parameter can be the following values: + * @arg IR_TX_FIFO_EMPTY_INT_EN: TX FIFO empty interrupt. + * @arg IR_TX_FIFO_LEVEL_INT_EN: TX FIFO threshold interrupt. + * @arg IR_TX_FIFO_OVER_INT_EN: TX FIFO overflow interrupt. + * @arg IR_RX_FIFO_FULL_INT_EN: RX FIFO full interrupt. + * @arg IR_RX_FIFO_LEVEL_INT_EN: RX FIFO threshold interrupt. + * @arg IR_RX_CNT_OF_INT_EN: RX counter overflow interrupt. + * @arg IR_RX_FIFO_OF_INT_EN: RX FIFO overflow interrupt. + * @arg IR_RX_CNT_THR_INT_EN: RX counter threshold interrupt. + * @arg IR_RX_FIFO_ERROR_INT_EN: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @param NewState: new state of the specified IR interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_INTConfig(IR_TypeDef *IRx, u32 IR_INT, u32 newState) +{ + if (IR_MODE(IRx->IR_TX_CONFIG)) { + assert_param(IS_RX_INT(IR_INT)); + + if (newState == ENABLE) { + IRx->IR_RX_CONFIG |= IR_INT; + } else { + IRx->IR_RX_CONFIG &= ~IR_INT; + } + } else { + assert_param(IS_TX_INT(IR_INT)); + + if (newState == ENABLE) { + IRx->IR_TX_CONFIG |= IR_INT; + } else { + IRx->IR_TX_CONFIG &= ~IR_INT; + } + } +} + +/** + * @brief Mask or unmask the specified IR interrupts. + * @param IR_INT: specifies the IR interrupts sources to be mask or unmask. + * This parameter can be the following values: + * @arg IR_TX_FIFO_EMPTY_INT_MASK: TX FIFO empty interrupt mask. + * @arg IR_TX_FIFO_LEVEL_INT_MASK: TX FIFO threshold interrupt mask. + * @arg IR_TX_FIFO_OVER_INT_MASK: TX FIFO overflow interrupt mask. + * @arg IR_RX_FIFO_FULL_INT_Msk: RX FIFO full interrupt mask. + * @arg IR_RX_FIFO_LEVEL_INT_Msk: RX FIFO threshold interrupt mask. + * @arg IR_RX_CNT_OF_INT_Msk: RX counter overflow interrupt mask. + * @arg IR_RX_FIFO_OF_INT_Msk: RX FIFO overflow interrupt mask. + * @arg IR_RX_CNT_THR_INT_Msk: RX counter threshold interrupt mask. + * @arg IR_RX_FIFO_ERROR_INT_Msk: RX FIFO error read interrupt mask. Trigger when RX FIFO empty and read RX FIFO. + * @param NewState: new state of the specified IR interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_MaskINTConfig(IR_TypeDef *IRx, u32 IR_INT, u32 newState) +{ + if (IR_MODE(IRx->IR_TX_CONFIG)) { + assert_param(IS_RX_INT_MASK(IR_INT)); + + if (newState == ENABLE) { + IRx->IR_RX_CONFIG |= IR_INT; + } else { + IRx->IR_RX_CONFIG &= ~IR_INT; + } + + } else { + assert_param(IS_TX_INT_MASK(IR_INT)); + + if (newState == ENABLE) { + IRx->IR_TX_CONFIG |= IR_INT; + } else { + IRx->IR_TX_CONFIG &= ~IR_INT; + } + } +} + +/** + * @brief Get the specified IR interrupt status. + * @retval The new state of IR_INT (SET or RESET). + */ +u32 IR_GetINTStatus(IR_TypeDef *IRx) +{ + u32 status; + + if (IR_MODE(IRx->IR_TX_CONFIG)) { + status = (IRx->IR_RX_SR); + } else { + status = (IRx->IR_TX_SR); + } + + /* Return the IR_INT status */ + return status; +} + +/** + * @brief Get the specified IR interrupt mask status. + * @retval The new mask state of IR_INT (SET or RESET). + */ +u32 IR_GetIMR(IR_TypeDef *IRx) +{ + u32 mask; + + if (IR_MODE(IRx->IR_TX_CONFIG)) { + mask = IRx->IR_RX_CONFIG & IR_RX_INT_ALL_MASK; + } else { + mask = IRx->IR_TX_CONFIG & IR_TX_INT_ALL_MASK; + } + + /* Return the IR_INT mask status */ + return mask; +} + +/** + * @brief Get the specified IR FSM status. + * @retval The new state of FSM (IDLE or RUN). + * @TRUE:RUN, FALSE:IDLE. + */ +u32 IR_FSMRunning(IR_TypeDef *IRx) +{ + u32 status = FALSE; + + if (IR_MODE(IRx->IR_TX_CONFIG)) { + if ((IRx->IR_RX_SR) & IR_BIT_RX_STATE) { + status = TRUE; + } + } else { + if ((IRx->IR_TX_SR) & IR_BIT_TX_STATUS) { + status = TRUE; + } + } + + return status; +} + +/** + * @brief Clear the IR interrupt pending bits. + * @param IR_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg IR_TX_FIFO_EMPTY_INT_CLR: Clear TX FIFO empty interrupt. + * @arg IR_TX_FIFO_LEVEL_INT_CLR: Clear TX FIFO threshold interrupt. + * @arg IR_TX_FIFO_OVER_INT_CLR: Clear TX FIFO overflow interrupt. + * @arg IR_RX_FIFO_FULL_INT_CLR: Clear RX FIFO full interrupt. + * @arg IR_RX_FIFO_LEVEL_INT_CLR: Clear RX FIFO threshold interrupt. + * @arg IR_RX_CNT_OF_INT_CLR: Clear RX counter overflow interrupt. + * @arg IR_RX_FIFO_OF_INT_CLR: Clear RX FIFO overflow interrupt. + * @arg IR_RX_CNT_THR_INT_CLR: Clear RX counter threshold interrupt. + * @arg IR_RX_FIFO_ERROR_INT_CLR: Clear RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @retval None + */ +void IR_ClearINTPendingBit(IR_TypeDef *IRx, u32 IR_CLEAR_INT) +{ + if (IR_MODE(IRx->IR_TX_CONFIG)) { + assert_param(IS_RX_INT_CLR(IR_CLEAR_INT)); + IRx->IR_RX_INT_CLR |= IR_CLEAR_INT; + } else { + assert_param(IS_TX_INT_CLR(IR_CLEAR_INT)); + IRx->IR_TX_INT_CLR |= IR_CLEAR_INT; + } +} + + +/** + * @brief Set tx threshold.when TX FIFO depth <= threshold value, trigger interrupt + * @param thd: tx threshold. + * @retval None + */ +void IR_SetTxThreshold(IR_TypeDef *IRx, uint8_t thd) +{ + u32 Tx_config; + + Tx_config = IRx->IR_TX_CONFIG; + Tx_config &= ~IR_MASK_TX_FIFO_LEVEL_TH; + Tx_config |= IR_TX_FIFO_LEVEL_TH(thd); + IRx->IR_TX_CONFIG = Tx_config; +} + + +/** + * @brief Set rx threshold.when RX FIFO depth > threshold value, trigger interrupt + * @param thd: rx threshold. + * @retval None + */ +void IR_SetRxThreshold(IR_TypeDef *IRx, uint8_t thd) +{ + u32 Rx_config; + + Rx_config = IRx->IR_RX_CONFIG; + Rx_config &= ~IR_MASK_RX_FIFO_LEVEL_TH; + Rx_config |= IR_RX_FIFO_LEVEL_TH(thd); + IRx->IR_RX_CONFIG = Rx_config; +} + + +/** + * @brief Get free size of TX FIFO . + * @param None + * @retval the free size of TX FIFO + */ +u32 IR_GetTxFIFOFreeLen(IR_TypeDef *IRx) +{ + return (IR_TX_FIFO_SIZE - IR_GET_TX_FIFO_OFFSET(IRx->IR_TX_SR)); //IR_TX_FIFO_SIZE - TX FIFO offset +} + + +/** + * @brief Get data size in RX FIFO. + * @param None + * @retval current data size in RX FIFO. + */ +u32 IR_GetRxDataLen(IR_TypeDef *IRx) +{ + return (IR_GET_RX_FIFO_OFFSET(IRx->IR_RX_SR)); +} + + +/** + * @brief Send one data. + * @param data: send data. + * @retval None + */ +void IR_SendData(IR_TypeDef *IRx, u32 data) +{ + IRx->IR_TX_FIFO = data; +} + + +/** + * @brief Start trigger only in manual receive mode. + * @param None. + * @retval None + */ +void IR_StartManualRxTrigger(IR_TypeDef *IRx) +{ + /* Start Rx manual mode */ + IRx->IR_RX_CONFIG |= IR_BIT_RX_MAN_START; +} + + +/** + * @brief Read one data. + * @param none + * @retval data which read from RX FIFO. + */ +u32 IR_ReceiveData(IR_TypeDef *IRx) +{ + return IRx->IR_RX_FIFO; +} + +/** + * @brief Clear IR TX FIFO. + * @param none + * @retval None + */ +void IR_ClearTxFIFO(IR_TypeDef *IRx) +{ + IRx->IR_TX_INT_CLR = IR_BIT_TX_FIFO_CLR; +} + + +/** + * @brief Clear IR RX FIFO. + * @param none + * @retval None + */ +void IR_ClearRxFIFO(IR_TypeDef *IRx) +{ + IRx->IR_RX_INT_CLR = IR_BIT_RX_FIFO_CLR; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_keyscan.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_keyscan.c new file mode 100644 index 00000000..cf27a2c3 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_keyscan.c @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" + +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup KSCAN +* @brief KSCAN driver modules +* @{ +*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup KSCAN_Exported_Functions KSCAN Exported Functions + * @{ + */ + +/** + * @brief Fills each KeyScan_InitStruct member with its default value. + * @param KeyScan_InitStruct: pointer to an KeyScan_InitTypeDef structure which will be initialized. + * @retval None + */ +void KeyScan_StructInit(KeyScan_InitTypeDef *KeyScan_InitStruct) +{ + /* Load HAL initial data structure default value */ + KeyScan_InitStruct->KS_ClkDiv = 199; + KeyScan_InitStruct->KS_ColSel = 0x03; + KeyScan_InitStruct->KS_RowSel = 0x03; + + KeyScan_InitStruct->KS_WorkMode = KS_REGULAR_SCAN_MODE; + + KeyScan_InitStruct->KS_DebounceCnt = 0x3e7; + KeyScan_InitStruct->KS_IntervalCnt = 0x7cf; + KeyScan_InitStruct->KS_ReleaseCnt = 0x3e7; + + KeyScan_InitStruct->KS_ThreholdLevel = 8; + KeyScan_InitStruct->KS_LimitLevel = 2; + KeyScan_InitStruct->KS_OverCtrl = KS_FIFO_OVER_CTRL_DIS_NEW; +} + +/** + * @brief Initializes the KeyScan peripheral according to the specified + * parameters in the KeyScan_InitStruct. + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_InitStruct: pointer to a KeyScan_InitTypeDef structure that contains + * the configuration information for the specified KeyScan peripheral. + * @retval None + */ +void KeyScan_Init(KSCAN_TypeDef *KeyScan, KeyScan_InitTypeDef *KeyScan_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + assert_param(KeyScan_InitStruct->KS_ClkDiv <= 0xfff); + assert_param((KeyScan_InitStruct->KS_ColSel >= 0x1) && (KeyScan_InitStruct->KS_ColSel <= 0xff)); + assert_param((KeyScan_InitStruct->KS_RowSel >= 0x1) && (KeyScan_InitStruct->KS_RowSel <= 0xff)); + assert_param(KeyScan_InitStruct->KS_DebounceCnt <= 0xfff); + assert_param(KeyScan_InitStruct->KS_IntervalCnt <= 0xfff); + assert_param(KeyScan_InitStruct->KS_ReleaseCnt <= 0xfff); + assert_param(IS_KS_WORK_MODE(KeyScan_InitStruct->KS_WorkMode)); + assert_param(IS_KS_FIFO_OVER_CTRL(KeyScan_InitStruct->KS_OverCtrl)); + assert_param(IS_KS_FIFO_LIMIT_LEVEL(KeyScan_InitStruct->KS_LimitLevel)); + assert_param(IS_KS_FIFO_TH_LEVEL(KeyScan_InitStruct->KS_ThreholdLevel)); + + /* Disable the IC first */ + KeyScan->KS_CTRL &= (~KS_BIT_RUN_ENABLE); + + /* Mask all keyscan interrupt */ + KeyScan->KS_IMR &= (~KS_BIT_ALL_INT_MSK); + + /* clock divider config */ + KeyScan->KS_CLK_DIV &= (~KS_MASK_CLK_DIV); + KeyScan->KS_CLK_DIV |= KS_CLK_DIV(KeyScan_InitStruct->KS_ClkDiv); + + /* Config scan mode*/ + KeyScan->KS_CTRL &= (~KS_BIT_WORK_MODE); + if (KeyScan_InitStruct->KS_WorkMode) { + KeyScan->KS_CTRL |= KS_BIT_WORK_MODE; + } + + KeyScan->KS_FIFO_CFG = KS_FIFO_TH_LEVEL(KeyScan_InitStruct->KS_ThreholdLevel) | \ + KS_FIFO_LIMIT_LEVEL(KeyScan_InitStruct->KS_LimitLevel); + if (KeyScan_InitStruct->KS_OverCtrl) { + KeyScan->KS_FIFO_CFG |= KS_BIT_FIFO_OV_CTRL; + } + + /* time count config */ + KeyScan->KS_TIM_CFG0 &= (~KS_MASK_DEB_TIMER); + KeyScan->KS_TIM_CFG0 |= KS_DEB_TIMER(KeyScan_InitStruct->KS_DebounceCnt); + KeyScan->KS_TIM_CFG1 = KS_INTERVAL_TIMER(KeyScan_InitStruct->KS_IntervalCnt) | \ + KS_RELEASE_TIMER(KeyScan_InitStruct->KS_ReleaseCnt); + + /* Set col map, config which col to work */ + KeyScan->KS_COL_CFG = KS_COL_SEL(KeyScan_InitStruct->KS_ColSel); + + /* Set row map, config which row to work */ + KeyScan->KS_ROW_CFG = KS_ROW_SEL(KeyScan_InitStruct->KS_RowSel); + + /* clear all interrupt status and status flag */ + KeyScan->KS_ICR |= KS_BIT_ALL_INT_CLR; + + return; +} + +/** + * @brief Enables or disables the specified KeyScan interrupts mask. + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_IT: specifies the KeyScan interrupt sources to be enabled or masked. + * This parameter can be one or combinations of the following values: + * @arg KS_BIT_ALL_DEFAULT_INT_MASK: Unmask all default interrupt + * @arg KS_BIT_FALSE_ALARM_INT_MASK: Unmask false alarm interrupt + * @arg KS_BIT_STUCK_EVENT_INT_MASK: Unmask Stuck event interrupt + * @arg KS_BIT_SCAN_EVENT_INT_MASK: Unmask Scan event interrupt + * @arg KS_BIT_FIFO_LIMIT_INT_MASK: Unmask FIFO limit interrupt + * @arg KS_BIT_FIFO_OV_INT_MASK: Unmask FIFO overflow interrupt + * @arg KS_BIT_FIFO_FULL_INT_MASK: Unmask FIFO full interrupt + * @arg KS_BIT_SCAN_FINISH_INT_MASK: Unmask scan finish interrupt + * @arg KS_BIT_FIFO_NOTEMPTY_INT_MASK: Unmask FIFO nonempty interrupt + * @arg KS_BIT_ALL_RELEASE_INT_MASK: Unmask All Release interrupt + * @param NewState: new state of the specified KeyScan interrupts mask. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_INTConfig(KSCAN_TypeDef *KeyScan, u32 KeyScan_IT, u8 newState) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + if (newState == ENABLE) { + /* Enable KeyScan interrupts */ + KeyScan->KS_IMR |= KeyScan_IT; + } else { + /* Disable KeyScan interrupts */ + KeyScan->KS_IMR &= (~KeyScan_IT); + } +} + +/** + * @brief Clears the specified KeyScan interrupt pending bit. + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_IT: specifies the KeyScan interrupt to be cleared. + * This parameter can be one or combinations of the following values: + * @arg KS_BIT_ALL_DEFAULT_INT_CLR: all default flag + * @arg KS_BIT_FALSE_ALARM_INT_CLR: false alarm flag + * @arg KS_BIT_STUCK_INT_CLR: Stuck event interrupt flag + * @arg KS_BIT_FIFO_LIMIT_INT_CLR: FIFO limit interrupt flag + * @arg KS_BIT_FIFO_OV_INT_CLR: FIFO overflow interrupt flag + * @arg KS_BIT_SCAN_FINISH_INT_CLR: Scan finish interrupt flag + * @arg KS_BIT_ALL_RELEASE_INT_CLR: All Release interrupt flag + * @note KS_BIT_SCAN_EVENT_INT_STATUS is automatically cleared by hardware when the data is read. + * KS_BIT_FIFO_FULL_INT_STATUS is automatically cleared by hardware when the buffer level + * goes below the KS_FIFO_TH_LEVEL threshold. + * KS_BIT_FIFO_NOTEMPTY_INT_STATUS is automatically cleared by hardware when the FIFO is empty. + * @retval None + */ +void KeyScan_ClearINT(KSCAN_TypeDef *KeyScan, u32 KeyScan_IT) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + KeyScan->KS_ICR |= KeyScan_IT; +} + +/** + * @brief Get KeyScan Raw Interrupt Status. + * @param KeyScan: selected KeyScan peripheral. + * @retval raw interrupt status + */ +u32 KeyScan_GetRawINT(KSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + return KeyScan->KS_ISR_RAW; +} + +/** + * @brief Get KeyScan interrupt status. + * @param KeyScan: selected KeyScan peripheral. + * @retval interrupt status + */ +u32 KeyScan_GetINT(KSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + return KeyScan->KS_ISR; +} + +/** + * @brief Get data number of keyscan FIFO. + * @param KeyScan: selected KeyScan peripheral. + * @retval data number of keyscan FIFO + */ +u8 KeyScan_GetDataNum(KSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + return KS_GET_FIFO_DATA_LEVEL(KeyScan->KS_DATA_NUM); +} + +/** + * @brief Clears the FIFO data. + * @param KeyScan: selected KeyScan peripheral. + * @retval None + */ +void KeyScan_ClearFIFOData(KSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + KeyScan->KS_FIFO_CFG |= KS_BIT_FIFO_CLR; +} + +/** + * @brief Get status of keyscan FIFO. + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_Flag: specifies the flag to check. + * This parameter can be one of the following values: + * @arg KS_BIT_FIFO_FULL + * @arg KS_BIT_FIFO_EMPTY + * @retval the new statue of the specified flag. + * This parameter can be: TRUE or FALSE. + */ +bool KeyScan_GetFIFOState(KSCAN_TypeDef *KeyScan, u32 KeyScan_Flag) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + if ((KeyScan->KS_DATA_NUM & KeyScan_Flag) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + * @brief Read data from keyscan FIFO. + * @param KeyScan: selected KeyScan peripheral. + * @param *outBuf: buffer to save data read from KeyScan FIFO. + * @param count: number of data to be read. + * @retval None + */ +void KeyScan_Read(KSCAN_TypeDef *KeyScan, u32 *outBuf, u8 count) +{ + u32 TempVal; + + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + for (TempVal = 0; TempVal < count; TempVal++) { + *outBuf++ = KS_GET_DATA(KeyScan->KS_DATA); + } +} + +/** + * @brief Enables or disables the specified KeyScan peripheral. + * @param KeyScan: selected KeyScan peripheral. + * @param NewState: new state of the KeyScan peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_Cmd(KSCAN_TypeDef *KeyScan, u8 NewState) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + if (NewState != DISABLE) { + /* Enable the KeyScan peripheral */ + KeyScan->KS_CTRL |= KS_BIT_RUN_ENABLE; + } else { + /* Disable the KeyScan peripheral */ + KeyScan->KS_CTRL &= (~KS_BIT_RUN_ENABLE); + } +} + +/** + * @brief Set Keyscan Column and Row that used. + * @param column_sel: Specifies which column(s) is used. + * This parameter must be set to a value in the 0x1-0xff range. + * @param row_sel: Specifies which row(s) is used. + * This parameter must be set to a value in the 0x1-0xff range. + * @retval None + */ +void KeyScan_SetColRow(KSCAN_TypeDef *KeyScan, u32 column_sel, u32 row_sel) +{ + assert_param((column_sel >= 0x1) && (column_sel <= 0xff)); + assert_param((row_sel >= 0x1) && (row_sel <= 0xff)); + + /* Set col map, config which col to work */ + KeyScan->KS_COL_CFG = KS_COL_SEL(column_sel); + + /* Set row map, config which row to work */ + KeyScan->KS_ROW_CFG = KS_ROW_SEL(row_sel); +} + +/** + * @brief Enables or disables KeyScan stuck auto check function. + * @param KeyScan: selected KeyScan peripheral. + * @param NewState: new state of the KeyScan stuck auto check function. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_StuckAutoCmd(KSCAN_TypeDef *KeyScan, u8 NewState) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + if (NewState != DISABLE) { + /* Enable the KeyScan stuck auto check function */ + KeyScan->KS_STUCK_CFG0 |= KS_BIT_AUTO_CHECK_STUCK_ENABLE; + } else { + /* Disable the KeyScan stuck auto check function */ + KeyScan->KS_STUCK_CFG0 &= (~KS_BIT_AUTO_CHECK_STUCK_ENABLE); + } +} + +/** + * @brief Set stuck time threshold. + * @param KeyScan: selected KeyScan peripheral. + * @param ThresholdMs: stuck time threshold convert to ms. + * ThresholdMs = (Threshold +1)* Scan_clk(ms). + * Threshold must be set to a value in the 0x0-0x7fffffff range. + * @retval None + */ +void KeyScan_SetStuckThreshold(KSCAN_TypeDef *KeyScan, u32 ThresholdMs) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + u32 Threshold = (ThresholdMs * 40 * 1000) / (KS_CLK_DIV(KeyScan->KS_CLK_DIV) + 1) - 1; + assert_param(Threshold <= 0x7fffffff); + + KeyScan->KS_STUCK_CFG0 &= (~KS_MASK_STUCK_TIME_THRESHOLD); + KeyScan->KS_STUCK_CFG0 |= KS_STUCK_TIME_THRESHOLD(Threshold); +} + + +/** + * @brief Set stuckrow detect periodical no pull time. + * @param KeyScan: selected KeyScan peripheral. + * @param PullUpUs: stuckrow detect pullup time convert to us. + * PullUpUs = (PullUpCnt +1)* clk_131k(us), max value is 15625us. + * PullUpCnt must be set to a value in the 0x0-0x7ff range. + * @param NoPullUs: stuckrow detect no pull time convert to us. + * When NoPullUs is 0, disable stuckrow detect function. + * When NoPullUs is not 0, NoPullUs = (NoPullCnt +1)* clk_131k(us), max value is 31259us. + * NoPullUs can be set to a value in the 0x0-0xfff range. + * @retval None + */ +void KeyScan_StuckPeriodicalPull(KSCAN_TypeDef *KeyScan, u32 PullUpUs, u32 NoPullUs) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + u32 PullUpCnt = PullUpUs * 131 / 1000 - 1; + u32 NoPullCnt = NoPullUs * 131 / 1000 - 1; + assert_param(PullUpCnt <= 0x7ff); + assert_param(NoPullCnt <= 0xfff); + + if (NoPullUs != 0) { + /* Enable the KeyScan stuckrow detect function */ + KeyScan->KS_STUCK_CFG2 |= KS_BIT_STUCKROW_DETECT_ENABLE; + + KeyScan->KS_STUCK_CFG2 &= ~(KS_MASK_STUCKROW_DETECT_TIME | KS_MASK_STUCKROW_DETECT_TIME_INTERVAL); + KeyScan->KS_STUCK_CFG2 |= (KS_STUCKROW_DETECT_TIME(PullUpCnt) | KS_STUCKROW_DETECT_TIME_INTERVAL(NoPullCnt)); + } else { + /* Disable the KeyScan stuckrow detect function */ + KeyScan->KS_STUCK_CFG2 &= (~KS_BIT_STUCKROW_DETECT_ENABLE); + } +} + +/** + * @brief Get stuckrow default status. + * @param KeyScan: selected KeyScan peripheral. + * @retval row0 ~ row7 default status. + * one bit one row, bit 0 means row0, bit 7 means row7. + * 1: row stucked + * 0: row unstucked + */ +u32 KeyScan_GetStuckRow(KSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + return KS_ROW_STATUS(KeyScan->KS_STUCK_KEY_ROW_STATUS1); +} + +/** + * @brief Set stuckrow default status. + * @param KeyScan: selected KeyScan peripheral. + * @param Status: row default status. + * one bit one row, bit 0 means row0, bit 7 means row7. + * 1: row stucked + * 0: row unstucked + * @retval None + */ +void KeyScan_SetStuckRow(KSCAN_TypeDef *KeyScan, u32 Status) +{ + /* Check the parameters */ + assert_param(IS_KEYSCAN_ALL_PERIPH(KeyScan)); + + KeyScan->KS_STUCK_CFG1 = KS_ROW_DEFAULT_STATUS(~Status); +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ldo.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ldo.c new file mode 100644 index 00000000..96b37533 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ldo.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +static const char *const TAG = "BOOT"; + +/** + * @brief Set Core voltage Type. + * @param Source: This parameter can be one of the following values: + * @arg CORE_VOL_0P9 + * @arg CORE_VOL_1P0 + */ +void CORE_LDO_Vol_Set(u8 vol_type) +{ + u32 Temp; + + Temp = HAL_READ32(OTPC_REG_BASE, SEC_OTP_HWCFG); + if (vol_type == CORE_VOL_1P0) { /*Core LDO 1.0V & SWR 1.35V */ + if ((Temp & SEC_BIT_BOOT_VOL_SEL) == 0) { + /* if OTP not set, trigger to 1.0V manually */ + Temp |= SEC_BIT_BOOT_VOL_SEL; + HAL_WRITE32(OTPC_REG_BASE, SEC_OTP_HWCFG, Temp); + Temp = HAL_READ32(PMC_BASE, AIP_TRIGGER); + Temp |= PMC_BIT_TRG_SYS_REGU_STS; + HAL_WRITE32(PMC_BASE, AIP_TRIGGER, Temp); + } + } else if ((vol_type == CORE_VOL_0P9) && ((Temp & SEC_BIT_BOOT_VOL_SEL) != 0)) { + RTK_LOGE(TAG, "OTP BOOT VOL choose 1.0V but usrcfg choose 0.9V!\n"); + } +} + +/** + * @brief Set LDO_Mem with different dummyload. + * @param dummy_load: LDO_MEM_DUMMY_200UA/LDO_MEM_DUMMY_500UA/LDO_MEM_DUMMY_700UA + */ +void LDO_Mem_Dummy_Ctrl(u32 dummy_load) +{ + LDO_TypeDef *LDO = LDO_BASE; + + LDO->LDO_3318 &= ~LDO_MASK_DMY_LOAD; + LDO->LDO_3318 |= LDO_DMY_LOAD(dummy_load); +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_loguart.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_loguart.c index 3c4551e6..5e454fcd 100644 --- a/ameba/amebadplus/source/fwlib/ram_common/ameba_loguart.c +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_loguart.c @@ -17,3 +17,134 @@ void LOGUART_INT_NP2AP(void) LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM0, DISABLE); LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM4, ENABLE); } + +/** + * @brief Switch LOGUART interrupt from AP to NP. + * @param None + * @retval None + * @note KM0 is NP and KM4 is AP. + */ +void LOGUART_INT_AP2NP(void) +{ + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM4, DISABLE); + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM0, ENABLE); +} + +/** + * @brief Set LOGUART IMR + * @param SetValue: specifies the LOGUART interrupt sources to be enabled or disabled. + * This parameter can be one or combinations of the following values: + * @arg LOGUART_BIT_ERBI: Received Data Available interrupt + * @arg LOGUART_BIT_ELSI: Receiver Line Status interrupt + * @arg LOGUART_BIT_ETOI: Rx Time Out interrupt + * @arg LOGUART_BIT_EDSSI: Modem Status Interrupt + * @arg LOGUART_TX_EMPTY_PATH_1_INTR: Tx Path 1 Transmitter FIFO Empty interrupt + * @arg LOGUART_TX_EMPTY_PATH_2_INTR: Tx Path 2 Transmitter FIFO Empty interrupt + * @arg LOGUART_TX_EMPTY_PATH_3_INTR: Tx Path 3 Transmitter FIFO Empty interrupt + * @arg LOGUART_TX_EMPTY_PATH_4_INTR: Tx Path 4 Transmitter FIFO Empty interrupt + * @retval none + */ +void LOGUART_INTConfig(LOGUART_TypeDef *UARTLOG, u32 UART_IT, u32 newState) +{ + (void)UARTLOG; + + u32 IerVal = LOGUART_GetIMR(); + + if (IS_LOGUART_TX_EMPTY_ENABLE(UART_IT & LOGUART_MASK_ETPFEI)) { + IerVal &= ~LOGUART_MASK_ETPFEI; + } + + if (newState == ENABLE) { + /* Enable the selected UARTx interrupts */ + IerVal |= UART_IT; + } else { + /* Disable the selected UARTx interrupts */ + IerVal &= (u32)~(UART_IT & (~LOGUART_MASK_ETPFEI)); + } + + LOGUART_SetIMR(IerVal); +} + +extern LOG_UART_PORT LOG_UART_IDX_FLAG[]; +/** +* @brief Check if there is space in loguart tx path fifo. +* @retval Status value: +* - 1: tx path fifo is not full +* - 0: tx path fifo is full +*/ +u8 LOGUART_Writable(void) +{ + LOGUART_TypeDef *UARTLOG = LOGUART_DEV; + u32 CPUID = SYS_CPUID(); + + if (UARTLOG->LOGUART_UART_LSR & LOG_UART_IDX_FLAG[CPUID].not_full) { + return 1; + } else { + return 0; + } +} + +/** + * @brief Wait until current tx path FIFO turns empty. + * @return None + * @note This function is called to check current tx path FIFO is empty or not. + * To check if tx process has been finished, call LOGUART_WaitTxComplete instead. + */ +void LOGUART_WaitBusy(void) +{ + LOGUART_TypeDef *UARTLOG = LOGUART_DEV; + u32 CPUID = SYS_CPUID(); + + /* Wait for LogUart print out */ + while (1) { + if (UARTLOG->LOGUART_UART_LSR & LOG_UART_IDX_FLAG[CPUID].empty) { + break; + } + + /* exit while-loop ASAP */ + DelayUs(1); + } +} + +/** + * @brief Wait until tx process finishes. + * @return None + * @note This function is called to wait until tx data is completely pushed from tx FIFO + * and all the tx path FIFO is empty. + */ +void LOGUART_WaitTxComplete(void) +{ + LOGUART_TypeDef *UARTLOG = LOGUART_DEV; + u32 lsr; + + while (1) { + lsr = UARTLOG->LOGUART_UART_LSR; + + if ((lsr & LOGUART_BIT_TP1F_EMPTY) && (lsr & LOGUART_BIT_TP2F_EMPTY) && (lsr & LOGUART_BIT_TP3F_EMPTY) && \ + (lsr & LOGUART_BIT_TP4F_EMPTY) && (!(lsr & LOGUART_BIT_RPF_DRDY)) && (lsr & LOGUART_BIT_TX_EMPTY)) { + break; + } + + /* exit while-loop ASAP */ + DelayUs(1); + } +} + +/** + * @brief Transmit single byte to current tx path FIFO without appending characters. + * @param c Data to be transmitted. + * @return None + */ +void LOGUART_PutChar_RAM(u8 c) +{ + LOGUART_TypeDef *UARTLOG = LOGUART_DEV; + u32 CPUID = SYS_CPUID(); + + if (ConfigDebugClose == 1) { + return; + } + + LOGUART_WaitTx(); + + UARTLOG->LOGUART_UART_THRx[LOG_UART_IDX_FLAG[CPUID].idx] = c; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_mpu_ram.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_mpu_ram.c new file mode 100644 index 00000000..3d199bc0 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_mpu_ram.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "cmsis.h" +#include "mpu_config.h" + +static const char *const TAG = "MPU"; +u8 mpu_entry_register[MPU_MAX_REGION]; + +/** + * @brief init mpu memory attribute to typical value. + * @param NA. + * @note typical value: + * - typical value if defined in @ref mpu_mem_attri_typical_define. + * @retval None + */ +void mpu_init(void) +{ + ARM_MPU_Disable(); + + /* Configure memory types */ + MPU->MAIR0 = ((MPU_MEM_ATTR0) << MPU_MAIR0_Attr0_Pos) | \ + ((MPU_MEM_ATTR1) << MPU_MAIR0_Attr1_Pos) | \ + ((MPU_MEM_ATTR2) << MPU_MAIR0_Attr2_Pos) | \ + ((MPU_MEM_ATTR3) << MPU_MAIR0_Attr3_Pos); + + MPU->MAIR1 = ((MPU_MEM_ATTR4) << MPU_MAIR1_Attr4_Pos) | \ + ((MPU_MEM_ATTR5) << MPU_MAIR1_Attr5_Pos) | \ + ((MPU_MEM_ATTR6) << MPU_MAIR1_Attr6_Pos) | \ + ((MPU_MEM_ATTR7) << MPU_MAIR1_Attr7_Pos); + + /* PRIVDEFENA Privileged background region enable: + * <0=> All accesses to unmapped addresses result in faults. + * <1=> Enables the default memory map for privilege code when the address accessed does not map into any MPU region. + * HFNMIENA MPU Enable for HardFault and NMI (Non-Maskable Interrupt): + * <0=> HardFault and NMI handlers bypass MPU configuration as if MPU is disabled. + * <1=> MPU access rules apply to HardFault and NMI handlers. + */ + ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk & ~MPU_CTRL_HFNMIENA_Msk); +} + +/** + * @brief change mpu memory attribute. + * @param attr_idx: where x can be 0~7. + * @param mem_attr: memory attribute. @ref mpu_region_memory_attribute_define. + * @note NA: + * - NA. + * @retval None + */ +void mpu_set_mem_attr(uint8_t attr_idx, uint8_t mem_attr) +{ + assert_param(attr_idx < MPU_MAX_REGION); + + ARM_MPU_Disable(); + ARM_MPU_SetMemAttr(attr_idx, mem_attr); + ARM_MPU_Enable(MPU->CTRL); +} + +/** + * @brief config mpu region memory attribute. + * @param region_num: where x can be 0~3. (KM0 & KM4 both) + * @param pmpu_cfg: pointer to an mpu_region_config structure which has been configured. + * @note NA: + * - NA. + * @retval None + */ +void mpu_region_cfg(uint8_t region_num, mpu_region_config *pmpu_cfg) +{ + MPU_Type *mpu = MPU; + u32 region_limit = pmpu_cfg->region_base + pmpu_cfg->region_size - 1; + + assert_param(region_num < MPU_MAX_REGION); + assert_param((pmpu_cfg->region_base & ~MPU_RBAR_BASE_Msk) == 0); + assert_param((pmpu_cfg->region_size & ~MPU_RLAR_LIMIT_Msk) == 0); + + ARM_MPU_Disable(); + + mpu->RNR = region_num; + mpu->RBAR = (pmpu_cfg->region_base & MPU_RBAR_BASE_Msk) | \ + pmpu_cfg->sh | \ + pmpu_cfg->ap | \ + pmpu_cfg->xn; + mpu->RLAR = ARM_MPU_RLAR(region_limit, pmpu_cfg->attr_idx); + + ARM_MPU_Enable(mpu->CTRL); + + RTK_LOGD(TAG, "mpu_region[%d] RBAR:0x%lx RLAR:0x%lx attr_idx:%d\n", mpu->RNR, mpu->RBAR, mpu->RLAR, pmpu_cfg->attr_idx); + RTK_LOGD(TAG, "MAIR0:0x%lx MAIR1:0x%lx CTRL:0x%lx TYPE:0x%lx\n", mpu->MAIR0, mpu->MAIR1, mpu->CTRL, mpu->TYPE); +} + +/** + * @brief free mpu entry. + * @param entry_index: KM0: 0~3, KM4_NS: 0~7; KM4_S: 0~3. + * @retval None + */ +void mpu_entry_free(u32 entry_index) +{ + mpu_entry_register[entry_index] = 0; +} + +/** + * @brief alloc a free mpu entry. + * @param NA. + * @retval value: mpu entry index KM0: 0~3, KM4_NS: 0~7; KM4_S: 0~3, -1 is fail. + */ +char mpu_entry_alloc(void) +{ + u32 entry_index = 0; + + for (entry_index = 0; entry_index < MPU_MAX_REGION; entry_index++) { + if (mpu_entry_register[entry_index] == 0) { + mpu_entry_register[entry_index] = 1; + return entry_index; + } + } + + return -1; +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ppe.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ppe.c new file mode 100644 index 00000000..31f5e024 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ppe.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup PPE +* @brief PPE driver modules +* @{ +*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PPE_Exported_Functions PPE Exported Functions + * @{ + */ + + +/** + * @brief Enable PPE. + * @param state: the state of PPE. + * This parameter can only be ENABLE. + * @retval None. + */ +void PPE_Cmd(int state) +{ + if (state) { + PPE->GLB_CTL |= PPE_GLB_EN_MSK; + } +} + +/** + * @brief Get PPE global state. + * @param None. + * @retval Global state. 0 means PPE is not working, 1 means PPE is working. + */ +u32 PPE_GetGlobalState(void) +{ + return (PPE->GLB_CTL & PPE_GLB_EN_MSK); +} + +/** + * @brief Suspend PPE. + * @param None. + * @retval None. + */ +void PPE_Suspend(void) +{ + PPE->GLB_CTL |= PPE_SUSPEND_MSK; +} + +/** + * @brief Resume PPE from suspend state. + * @param None. + * @retval None. + */ +void PPE_Resume(void) +{ + PPE->GLB_CTL = PPE_RESUME_MSK; +} + +/** + * @brief PPE abort. + * @param None. + * @retval None. + */ +void PPE_Abort(void) +{ + /* Abort the transaction when the values of SUSP and ALL_INACT are both 1*/ + PPE->GLB_CTL |= PPE_SUSPEND_MSK; + while (!(PPE->GLB_CTL & PPE_ALL_INACT_MSK)); + PPE->GLB_CTL = PPE_ABORT_MSK; +} + + +/** + * @brief Check if a layer is inactive. + * @param chn_id: the layer number to be checked. + * @retval Status. + */ +int PPE_ChannelInactiveCheck(u8 chn_id) +{ + int rv = 0; + + if (PPE->GLB_CTL & ((BIT0 << PPE_CHN_INACT_POS) << chn_id)) { + rv = 1; + } + return rv; +} + +/** + * @brief Set ration of scale function. + * @param scale_x: ration of scale in X diretion. No smaller than 1/16. + * scale_y: ration of scale in Y diretion. No smaller than 1/16. + * @retval None. + */ +void PPE_SetScaleRation(float scale_x, float scale_y) +{ + u32 fix_x, fix_y; + + assert_param(scale_x > 0); + assert_param(scale_y > 0); + + fix_x = (u32)(65536 / scale_x); + fix_y = (u32)(65536 / scale_y); + + /* workaround: In multi-frame function, if fix_y of first frame is multiple of 65536 and fix_y of + second frame, and input layer1 is not reload for the second frame, error may occur. So here set fix_y + minus 1 */ + if ((fix_y >= 65536) && (fix_y % 65536 == 0)) { + fix_y = fix_y - 1; + } + + PPE->SCA_RATIO_X = fix_x; + PPE->SCA_RATIO_Y = fix_y; +} + +/** + * @brief Get all interrupt status. + * @param None. + * @retval Status. + */ +u32 PPE_GetAllIntStatus(void) +{ + return PPE->INT_STATUS; +} + +/** + * @brief Clear specific interrupt status. + * @param PPE_INT: specifies the PPE interrupt type. + * This parameter can be one or combinations of the following values: + * @arg PPE_ALL_OVER_INT: All frames blend or scale over. + * @arg PPE_FR_OVER_INT: One frame blend or scale over. + * @arg PPE_LOAD_OVER_INT: layers register be loaded to internal register over. + * @arg PPE_LINE_WL_INT: Specific line blend/scale over. + * @arg PPE_SUSP_INAC_INT: All channels come to inactive after suspend. + * @retval None. + */ +void PPE_ClearINTPendingBit(u32 PPE_INT) +{ + PPE->INT_CLR |= PPE_INT; +} + +/** + * @brief Enable/disable specific interrupt. + * @param PPE_INT_MSK: specifies the PPE interrupt type. + * This parameter can be one or combinations of the following values: + * @arg PPE_ALL_OVER_INT: All frames blend or scale over. + * @arg PPE_FR_OVER_INT: One frame blend or scale over. + * @arg PPE_LOAD_OVER_INT: layers register be loaded to internal register over. + * @arg PPE_LINE_WL_INT: Specific line blend/scale over. + * @arg PPE_SUSP_INAC_INT: All channels come to inactive after suspend. + * NewState: the new state. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void PPE_MaskINTConfig(u32 PPE_INT_MSK, int NewState) +{ + if (NewState == ENABLE) { + PPE->INT_MASK |= PPE_INT_MSK; + } else { + PPE->INT_MASK &= ~PPE_INT_MSK; + } +} + +/** + * @brief Mask all interrupt. + * @param None. + * @retval None. + */ +void PPE_MaskAllInt(void) +{ + PPE->INT_MASK = 0x0; +} + +/** + * @brief Configure auto reload layers. + * @param layers: auto reload layers. + * This parameter can be one or combinations of the following values: + * @arg PPE_RESULT_LAYER_BIT: result layer. + * @arg PPE_INPUT_LAYER1_BIT: input layer1. + * @arg PPE_INPUT_LAYER2_BIT: input layer2. + * @arg PPE_INPUT_LAYER3_BIT: input layer3. + * @retval None. + */ +void PPE_AutoReloadSetLayer(u32 layers) +{ + u32 reload_en; + + reload_en = PPE_LAYER_RELOAD_EN_MSK & layers; + PPE->RELOAD_CFG &= PPE_LAYER_RELOAD_EN_CLR; + PPE->RELOAD_CFG |= reload_en; +} + +/** + * @brief Enable/disable Auto reload function. + * @param NewState: the new state. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void PPE_AutoReloadClrLayerAll(void) +{ + PPE->RELOAD_CFG &= PPE_LAYER_RELOAD_EN_CLR; +} + +/** + * @brief Enable/disable auto cleared after loading. + * @param NewState:the new state. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void PPE_AutoClearCmd(int NewState) +{ + if (NewState) { + PPE->RELOAD_CFG |= PPE_AUTO_CLR_MSK; + } else { + PPE->RELOAD_CFG &= PPE_AUTO_CLR_CLR; + } +} + +/** + * @brief Tell PPE setting is vaild for auto reload function. + * @param None + * @retval None. + */ +void PPE_SetValid(void) +{ + PPE->RELOAD_CFG |= PPE_SET_VALID_MSK; +} + +/** + * @brief Get setting valid value to polling. + * @param None. + * @retval Set valid bit value. 0 means user can use to PPE_SetValid tell PPE setting is valid. + */ +u32 PPE_GetValid(void) +{ + return ((PPE->RELOAD_CFG & PPE_SET_VALID_MSK) == 0) ? 0 : 1; +} + +/** + * @brief Set LLP value to the pointer of first linklist item. + * @param lli: pointer to first listlist item. Must align to 4Byte. + * @retval None. + */ +void PPE_SetLLP(u32 lli) +{ + PPE->LLP = lli; +} + +/** + * @brief Set layer used by first linklist item. + * @param layers: linklist layers. + * This parameter can be one or combinations of the following values: + * @arg PPE_RESULT_LAYER_BIT: result layer. + * @arg PPE_INPUT_LAYER1_BIT: input layer1. + * @arg PPE_INPUT_LAYER2_BIT: input layer2. + * @arg PPE_INPUT_LAYER3_BIT: input layer3. + * @retval None. + */ +void PPE_LLSetLayer(u32 layers) +{ + u32 layer_ll_en; + + layer_ll_en = PPE_LAYER_LL_EN_MSK & layers; + PPE->LL_CFG &= PPE_LAYER_LL_EN_CLR; + PPE->LL_CFG |= layer_ll_en; +} + + +/** + * @brief Set line index for line over interrupt. + * @param line: the link index. + * @retval None. + */ +void PPE_SetLine(u32 line) +{ + PPE->LINE_INDEX = line; +} + + +/** + * @brief Fills each PPE_init_struct member with its default value. + * @param PPE_init_struct: pointer to an PPE_InitTypeDef structure which will be initialized. + * @retval None + */ +void PPE_StructInit(PPE_InitTypeDef *PPE_init_struct) +{ + assert_param(PPE_init_struct != NULL); + + PPE_init_struct->function = PPE_FUNCTION_ALPHA_BLEND; + PPE_init_struct->blend_layer_num = 0; +} + +/** + * @brief Fills each layer_init_struct member with its default value. + * @param layer_init_struct: pointer to an PPE_InputLayer_InitTypeDef structure which will be initialized. + * @retval None + */ +void PPE_InputLayer_StructInit(PPE_InputLayer_InitTypeDef *layer_init_struct) +{ + layer_init_struct->src_addr = 0; + layer_init_struct->start_x = 0; + layer_init_struct->start_y = 0; + layer_init_struct->width = 1; + layer_init_struct->height = 1; + layer_init_struct->const_ABGR8888_value = 0xFFFFFFFF; + layer_init_struct->format = PPE_RGB888; + layer_init_struct->src = PPE_LAYER_SRC_FROM_DMA; + layer_init_struct->color_key_en = DISABLE; + layer_init_struct->line_len = 0; + layer_init_struct->key_color_value = 0xFFFFFFFF; +} + +/** + * @brief Fills each layer_init_struct member with its default value. + * @param layer_init_struct: pointer to an PPE_ResultLayer_InitTypeDef structure which will be initialized. + * @retval None + */ +void PPE_ResultLayer_StructInit(PPE_ResultLayer_InitTypeDef *layer_init_struct) +{ + layer_init_struct->src_addr = 0; + layer_init_struct->width = 1; + layer_init_struct->height = 1; + layer_init_struct->format = PPE_RGB888; + layer_init_struct->line_len = 1; + layer_init_struct->type = PPE_ADDR_MEM; +} + +/** + * @brief Initializes the PPE peripheral according to the specified + * parameters in the PPE_init_struct. + * @param PPE_init_struct: pointer to a PPE_InitTypeDef structure that contains + * the configuration information for the specified PPE peripheral. + * @retval None + */ +void PPE_Init(PPE_InitTypeDef *PPE_init_struct) +{ + assert_param(PPE_init_struct != NULL); + assert_param(IS_PPE_FUNCTION(PPE_init_struct->function)); + + switch (PPE_init_struct->function) { + case PPE_FUNCTION_ALPHA_BLEND: { + assert_param(IS_PPE_ALPHA_BLEND_LAYER_NUM(PPE_init_struct->blend_layer_num)); + PPE->FUNC_CFG &= PPE_FUNC_SEL_CLR; + PPE->FUNC_CFG |= ((PPE_FUNCTION_ALPHA_BLEND << PPE_FUNC_SEL_POS) & PPE_FUNC_SEL_MSK); + PPE->FUNC_CFG &= PPE_BLEND_LAYER_NUM_CLR; + PPE->FUNC_CFG |= ((PPE_init_struct->blend_layer_num << PPE_BLEND_LAYER_NUM_POS) & PPE_BLEND_LAYER_NUM_MSK); + break; + } + case PPE_FUNCTION_SCALE: { + PPE->FUNC_CFG &= PPE_FUNC_SEL_CLR; + PPE->FUNC_CFG |= ((PPE_FUNCTION_SCALE << PPE_FUNC_SEL_POS) & PPE_FUNC_SEL_MSK); + break; + } + } +} + +/** + * @brief Initialize specific input layer. + * @param id: Input layer number. Can be 1/2/3. + * layer_init_struct: pointer to a PPE_InputLayer_InitTypeDef structure that contains + * the configuration information for the specified input layer. + * @retval None + */ +void PPE_InitInputLayer(u8 id, PPE_InputLayer_InitTypeDef *layer_init_struct) +{ + u8 cov_layer_id = id - 1; + + PPE_LAYER->INPUT_LAYER[cov_layer_id].ADDR = layer_init_struct->src_addr; + PPE_LAYER->INPUT_LAYER[cov_layer_id].CONST_PIX = layer_init_struct->const_ABGR8888_value; + PPE_LAYER->INPUT_LAYER[cov_layer_id].POS = ( + ((layer_init_struct->start_x << INPUT_LAYER_POS_X_POS) & INPUT_LAYER_POS_X_MSK) | + ((layer_init_struct->start_y << INPUT_LAYER_POS_Y_POS) & INPUT_LAYER_POS_Y_MSK) + ); + PPE_LAYER->INPUT_LAYER[cov_layer_id].WIN_SIZE = ( + ((layer_init_struct->width << INPUT_LAYER_WIDTH_POS) & INPUT_LAYER_WIDTH_MSK) | + ((layer_init_struct->height << INPUT_LAYER_HEIGHT_POS) & INPUT_LAYER_HEIGHT_MSK) + ); + PPE_LAYER->INPUT_LAYER[cov_layer_id].PIC_CFG = ( + ((layer_init_struct->format << INPUT_LAYER_PIX_FORMAT_POS) & INPUT_LAYER_PIX_FORMAT_MSK) | + ((layer_init_struct->src << INPUT_LAYER_PIX_SRC_POS) & INPUT_LAYER_PIX_SRC_MSK) | + ((layer_init_struct->color_key_en << INPUT_LAYER_KEY_EN_POS) & INPUT_LAYER_KEY_EN_MSK) | + ((layer_init_struct->line_len << INPUT_LAYER_LINE_LEN_POS) & INPUT_LAYER_LINE_LEN_MSK) + ); + PPE_LAYER->INPUT_LAYER[cov_layer_id].KEY_COLOR = layer_init_struct->key_color_value; + PPE_LAYER->INPUT_LAYER[cov_layer_id].HS_CFG = ( + ((0 << INPUT_LAYER_HW_INDEX_POS) & INPUT_LAYER_HW_INDEX_MSK) | + ((PPE_MSIZE_8 << INPUT_LAYER_MSIZE_LOG_POS) & INPUT_LAYER_MSIZE_LOG_MSK) | + ((DISABLE << INPUT_LAYER_HS_EN_POS) & INPUT_LAYER_HS_EN_MSK) | + ((PPE_POLARITY_HIGH << INPUT_LAYER_POLAR_POS) & INPUT_LAYER_POLAR_MSK) | + ((PPE_DMA_HW_HANDSHAKE << INPUT_LAYER_HW_HS_POS) & INPUT_LAYER_HW_HS_MSK) + ); + PPE_LAYER->INPUT_LAYER[cov_layer_id].BUS_CFG = ( + ((0 << INPUT_LAYER_PRIOR_POS) & INPUT_LAYER_PRIOR_MSK) | + ((PPE_MAX_AXLEN_127 << INPUT_LAYER_MAX_AXLEN_LOG_POS) & INPUT_LAYER_MAX_AXLEN_LOG_MSK) | + ((1 << INPUT_LAYER_AXCACHE_POS) & INPUT_LAYER_AXCACHE_MSK) | + ((PPE_ARBURST_INCR << INPUT_LAYER_INCR_POS) & INPUT_LAYER_INCR_MSK) | + ((2 << INPUT_LAYER_AXSIZE_POS) & INPUT_LAYER_AXSIZE_MSK) + ); +} + +/** + * @brief Initialize result layer. + * @param layer_init_struct: pointer to a PPE_ResultLayer_InitTypeDef structure that contains + * the configuration information for the result layer. + * @retval None + */ +void PPE_InitResultLayer(PPE_ResultLayer_InitTypeDef *layer_init_struct) +{ + u32 handshake_en, INCR; + + if (layer_init_struct->type == PPE_ADDR_QSPI) { + handshake_en = ENABLE; + INCR = PPE_ARBURST_FIX; + } else { + handshake_en = DISABLE; + INCR = PPE_ARBURST_INCR; + } + + PPE_LAYER->RESULT_LAYER.ADDR = layer_init_struct->src_addr; + PPE_LAYER->RESULT_LAYER.WIN_SIZE = ( + ((layer_init_struct->width << RESULT_LAYER_WIDTH_POS) & RESULT_LAYER_WIDTH_MSK) | + ((layer_init_struct->height << RESULT_LAYER_HEIGHT_POS) & RESULT_LAYER_HEIGHT_MSK) + ); + PPE_LAYER->RESULT_LAYER.PIC_CFG = ( + ((layer_init_struct->format << RESULT_LAYER_PIX_FORMAT_POS) & RESULT_LAYER_PIX_FORMAT_MSK) | + ((layer_init_struct->line_len << RESULT_LAYER_LINE_LEN_POS) & RESULT_LAYER_LINE_LEN_MSK) + ); + PPE_LAYER->RESULT_LAYER.HS_CFG = ( + ((0 << RESULT_LAYER_HW_INDEX_POS) & RESULT_LAYER_HW_INDEX_MSK) | + ((PPE_MSIZE_8 << RESULT_LAYER_MSIZE_LOG_POS) & RESULT_LAYER_MSIZE_LOG_MSK) | + ((handshake_en << RESULT_LAYER_HS_EN_POS) & RESULT_LAYER_HS_EN_MSK) | + ((PPE_POLARITY_HIGH << RESULT_LAYER_POLAR_POS) & RESULT_LAYER_POLAR_MSK) | + ((PPE_DMA_HW_HANDSHAKE << RESULT_LAYER_HW_HS_POS) & RESULT_LAYER_HW_HS_MSK) + ); + PPE_LAYER->RESULT_LAYER.BUS_CFG = ( + ((0 << RESULT_LAYER_PRIOR_POS) & RESULT_LAYER_PRIOR_MSK) | + ((PPE_MAX_AXLEN_127 << RESULT_LAYER_MAX_AXLEN_LOG_POS) & RESULT_LAYER_MAX_AXLEN_LOG_MSK) | + ((1 << RESULT_LAYER_AXCACHE_POS) & RESULT_LAYER_AXCACHE_MSK) | + ((INCR << RESULT_LAYER_INCR_POS) & RESULT_LAYER_INCR_MSK) | + ((2 << RESULT_LAYER_AXSIZE_POS) & RESULT_LAYER_AXSIZE_MSK) + ); +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_psram.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_psram.c new file mode 100644 index 00000000..19b765c1 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_psram.c @@ -0,0 +1,854 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +static const char *const TAG = "PSRAM"; +u8 APM_WR_INIT_LATENCY_SPEC[6] = { + APM_WR_INIT_LATENCY_3CLK, + APM_WR_INIT_LATENCY_4CLK, + APM_WR_INIT_LATENCY_5CLK, + APM_WR_INIT_LATENCY_6CLK, + APM_WR_INIT_LATENCY_7CLK, + APM_WR_INIT_LATENCY_8CLK, +}; + + +static const u32 PSRAM_CALIB_PATTERN[6] = { + 0x11223344, + 0xA55AA55A, + 0x5AA55AA5, + 0x44332211, + 0x96696996, + 0x69969669, +}; +PSRAMINFO_TypeDef PsramInfo; + + +/** + * @brief Initialize PSRAMINFO_TypeDef according to the memory configuration from MCM_MemTypeDef. + * @param meminfo [in] Pointer to MCM_MemTypeDef structure (typically from ChipInfo_MCMInfo()). + * @param info [out] Pointer to PSRAMINFO_TypeDef structure to fill in. + * @return None + * @note + */ +void ChipInfo_InitPsramInfoFromMemInfo(const MCM_MemTypeDef *meminfo, PSRAMINFO_TypeDef *info) +{ + _memset(info, 0, sizeof(PSRAMINFO_TypeDef)); + info->Psram_Page_size = 0; + info->Psram_Clk_Limit = 0; + info->Psram_Type = 0; + RRAM_TypeDef *rram = RRAM_DEV; + + if (meminfo == NULL || info == NULL) { + return; + } + + if (meminfo->mem_type == MCM_TYPE_PSRAM) { + switch (meminfo->dram_info.model) { + case MCM_PSRAM_VENDOR_WB: + info->Psram_Vendor = MCM_PSRAM_VENDOR_WB; + switch (meminfo->dram_info.density) { + case MCM_PSRAM_SIZE_32Mb: + info->Psram_Size = 4 * 1024 * 1024; + info->Psram_Page_size = PSRAM_PAGE128; + info->Psram_Clk_Limit = PSRAM_DEVICE_CLK_200; + info->Psram_Type = PSRAM_TYPE_WB955; + break; + case MCM_PSRAM_SIZE_128Mb: + info->Psram_Size = 16 * 1024 * 1024; + info->Psram_Page_size = PSRAM_PAGE2048; + info->Psram_Clk_Limit = PSRAM_DEVICE_CLK_250; + info->Psram_Type = PSRAM_TYPE_WB957; + break; + case MCM_PSRAM_SIZE_256Mb: + info->Psram_Size = 32 * 1024 * 1024; + info->Psram_Page_size = PSRAM_PAGE1024; + info->Psram_Clk_Limit = PSRAM_DEVICE_CLK_250; + info->Psram_Type = PSRAM_TYPE_WB958; + break; + default: + break; + } + break; + case MCM_PSRAM_VENDOR_APM: + info->Psram_Vendor = MCM_PSRAM_VENDOR_APM; + switch (meminfo->dram_info.density) { + case MCM_PSRAM_SIZE_64Mb: + info->Psram_Size = 8 * 1024 * 1024; + info->Psram_Page_size = PSRAM_PAGE1024; + info->Psram_Clk_Limit = PSRAM_DEVICE_CLK_200; + info->Psram_Type = PSRAM_TYPE_APM64; + break; + default: + break; + } + break; + + default: + info->Psram_Vendor = MCM_PSRAM_VENDOR_NOTCARE; + break; + } + } else { + info->Psram_Vendor = MCM_PSRAM_VENDOR_NOTCARE; + } + rram->PSRAM_TYPE = info->Psram_Vendor; +} + + +/** + * @brief get psram clk info + * @param none + * @retval none + */ +void PSRAM_CLK_Update(void) +{ + MCM_MemTypeDef meminfo = ChipInfo_MCMInfo(); + ChipInfo_InitPsramInfoFromMemInfo(&meminfo, &PsramInfo); + + u32 PsramClk = 0; + u32 PLLCLk, Div; + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_CKSL_GRP0); + u32 ClkSel = LSYS_GET_CKSL_PSRAM(Temp); + + if (ClkSel == BIT_LSYS_CKSL_SPIC_XTAL) { + + PsramClk = XTAL_ClkGet(); + + } else if (ClkSel == BIT_LSYS_CKSL_SPIC_PLL) { + Div = LSYS_GET_PSRAMC_FLASH_DIV_INT(HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_PSRAMC_FLASH_CTRL)); + Div += 1; + + PLLCLk = PLL_ClkGet(); + PsramClk = PLLCLk / Div; + + } + + if (!PsramClk) { + RTK_LOGE(TAG, "Invalid PsramClk\n"); + return ; + } + + PsramInfo.Psram_Clk_Set = PsramClk / 2; + PsramInfo.PSRAMC_Clk_Unit = 1000000000000 / PsramClk;// unit ps + + if (PsramInfo.Psram_Vendor == MCM_PSRAM_VENDOR_WB) { + if (PsramInfo.Psram_Clk_Set <= 83000000) { + PsramInfo.Psram_Latency_Set = 3; + PsramInfo.Psram_TRWR = Psram_WB_TRWR133; + PsramInfo.Psram_Latency_Code = WB_INIT_LATENCY_3CLK; + } else if (PsramInfo.Psram_Clk_Set <= 104000000) { + PsramInfo.Psram_Latency_Set = 4; + PsramInfo.Psram_TRWR = Psram_WB_TRWR133; + PsramInfo.Psram_Latency_Code = WB_INIT_LATENCY_4CLK; + } else if (PsramInfo.Psram_Clk_Set <= 133000000) { + PsramInfo.Psram_Latency_Set = 5; + PsramInfo.Psram_TRWR = Psram_WB_TRWR133; + PsramInfo.Psram_Latency_Code = WB_INIT_LATENCY_5CLK; + } else if (PsramInfo.Psram_Clk_Set <= 200000000) { + PsramInfo.Psram_Latency_Set = 6; + PsramInfo.Psram_TRWR = Psram_WB_TRWR166; + PsramInfo.Psram_Latency_Code = WB_INIT_LATENCY_6CLK; + } + + } else if (PsramInfo.Psram_Vendor == MCM_PSRAM_VENDOR_APM) { + + if (PsramInfo.Psram_Clk_Set <= 104000000) { + PsramInfo.Psram_Latency_Set = 4; + PsramInfo.Psram_CSHI = Psram_APM_CSHI133; + } else if (PsramInfo.Psram_Clk_Set <= 133000000) { + PsramInfo.Psram_Latency_Set = 5; + PsramInfo.Psram_CSHI = Psram_APM_CSHI133; + } else if (PsramInfo.Psram_Clk_Set <= 166000000) { + PsramInfo.Psram_Latency_Set = 6; + PsramInfo.Psram_CSHI = Psram_APM_CSHI166; + } else if (PsramInfo.Psram_Clk_Set <= 200000000) { + PsramInfo.Psram_Latency_Set = 7; + PsramInfo.Psram_CSHI = Psram_APM_CSHI200; + } else if (PsramInfo.Psram_Clk_Set <= 250000000) { + PsramInfo.Psram_Latency_Set = 8; + PsramInfo.Psram_CSHI = Psram_APM_CSHI250; + } + } + + // RTK_LOGI(TAG, "PSRAM Ctrl CLK: %lu Hz \n", PsramClk); +} + +/** + * @brief Fills each PSPHY_InitStruct member with its default value. + * @param PSPHY_InitStruct: pointer to an PSPHY_InitStruct structure which will be initialized. + * @retval None + */ +void PSRAM_PHY_StructInit(PSPHY_InitTypeDef *PSPHY_InitStruct) +{ + // 0x04 + PSPHY_InitStruct->PSRAMP_PRE_CAL_PHASE = 0x0; /* only for rtl now, default choose 1 on asic */ + PSPHY_InitStruct->PSRAMP_CFG_CAL_JMIN = 0x2; + PSPHY_InitStruct->PSRAMP_CFG_CAL_JMAX = 0x3; + PSPHY_InitStruct->PSRAMP_CFG_CAL_J = 0x3; + PSPHY_InitStruct->PSRAMP_CFG_CAL_N = 0xA; + + //0x18 + PSPHY_InitStruct->PSRAMP_SW_RST_N = 0x1; + PSPHY_InitStruct->PSRAMP_LATENCY_TYPE = PSRSAM_FIX_LATENCY; //0:variable latency 1:fix leatency + PSPHY_InitStruct->PSRAMP_RWDS_CHK_OPT = 0x1; //1:for fpga + PSPHY_InitStruct->PSRAMP_RWDS_PD_EN = 0x0; //0: for fpga + PSPHY_InitStruct->PSRAMP_CAL_RWDS_PHASE = 0x1; + if (PSPHY_InitStruct->PSRAMP_LATENCY_TYPE) { + PSPHY_InitStruct->PSRAMP_RFIFO_RDY_DLY = PSPHY_RFIFO_READY_DELAY_FIX; + } else { + PSPHY_InitStruct->PSRAMP_RFIFO_RDY_DLY = PSPHY_RFIFO_READY_DELAY_VL; + + } +} + +/** + * @brief Initializes the PSRAM phy according to the specified + * parameters in the PSPHY_InitStruct + * @param PSPHY_InitStruct: pointer to a PSPHY_InitStruct structure that + * contains the configuration information for the specified PSRAM phy + * @retval None + */ +void PSRAM_PHY_Init(PSPHY_InitTypeDef *PSPHY_InitStruct) +{ + + PSPHY_TypeDef *psram_phy = PSRAMPHY_DEV; + + //0x04 + psram_phy->PSPHY_CAL_PAR = PSPHY_PRE_CAL_PHASE(PSPHY_InitStruct->PSRAMP_PRE_CAL_PHASE) | \ + PSPHY_CFG_CAL_JMIN(PSPHY_InitStruct->PSRAMP_CFG_CAL_JMIN) | \ + PSPHY_CFG_CAL_JMAX(PSPHY_InitStruct->PSRAMP_CFG_CAL_JMAX) | \ + PSPHY_CFG_CAL_J(PSPHY_InitStruct->PSRAMP_CFG_CAL_J) | \ + PSPHY_CFG_CAL_N(PSPHY_InitStruct->PSRAMP_CFG_CAL_N); + + //0x18 + psram_phy->PSPHY_PHY_CTRL = PSPHY_PSRAM_SW_RST_N(PSPHY_InitStruct->PSRAMP_SW_RST_N) | \ + PSPHY_RWDS_CHK_OPT(PSPHY_InitStruct->PSRAMP_RWDS_CHK_OPT) | \ + PSPHY_RWDS_PD_EN(PSPHY_InitStruct->PSRAMP_RWDS_PD_EN) | \ + PSPHY_LATENCY_TYPE(PSPHY_InitStruct->PSRAMP_LATENCY_TYPE) | \ + PSPHY_CAL_RWDS_PHASE(PSPHY_InitStruct->PSRAMP_CAL_RWDS_PHASE) | \ + PSPHY_RFIFO_RDY_DLY(PSPHY_InitStruct->PSRAMP_RFIFO_RDY_DLY); + +} + +void PSRAM_InfoDump(void) +{ + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + PSPHY_TypeDef *psram_phy = PSRAMPHY_DEV; + RRAM_TypeDef *rram = RRAM_DEV; + u8 psramir0[2] = {0, 0}; + u8 psramcr0[2] = {0, 0}; + u8 psramcr1[2] = {0, 0}; + u8 psram_type = rram->PSRAM_TYPE; + + RTK_LOGI(TAG, "BDnum is 0x%x\n", ChipInfo_BDNum()); + + RTK_LOGI(TAG, "SSIENR\t0x%x=0x%x\n", &psram_ctrl->SSIENR, psram_ctrl->SSIENR); + RTK_LOGI(TAG, "CTRLR0\t0x%x=0x%x\n", &psram_ctrl->CTRLR0, psram_ctrl->CTRLR0); + RTK_LOGI(TAG, "BAUDR\t0x%x=0x%x\n", &psram_ctrl->BAUDR, psram_ctrl->BAUDR); + RTK_LOGI(TAG, "VALID_CMD\t0x%x=0x%x\n", &psram_ctrl->VALID_CMD, psram_ctrl->VALID_CMD); + RTK_LOGI(TAG, "CTRLR2\t0x%x=0x%x\n", &psram_ctrl->CTRLR2, psram_ctrl->CTRLR2); + RTK_LOGI(TAG, "DEVICE_INFO\t0x%x=0x%x\n", &psram_ctrl->DEVICE_INFO, psram_ctrl->DEVICE_INFO); + RTK_LOGI(TAG, "TPR0\t0x%x=0x%x\n", &psram_ctrl->TPR0, psram_ctrl->TPR0); + RTK_LOGI(TAG, "READ_FAST_SINGLE\t0x%x=0x%x\n", &psram_ctrl->READ_FAST_SINGLE, psram_ctrl->READ_FAST_SINGLE); + RTK_LOGI(TAG, "WRITE_SIGNLE\t0x%x=0x%x\n", &psram_ctrl->WRITE_SIGNLE, psram_ctrl->WRITE_SIGNLE); + RTK_LOGI(TAG, "AUTO_LENGTH\t0x%x=0x%x\n", &psram_ctrl->AUTO_LENGTH, psram_ctrl->AUTO_LENGTH); + RTK_LOGI(TAG, "USER_LENGTH\t0x%x=0x%x\n", &psram_ctrl->USER_LENGTH, psram_ctrl->USER_LENGTH); + RTK_LOGI(TAG, "AUTO_LENGTH2\t0x%x=0x%x\n", &psram_ctrl->AUTO_LENGTH2, psram_ctrl->AUTO_LENGTH2); + RTK_LOGI(TAG, "SR\t0x%x=0x%x\n", &psram_ctrl->SR, psram_ctrl->SR); + + RTK_LOGI(TAG, "PSPHY_CAL_PAR\t0x%x=0x%x\n", &psram_phy->PSPHY_CAL_PAR, psram_phy->PSPHY_CAL_PAR); + RTK_LOGI(TAG, "PSPHY_PHY_CTRL\t0x%x=0x%x\n", &psram_phy->PSPHY_PHY_CTRL, psram_phy->PSPHY_PHY_CTRL); + RTK_LOGI(TAG, "PSPHY_DBG_SEL\t0x%x=0x%x\n", &psram_phy->PSPHY_DBG_SEL, psram_phy->PSPHY_DBG_SEL); + + PSRAM_REG_Read(psram_type, 0x0, 2, psramir0, 0); + RTK_LOGI(TAG, "IR0[1]=0x%x\n", psramir0[1]); + RTK_LOGI(TAG, "IR0[0]=0x%x\n", psramir0[0]); + PSRAM_REG_Read(psram_type, 0x0, 2, psramcr0, 1); + RTK_LOGI(TAG, "CR0[1]=0x%x\n", psramcr0[1]); + RTK_LOGI(TAG, "CR0[0]=0x%x\n", psramcr0[0]); + PSRAM_REG_Read(psram_type, 0x1, 2, psramcr1, 1); + RTK_LOGI(TAG, "CR1[1]=0x%x\n", psramcr1[1]); + RTK_LOGI(TAG, "CR1[0]=0x%x\n", psramcr1[0]); + +} + + +/** + * @brief Initializes the PSRAM controller according to the specified + * parameters in the PSRAM_InitStruct + * @param PSRAM_InitStruct: pointer to a PSRAM_InitTypeDef structure that + * contains the configuration information for the specified PSRAM controller + * @retval None + */ +void PSRAM_CTRL_Init(void) +{ + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + + /* Disable psramc */ + psram_ctrl->SSIENR = 0; + + //0x00 + psram_ctrl->CTRLR0 = MASK_DDR_EN | MASK_ADDR_CH | CK_MTIMES(0x1) | MASK_DATA_CH | MASK_CMD_CH; + + //0x14 + psram_ctrl->BAUDR = SCKDV(Psram_ClkDiv2); + + //0x120 + psram_ctrl->VALID_CMD = BIT_SEQ_WR_EN | BIT_SEQ_RD_EN | BIT_FRD_SINGLE | BIT_CTRLR0_CH; + + //psram_ctrl->CTRLR2 &= ~BIT_FULL_WR; //bit 13 = 0 need to disable,default = 0 + //0x110 + if (PsramInfo.Psram_Vendor == MCM_PSRAM_VENDOR_WB) { + psram_ctrl->CTRLR2 = BIT_SO_DNUM | TX_FIFO_ENTRY(0x5) | RX_FIFO_ENTRY(0x5) | BIT_DM_ACT | BIT_DIS_DM_CA | \ + WR_VL_EN(!PSRSAM_FIX_LATENCY) | RD_VL_EN(!PSRSAM_FIX_LATENCY) | RD_WEIGHT(0x2); + //0x134 waiting update typedefine + psram_ctrl->DEVICE_INFO = BIT_DATA_UNIT_2B | BIT_JEDEC_P2CMF | BIT_PSRAM | ATOM_SIZE(0x1) | BIT_RD_PAGE_EN | \ + BIT_WR_PAGE_EN | PAGE_SIZE(PsramInfo.Psram_Page_size); + psram_ctrl->TPR1 &= ~(MASK_CR_IDLE_WINDOW | MASK_CR_TPWR); + psram_ctrl->TPR0 = (CS_TCEM(Psram_Tcem_T85 * 1000 / PsramInfo.PSRAMC_Clk_Unit / 32)) | \ + (CS_SEQ_TIMEOUT(Psram_Seq_timeout)) | \ + (CS_ACTIVE_HOLD(Psram_WB_CSH)) | \ + (CS_H_WR_DUM_LEN(((PsramInfo.Psram_TRWR * 1000 + PsramInfo.PSRAMC_Clk_Unit - 1) / PsramInfo.PSRAMC_Clk_Unit - 2 - 3 - 1))) | \ + (CS_H_RD_DUM_LEN(((PsramInfo.Psram_TRWR * 1000 + PsramInfo.PSRAMC_Clk_Unit - 1) / PsramInfo.PSRAMC_Clk_Unit - 2 - 3 - 1))); + //0xe0 + psram_ctrl->READ_FAST_SINGLE = FRD_CMD(WB_RD_CMD); + //0xf4 + psram_ctrl->WRITE_SIGNLE = WR_CMD(WB_WR_CMD); + //0x11c + psram_ctrl->AUTO_LENGTH = AUTO_ADDR_LENGTH(0x5); + //0x118 + psram_ctrl->USER_LENGTH = USER_ADDR_LENGTH(0x5) | USER_CMD_LENGHT(0x1); + } else { + + //0x110 + psram_ctrl->CTRLR2 = BIT_SO_DNUM | TX_FIFO_ENTRY(0x5) | RX_FIFO_ENTRY(0x5) | BIT_DM_ACT | \ + WR_VL_EN(!PSRSAM_FIX_LATENCY) | RD_VL_EN(!PSRSAM_FIX_LATENCY) | RD_WEIGHT(0x2); + //0x134 waiting update typedefine + psram_ctrl->DEVICE_INFO = BIT_PSRAM | ATOM_SIZE(0x1) | BIT_RD_PAGE_EN | \ + BIT_WR_PAGE_EN | PAGE_SIZE(PsramInfo.Psram_Page_size); + //0x138 waiting update typedefine + //CS_TCEM = 0 for seq performance + //todo + psram_ctrl->TPR0 = (CS_TCEM(Psram_Tcem_T85 * 1000 / PsramInfo.PSRAMC_Clk_Unit / 32)) | \ + (CS_SEQ_TIMEOUT(Psram_Seq_timeout)) | \ + (CS_ACTIVE_HOLD(Psram_APM_CSH)) | \ + (CS_H_WR_DUM_LEN(PsramInfo.Psram_CSHI * 1000 / PsramInfo.PSRAMC_Clk_Unit)) | \ + (CS_H_RD_DUM_LEN(PsramInfo.Psram_CSHI * 1000 / PsramInfo.PSRAMC_Clk_Unit)); + psram_ctrl->READ_FAST_SINGLE = FRD_CMD(APM_RD_CMD); + psram_ctrl->WRITE_SIGNLE = WR_CMD(APM_WR_CMD); + //0x11c + psram_ctrl->AUTO_LENGTH = AUTO_ADDR_LENGTH(0x4); + //0x118 + psram_ctrl->USER_LENGTH = USER_ADDR_LENGTH(0x4) | USER_CMD_LENGHT(0x2); + } + + + if (PSRSAM_FIX_LATENCY) { + //auto rd latency + psram_ctrl->AUTO_LENGTH |= RD_DUMMY_LENGTH(2 * 2 * PsramInfo.Psram_Latency_Set - 1) | \ + IN_PHYSICAL_CYC(PSPHY_RFIFO_READY_DELAY_FIX + 2); + //auto wr latency + psram_ctrl->AUTO_LENGTH2 = WR_DUMMY_LENGTH(2 * 2 * PsramInfo.Psram_Latency_Set - 2); + + psram_ctrl->USER_LENGTH |= USER_RD_DUMMY_LENGTH(2 * 2 * PsramInfo.Psram_Latency_Set - 1); + } else { + //auto rd latency + psram_ctrl->AUTO_LENGTH |= RD_DUMMY_LENGTH(2 * PsramInfo.Psram_Latency_Set - 1) ; + //auto wr latency + psram_ctrl->AUTO_LENGTH2 = WR_DUMMY_LENGTH(2 * PsramInfo.Psram_Latency_Set - 2); + psram_ctrl->USER_LENGTH |= USER_RD_DUMMY_LENGTH(2 * PsramInfo.Psram_Latency_Set - 1); + } +} + + + +void PSRAM_APM_DEVIC_Init(void) +{ + u8 mr0[2]; + u8 mr4[2]; + mr0[0] = PSRAM_READ_LATENCY_CODE(PsramInfo.Psram_Latency_Set - 3) | \ + PSRAM_LT_SELECT(PSRSAM_FIX_LATENCY) | \ + PSRAM_Drive_Strength(APM_Drive_Strength_100ohms); //0:variable latency 1:fix latency + + mr4[0] = PSRAM_WRITE_LATENCY_CODE(APM_WR_INIT_LATENCY_SPEC[PsramInfo.Psram_Latency_Set - 3]); + + mr0[1] = mr0[0]; + mr4[1] = mr4[0]; + + PSRAM_REG_Write(MCM_PSRAM_VENDOR_APM, 0x0, 2, mr0); + PSRAM_REG_Write(MCM_PSRAM_VENDOR_APM, 0x4, 2, mr4); +} + +void PSRAM_WB_DEVIC_Init(void) +{ + u8 data[2]; + data[0] = PSRAM_WB_RESERVER | \ + PSRAM_WB_DRIVE_STRENGTH(WB_Drive_Strength_100ohms) | \ + PSRAM_WB_DPD_EN(WB_NORMAL_OPE); + + data[1] = PSRAM_WB_BURST_LENGTH(WB_BURST_LEN_128B) | \ + PSRAM_WB_HyBURSE_EN | \ + PSRAM_WB_FIX_LATENCY_EN(PSRSAM_FIX_LATENCY) | \ + PSRAM_WB_INIT_LATENCY(PsramInfo.Psram_Latency_Code); + + PSRAM_REG_Write(MCM_PSRAM_VENDOR_WB, PSRAM_WB_CR0, 2, data); +} + + +/** + * @brief Get APM/Winbond PSRAM register value + * @param type: APM :0 Winbond:1 + * @param addr: APM/Winbond PSRAM register addr + * @param read_len: read data length + * @param read_data: read data output buf + * @retval None + */ +NON_DRAM_TEXT_SECTION +void PSRAM_REG_Read(u8 type, u32 addr, u32 read_len, u8 *read_data, u32 CR) +{ + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + u32 rx_num = 0; + + /* Wait spic busy done before switch to user mode */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Enter User Mode */ + psram_ctrl->CTRLR0 |= BIT_USER_MODE; + + /* Disable SSIENR to program control registers*/ + psram_ctrl->SSIENR = 0; + + /* Set RX_NDF: frame number of receiving data. TX_NDF should be set in both transmit mode and receive mode. + TX_NDF should be set to zero in receive mode to skip the TX_DATA phase. */ + psram_ctrl->RX_NDF = RX_NDF(read_len); + psram_ctrl->TX_NDF = 0; + //RTK_LOGD(TAG, "RX_NDF = %p %lx\n", &(psram_ctrl->RX_NDF), psram_ctrl->RX_NDF); + + //set rx mode + psram_ctrl->CTRLR0 |= TMOD(3); + //RTK_LOGD(TAG, "CTRLR0 = %p %lx\n", &(psram_ctrl->CTRLR0), psram_ctrl->CTRLR0); + + /* set flash_cmd: write cmd to fifo */ + if (type == MCM_PSRAM_VENDOR_APM) { + psram_ctrl->DR[0].BYTE = 0x40; + psram_ctrl->DR[0].BYTE = 0x40; + } else { + psram_ctrl->DR[0].BYTE = 0xe0; + psram_ctrl->DR[0].BYTE = 0x00; + } + + + if (CR) { + psram_ctrl->DR[0].BYTE = 0x01; + } else { + psram_ctrl->DR[0].BYTE = 0x00; // IR reg read only + } + + psram_ctrl->DR[0].BYTE = 0x00; + psram_ctrl->DR[0].BYTE = 0x00; + + psram_ctrl->DR[0].BYTE = (u8)(addr & 0xFF);//addr + + + /* Enable SPI_FLASH User Mode */ + psram_ctrl->SSIENR = BIT_SPIC_EN; + while (psram_ctrl->SSIENR & BIT_SPIC_EN) { + }; + + /* read data */ + rx_num = 0; + + while (rx_num < read_len) { + read_data[rx_num] = psram_ctrl->DR[0].BYTE; + rx_num += 1; + } + + /* Wait transfer complete. When complete, SSIENR[0] and CTRLR0[31] is cleared by HW automatically. */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Restore to auto mode */ + psram_ctrl->CTRLR0 &= ~BIT_USER_MODE; + +} + +/** + * @brief set APM/Winbond PSRAM register value + * @param type: APM :0 Winbond:1 + * @param addr: PSRAM register addr + * @param write_len: write data length + * @param write_data: write data buf + * @retval None + */ +NON_DRAM_TEXT_SECTION +void PSRAM_REG_Write(u8 type, u32 addr, u32 write_len, u8 *write_data) +{ + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + u32 tx_num = 0; + + /* Wait spic busy done before switch to user mode */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Enter User Mode */ + psram_ctrl->CTRLR0 |= BIT_USER_MODE; + + /* Disable SSIENR to program control registers*/ + psram_ctrl->SSIENR = 0; + + //set tx mode + psram_ctrl->CTRLR0 &= ~(TMOD(3)); + + /* Set RX_NDF: frame number of receiving data. TX_NDF should be set in both transmit mode and receive mode. + TX_NDF should be set to zero in receive mode to skip the TX_DATA phase. */ + psram_ctrl->RX_NDF = 0; + psram_ctrl->TX_NDF = TX_NDF(write_len); + + /* set flash_cmd: write cmd to fifo */ + if (type == MCM_PSRAM_VENDOR_APM) { + + psram_ctrl->DR[0].BYTE = 0xc0; + psram_ctrl->DR[0].BYTE = 0xc0; + } else { + + psram_ctrl->DR[0].BYTE = 0x60; + psram_ctrl->DR[0].BYTE = 0x00; + } + + psram_ctrl->DR[0].BYTE = 0x01; + psram_ctrl->DR[0].BYTE = 0x00; + psram_ctrl->DR[0].BYTE = 0x00; + + psram_ctrl->DR[0].BYTE = (u8)(addr & 0xFF);//addr + + /* fill data */ + for (tx_num = 0; tx_num < write_len; tx_num++) { + psram_ctrl->DR[0].BYTE = (u8) * (write_data + tx_num); + } + + /* Enable SPI_FLASH User Mode */ + psram_ctrl->SSIENR = BIT_SPIC_EN; + while (psram_ctrl->SSIENR & BIT_SPIC_EN) { + }; + + /* Wait transfer complete. When complete, SSIENR[0] and CTRLR0[31] is cleared by HW automatically. */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Restore to auto mode */ + psram_ctrl->CTRLR0 &= ~BIT_USER_MODE; + +} + +/** + * @brief set APM PSRAM register value + * @param cmd: APM PSRAM write mem cmd: 0x80 or 0xa0 + * @param addr: APM PSRAM register addr + * @param write_len: write data length + * @param write_data: write data buf + * @retval None + */ + +void PSRAM_MEM_Write(u8 cmd, u32 addr, u32 write_len, u8 *write_data) +{ + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + u32 tx_num = 0; + u32 txlen = write_len + (PsramInfo.Psram_Latency_Set - 1) * 2; + + /* Wait spic busy done before switch to user mode */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Enter User Mode */ + psram_ctrl->CTRLR0 |= BIT_USER_MODE; + + /* Disable SSIENR to program control registers*/ + psram_ctrl->SSIENR = 0; + + //set tx mode + psram_ctrl->CTRLR0 &= ~(TMOD(3)); + RTK_LOGI(TAG, "CTRLR0 = %p %lx\n", &(psram_ctrl->CTRLR0), psram_ctrl->CTRLR0); + + /* Set RX_NDF: frame number of receiving data. TX_NDF should be set in both transmit mode and receive mode. + TX_NDF should be set to zero in receive mode to skip the TX_DATA phase. */ + psram_ctrl->RX_NDF = 0; + psram_ctrl->TX_NDF = TX_NDF(txlen); + + addr = addr - PSRAM_BASE; + + /* set flash_cmd: write cmd to fifo */ + psram_ctrl->DR[0].BYTE = cmd; + psram_ctrl->DR[0].BYTE = cmd; + psram_ctrl->DR[0].BYTE = (u8)((addr & 0xFF000000) >> 24); + psram_ctrl->DR[0].BYTE = (u8)((addr & 0xFF0000) >> 16); + psram_ctrl->DR[0].BYTE = (u8)((addr & 0xFF00) >> 8); + psram_ctrl->DR[0].BYTE = (u8)(addr & 0xFF); + + /* fill data */ + for (tx_num = 0; tx_num < (PsramInfo.Psram_Latency_Set - 1) * 2; tx_num++) { + psram_ctrl->DR[0].BYTE = 0x0; + } + + /* fill data */ + for (tx_num = 0; tx_num < write_len; tx_num++) { + psram_ctrl->DR[0].BYTE = (u8) * (write_data + tx_num); + } + + /* Enable SPI_FLASH User Mode */ + psram_ctrl->SSIENR = BIT_SPIC_EN; + + while (psram_ctrl->SSIENR & BIT_SPIC_EN) { + }; + + /* Wait transfer complete. When complete, SSIENR[0] and CTRLR0[31] is cleared by HW automatically. */ + while (psram_ctrl->SR & BIT_BUSY); + + /* Restore to auto mode */ + psram_ctrl->CTRLR0 &= ~BIT_USER_MODE; + +} + +void PSRAM_calwindow(int window_start, int window_end, PCAL_InitTypeDef *PCAL_InitStruct) +{ + u32 suggest_phase = 0; + int window_size = 0; + int windowt_size, windowt_start, windowt_end; + int JMAX_val = 0; + int J_val = 0; + int N_val = 0; + int i, head, tail; + u32 phase; + for (i = 0; i < 4; i++) { + head = i * 16; + tail = head + 31; + phase = BIT(i); + windowt_start = head > window_start ? head : window_start; + windowt_end = tail < window_end ? tail : window_end; + windowt_size = windowt_end - windowt_start + 1; + if (windowt_size > window_size) { + + window_size = windowt_size; + N_val = (windowt_start + windowt_end - head - head) / 2; + JMAX_val = (windowt_end - windowt_start) / 2 - 2; + J_val = (windowt_end - windowt_start) / 2 - 2; + suggest_phase = phase; + } + } + + if (window_size > PCAL_InitStruct->window_size) { + PCAL_InitStruct->window_size = window_size; + PCAL_InitStruct->CAL_JMAX = JMAX_val; + PCAL_InitStruct->CAL_J = J_val; + PCAL_InitStruct->CAL_N = N_val; + PCAL_InitStruct->phase = suggest_phase; + } + +} + +/** + * @brief PSRAM FW calibration function + * @retval None + * @note cache will be disable during calibration + */ +bool PSRAM_calibration(u32 log_en) +{ + PSPHY_TypeDef *psram_phy = PSRAMPHY_DEV; + + u32 caltempN = 0; + u32 phase = 0; + u32 tempPHYPara = psram_phy->PSPHY_CAL_PAR & (~PSPHY_MASK_CFG_CAL_N) & (~PSPHY_MASK_PRE_CAL_PHASE); + const u32 *tempdatawr = PSRAM_CALIB_PATTERN; + u32 tempdatard[6] = {0, 0, 0, 0, 0, 0}; + int window_start = -1; + int window_end = -1; + int window_size = 0; + + int windowt_start = -1; + int windowt_size = 0; + int windowt_end = -1; + + int phase_cnt = -1; + + /*Disable HW calibration*/ + psram_phy->PSPHY_CAL_CTRL &= (~PSPHY_BIT_CFG_CAL_EN); + for (phase = 0x0; phase <= 0x8; phase = (phase == 0 ? phase + 1 : phase * 2)) { + windowt_size = 0; + windowt_start = -1; + windowt_end = -1; + if (log_en) { + RTK_LOGI(TAG, "===phase %lx =====\n", phase); + } + for (caltempN = 0; caltempN < 32; caltempN++) { + psram_phy->PSPHY_CAL_PAR = tempPHYPara | caltempN | PSPHY_PRE_CAL_PHASE(phase); + /*PG needs to be recalibrated when the temperature changes sharply. + To avoid accessing the secure address, the calibration address starts from __km4_bd_psram_start__.*/ + for (int i = 0; i < 6; i += 1) { + HAL_WRITE32((u32)__km4_bd_psram_start__, i * 0x50000, tempdatawr[i]); + DCache_CleanInvalidate((u32)__km4_bd_psram_start__ + i * 0x50000, CACHE_LINE_SIZE); + tempdatard[i] = HAL_READ32((u32)__km4_bd_psram_start__, i * 0x50000); + } + + if (_memcmp(tempdatard, PSRAM_CALIB_PATTERN, 24) == 0) { + if (log_en) { + RTK_LOGI(TAG, "ok %lx %lx %lx %lx %lx %lx %lx\n", caltempN, tempdatard[0], tempdatard[1], tempdatard[2], tempdatard[3], tempdatard[4], tempdatard[5]); + } + if (windowt_start < 0) { + windowt_start = caltempN; + } + windowt_end = windowt_start + windowt_size; + windowt_size ++; + + if (caltempN == (32 - 1)) { + if (windowt_size > window_size) { + window_start = windowt_start; + window_end = windowt_end; + window_size = windowt_size; + phase_cnt = phase; + } + } + } else { + if (log_en) { + RTK_LOGI(TAG, "fail %lx %lx %lx %lx %lx %lx %lx\n", caltempN, tempdatard[0], tempdatard[1], tempdatard[2], tempdatard[3], tempdatard[4], tempdatard[5]); + } + if (windowt_start >= 0) { + if (windowt_size > window_size) { + window_start = windowt_start; + window_end = windowt_end; + window_size = windowt_size; + phase_cnt = phase; + + } + windowt_start = -1; + windowt_size = 0; + windowt_end = -1; + } + } + } + } + + + RTK_LOGI(TAG, "CalNmin = %x CalNmax = %x WindowSize = %x phase: %x \n", window_start, window_end, window_size, phase_cnt); + + if ((window_size) < 9) { + return FALSE; + } + tempPHYPara &= (~0xfffff); + tempPHYPara |= PSPHY_CFG_CAL_JMAX((window_end - window_start) / 2 - 2) | \ + PSPHY_CFG_CAL_J((window_end - window_start) / 2 - 2) | \ + PSPHY_CFG_CAL_N((window_end + window_start) / 2) | \ + PSPHY_PRE_CAL_PHASE(phase_cnt); + + psram_phy->PSPHY_CAL_PAR = tempPHYPara; + + /*start HW calibration*/ + psram_phy->PSPHY_CAL_CTRL |= PSPHY_BIT_CFG_CAL_EN; + + return TRUE; + +} + + +/** + * @brief set psram into half sleep mode. + * @param type: 0:apm psram type 1: winbond psram type + * @retval None + * @note None + */ +NON_DRAM_TEXT_SECTION +void set_psram_sleep_mode(void) +{ + u8 psram_halfsleep[2]; + u8 mr4[2]; + + RRAM_TypeDef *rram = RRAM_DEV; + PSPHY_TypeDef *psram_phy = PSRAMPHY_DEV; + psram_phy->PSPHY_CAL_CTRL = PSRAM_MASK_CAL_ITT; + + rram->psram_backup[0] = HAL_READ32((u32)__km4_bd_psram_start__, 0x0); + rram->psram_backup[1] = HAL_READ32((u32)__km4_bd_psram_start__, 0x50000); + rram->psram_backup[2] = HAL_READ32((u32)__km4_bd_psram_start__, 0x100000); + rram->psram_backup[3] = HAL_READ32((u32)__km4_bd_psram_start__, 0x150000); + rram->psram_backup[4] = HAL_READ32((u32)__km4_bd_psram_start__, 0x200000); + rram->psram_backup[5] = HAL_READ32((u32)__km4_bd_psram_start__, 0x250000); + + if (rram->PSRAM_TYPE == MCM_PSRAM_VENDOR_APM) { + psram_halfsleep[0] = 0xF0; + psram_halfsleep[1] = 0xF0; + + /*enable apm slow refresh*/ + PSRAM_REG_Read(MCM_PSRAM_VENDOR_APM, 0x4, 2, mr4, 1); + mr4[0] |= PSRAM_ENABLE_SLOW_REFRESH; + mr4[1] = mr4[0]; + PSRAM_REG_Write(MCM_PSRAM_VENDOR_APM, 0x4, 2, mr4); + PSRAM_REG_Write(MCM_PSRAM_VENDOR_APM, 0x06, 2, psram_halfsleep); + + } else { + psram_halfsleep[0] = 0xFF; + psram_halfsleep[1] = 0x20; + + PSRAM_REG_Write(MCM_PSRAM_VENDOR_WB, 0x1, 2, psram_halfsleep); + } + +} + +/** + * @brief Wake PSRAM from half sleep mode. + * @param type: 0:apm psram type 1: winbond psram type + * @retval None + * @note None + */ +_OPTIMIZE_NONE_ +NON_DRAM_TEXT_SECTION +void set_psram_wakeup_mode(void) +{ + u32 temp, rdata; + u8 mr4[2]; + u8 psram_type; + + RRAM_TypeDef *rram = RRAM_DEV; + PSPHY_TypeDef *psram_phy = PSRAMPHY_DEV; + SPIC_TypeDef *psram_ctrl = PSRAMC_DEV; + psram_type = rram->PSRAM_TYPE; + + /*1. auto read , trigger psram to exit sleep mode*/ + DCache_Invalidate((u32)__km4_bd_psram_start__, 32); + rdata = HAL_READ32((u32)__km4_bd_psram_start__, 0); + + /* 2. when PG wakeup, fisrt read will cause phy hang, set PSPHY_PHY_INFO to return work correctly*/ + temp = psram_phy->PSPHY_PHY_INFO; + psram_phy->PSPHY_PHY_INFO = temp; + + /*3. wait for Txhs until psram exit sleep mode*/ + if (psram_type == MCM_PSRAM_VENDOR_APM) { + DelayUs(150); + } else if (psram_type == MCM_PSRAM_VENDOR_WB) { + DelayUs(100); + } + + /* 4. read again. */ + DCache_Invalidate((u32)__km4_bd_psram_start__, 32); + rdata = HAL_READ32((u32)__km4_bd_psram_start__, 0); + + /* 5. Check if the window has changed. */ + if (PSRAM_CHECK_INT(psram_phy->PSPHY_CAL_CTRL)) { + rdata = psram_phy->PSPHY_CAL_CTRL; + psram_phy->PSPHY_CAL_CTRL = rdata; + PSRAM_calibration(DISABLE); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x0, rram->psram_backup[0]); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x50000, rram->psram_backup[1]); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x100000, rram->psram_backup[2]); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x150000, rram->psram_backup[3]); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x200000, rram->psram_backup[4]); + HAL_WRITE32((u32)__km4_bd_psram_start__, 0x250000, rram->psram_backup[5]); + } + + /*6. backfill the value of the register*/ + psram_ctrl->TPR1 &= ~(MASK_CR_IDLE_WINDOW | MASK_CR_TPWR); + + /*7. disable apm slow refresh*/ + if (psram_type == MCM_PSRAM_VENDOR_APM) { + PSRAM_REG_Read(MCM_PSRAM_VENDOR_APM, 0x4, 2, mr4, 1); + mr4[0] &= ~PSRAM_ENABLE_SLOW_REFRESH; + mr4[1] = mr4[0]; + PSRAM_REG_Write(MCM_PSRAM_VENDOR_APM, 0x4, 2, mr4); + } +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_qspi.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_qspi.c new file mode 100644 index 00000000..33f14bc5 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_qspi.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +#include "os_wrapper.h" + +static const char *const TAG = "QSPI"; +static struct GDMA_CH_LLI *qspi_gdma_lli; + +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup QSPI +* @brief QSPI driver modules +* @{ +*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup QSPI_Exported_Functions QSPI Exported Functions + * @{ + */ + +/** + * @brief Initialize QSPI to user mode. + * @param None. + * @retval None. + */ +void QSPI_Init(void) +{ + /* set cs and baudrate */ + QSPI->SSIENR = 0; + QSPI->SER = BIT_SER; + QSPI->BAUDR = 1; + + /* enter user mode */ + QSPI->CTRLR0 |= BIT_USER_MODE; + QSPI->CTRLR0 |= BIT_SPI_DREIR_R_DIS; + + /* user mode is entered after auto cmd is done, which means if SPIC BUSY=1, HW will not write Ctrl0 */ + while (!(QSPI->CTRLR0 & BIT_USER_MODE)); +} + +/** + * @brief Initialize QSPI_CmdAddrInfo structure. + * @param info: cmd and addr info given by user. + * @retval None. + */ +void QSPI_StructInit(QSPI_CmdAddrInfo *info) +{ + info->cmd_length = 1; + info->addr_length = 0; + info->cmd_ch = 0; + info->addr_ch = 0; + info->data_ch = 0; + info->ddr_en = 0; + info->rx_dummy_cycle = 0; +} + +/** + * @brief Set baud value to divide clock. + * @param div: actual QSPI clock = bus_clk/(2 * div). + * @retval None. + */ +void QSPI_SetBaud(u32 div) +{ + QSPI->BAUDR = div; +} + + +/** + * @brief Set SO_DUM value to determine if sdo & sdi use same line. + * @param val: val = 0 means use same line, other value means use different line. + * @retval None. + */ +void QSPI_SO_DNUM(u32 val) +{ + if (val == 0) { + QSPI->CTRLR2 &= ~(BIT_SO_DNUM); + } else { + QSPI->CTRLR2 |= BIT_SO_DNUM; + } +} + + +/** + * @brief Write data by CPU according to the given parameter. + * @param info: cmd and addr info given by user. + * data: data to transmit. + * len: transmit data length. + * @retval None. + */ +void QSPI_Write(QSPI_CmdAddrInfo *info, u8 *data, u32 len) +{ + u32 reg, i; + QSPI->SER = BIT_SER; + + /* Disable QSPI */ + QSPI->SSIENR = 0; + + QSPI->CTRLR0 &= ~MASK_DDR_EN; + QSPI->CTRLR0 |= DDR_EN(info->ddr_en); + + /* Set Channel number */ + QSPI->CTRLR0 &= ~(TMOD(3) | CMD_CH(3) | ADDR_CH(3) | DATA_CH(3)); + QSPI->CTRLR0 |= (CMD_CH(info->cmd_ch) | ADDR_CH(info->addr_ch) | DATA_CH(info->data_ch)); + + /* Set tx mode */ + QSPI->CTRLR0 &= ~(TMOD(3)); + + /* Set cmd and addr length */ + reg = QSPI->USER_LENGTH & ~(MASK_USER_ADDR_LENGTH | MASK_USER_CMD_LENGHT); + QSPI->USER_LENGTH = reg | USER_ADDR_LENGTH(info->addr_length) | USER_CMD_LENGHT(info->cmd_length); + + /* Set tx length */ + QSPI->RX_NDF = 0; + QSPI->TX_NDF = TX_NDF(len); + + /* Send cmd */ + for (i = 0; i < info->cmd_length; i++) { + QSPI->DR[0].BYTE = info->cmd[i]; + } + + /* Send addr */ + for (i = 0; i < info->addr_length; i++) { + QSPI->DR[0].BYTE = info->addr[i]; + } + + /* Enable QSPI */ + QSPI->SSIENR = BIT_SPIC_EN; + + /* Send data */ + for (i = 0; i < len;) { + if (QSPI->SR & BIT_TFNF) { + QSPI->DR[0].BYTE = data[i]; + i++; + } + } + + /* Wait bus busy */ + while (QSPI->SR & BIT_BUSY); + + /* Disable QSPI */ + QSPI->SSIENR = 0; +} + +/** + * @brief Read data by CPU according to the given parameter. + * @param info: cmd and addr info given by user. + * data: pointer to recevie data. + * len: receive data length. + * @retval None. + */ +void QSPI_Read(QSPI_CmdAddrInfo *info, u8 *data, u32 len) +{ + u32 reg, i; + u32 rd_num = 0; + + /* Disable QSPI */ + QSPI->SSIENR = 0; + + /* Set Channel number */ + QSPI->CTRLR0 &= ~(CMD_CH(3) | ADDR_CH(3) | DATA_CH(3)); + QSPI->CTRLR0 |= (CMD_CH(info->cmd_ch) | ADDR_CH(info->addr_ch) | DATA_CH(info->data_ch)); + + /* Set rx mode */ + QSPI->CTRLR0 |= TMOD(3); + + /* Set rx length */ + QSPI->RX_NDF = RX_NDF(len); + QSPI->TX_NDF = 0; + + /* Set cmd and addr and dummy cycle length */ + reg = QSPI->USER_LENGTH & ~(MASK_USER_ADDR_LENGTH | MASK_USER_CMD_LENGHT); + QSPI->USER_LENGTH = reg | USER_ADDR_LENGTH(info->addr_length) | USER_CMD_LENGHT(info->cmd_length) + | USER_RD_DUMMY_LENGTH(info->rx_dummy_cycle * 2); + + /* Send cmd */ + for (i = 0; i < info->cmd_length; i++) { + QSPI->DR[0].BYTE = info->cmd[i]; + } + + /* Send addr */ + for (i = 0; i < info->addr_length; i++) { + QSPI->DR[0].BYTE = info->addr[i]; + } + + /* Enable QSPI */ + QSPI->SSIENR = BIT_SPIC_EN; + + while (rd_num < len) { + if (QSPI->SR & BIT_RFNE) { + data[rd_num] = QSPI->DR[0].BYTE; + rd_num ++; + } + } + + /* Disable QSPI */ + QSPI->SSIENR = 0; +} + +/** + * @brief Write data according to the given parameter through PPE or GDMA. User should + * enable PPE to QSPI or GDMA to QSPI handshake to start data transfer. + * @param info: cmd and addr info given by user. + * len: transmit data length. + * @retval None. + */ +void QSPI_WriteStart(QSPI_CmdAddrInfo *info, u32 len) +{ + u32 reg, i; + QSPI->SER = BIT_SER; + + /* Disable QSPI */ + QSPI->SSIENR = 0; + + QSPI->CTRLR0 &= ~MASK_DDR_EN; + QSPI->CTRLR0 |= DDR_EN(info->ddr_en); + + /* Set Channel number */ + QSPI->CTRLR0 &= ~(TMOD(3) | CMD_CH(3) | ADDR_CH(3) | DATA_CH(3)); + QSPI->CTRLR0 |= (CMD_CH(info->cmd_ch) | ADDR_CH(info->addr_ch) | DATA_CH(info->data_ch)); + + /* Set tx mode */ + QSPI->CTRLR0 &= ~(TMOD(3)); + + /* Set cmd and addr length */ + reg = QSPI->USER_LENGTH & ~(MASK_USER_ADDR_LENGTH | MASK_USER_CMD_LENGHT); + QSPI->USER_LENGTH = reg | USER_ADDR_LENGTH(info->addr_length) | USER_CMD_LENGHT(info->cmd_length); + + /* Set tx length */ + QSPI->RX_NDF = 0; + QSPI->TX_NDF = TX_NDF(len); + + /* DMA configuration*/ + QSPI->DMACR = 2; + QSPI->DMATDLR = 16; + + /* Send cmd */ + for (i = 0; i < info->cmd_length; i++) { + QSPI->DR[0].BYTE = info->cmd[i]; + } + + /* Send addr */ + for (i = 0; i < info->addr_length; i++) { + QSPI->DR[0].BYTE = info->addr[i]; + } + + /* Enable QSPI */ + QSPI->SSIENR = BIT_SPIC_EN; +} + + +/** + * @brief User could use this to disable QSPI After PPE or GDMA transfer complete. + * @param None. + * @retval None. + */ +void QSPI_WriteEnd(void) +{ + /* Wait bus busy */ + while (QSPI->SR & BIT_BUSY); + + /* Disable QSPI */ + QSPI->SSIENR = 0; +} + + +/** + * @brief Init data transfer from GDMA to QSPI. If size exceed GDMA max block size, use GDMA linklist function. + * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains + * the configuration information for the GDMA peripheral. + * @param CallbackData: GDMA callback data. + * @param CallbackFunc: GDMA callback function. + * @param pbuf: data buffer send to QSPI. Must be 4-bytes aligned. + * @param size: buffer size; + * @retval TRUE/FLASE + */ +int QSPI_GDMAInit(GDMA_InitTypeDef *GDMA_InitStruct, + IRQ_FUN CallbackFunc, + void *CallbackData, + u8 *Pbuf, + u32 Size) +{ + u8 GdmaChnl; + u32 blocksize = 65535 * 4; //GDMA max block size 65535, data width 4B + u32 blockcnt = (Size / blocksize) + 1; + u32 llisize; + + GdmaChnl = GDMA_ChnlAlloc(0, (IRQ_FUN)CallbackFunc, (u32)CallbackData, INT_PRI_HIGHEST); + if (GdmaChnl == 0xFF) { + /* No Available DMA channel */ + RTK_LOGE(TAG, "Alloc dma channel fail\n"); + return FALSE; + } + + /* Set QSPI hw handshake to GDMA */ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_ECO_CTRL, HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_ECO_CTRL) | BIT_QSPI_HW_HANDSHAKE_SEL); + + _memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef)); + GDMA_InitStruct->MuliBlockCunt = 0; + GDMA_InitStruct->MaxMuliBlock = blockcnt; + GDMA_InitStruct->GDMA_DIR = TTFCMemToPeri; + GDMA_InitStruct->GDMA_DstHandshakeInterface = GDMA_HANDSHAKE_INTERFACE_SPIC_TX; + GDMA_InitStruct->GDMA_DstAddr = (u32) & (QSPI->DR[0].BYTE); + GDMA_InitStruct->GDMA_Index = 0; + GDMA_InitStruct->GDMA_ChNum = GdmaChnl; + GDMA_InitStruct->GDMA_IsrType = (TransferType | ErrType); + GDMA_InitStruct->GDMA_DstMsize = MsizeFour; + GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes; + GDMA_InitStruct->GDMA_DstInc = NoChange; + GDMA_InitStruct->GDMA_SrcInc = IncType; + /* 4-bytes aligned, move 4 bytes each transfer */ + GDMA_InitStruct->GDMA_SrcMsize = MsizeFour; + GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes; + GDMA_InitStruct->GDMA_BlockSize = Size >> 2; + GDMA_InitStruct->GDMA_SrcAddr = (u32)(Pbuf); + + if (blockcnt > 1) { + GDMA_InitStruct->GDMA_LlpSrcEn = 1; + GDMA_InitStruct->GDMA_LlpDstEn = 1; + } else { + GDMA_InitStruct->GDMA_LlpSrcEn = 0; + GDMA_InitStruct->GDMA_LlpDstEn = 0; + } + + GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct); + + /* Note that GDMA max block size is 65536*4. If display buffer is exceed it, GDMA linklist function should be used. + GDMA multi-block function is not suitable because it need extra interrupt for each block but we need only a + transfer done interrupt. */ + if (blockcnt > 1) { + llisize = blockcnt * sizeof(struct GDMA_CH_LLI); + qspi_gdma_lli = (struct GDMA_CH_LLI *) rtos_mem_malloc(llisize); + _memset(qspi_gdma_lli, 0, llisize); + + for (u32 i = 0; i < blockcnt; i++) { + qspi_gdma_lli[i].LliEle.Sarx = ((u32)Pbuf) + blocksize * i; + qspi_gdma_lli[i].LliEle.Darx = (u32) & (QSPI->DR[0].BYTE); + + if (i != (blockcnt - 1)) { + qspi_gdma_lli[i].BlockSize = (blocksize) >> GDMA_InitStruct->GDMA_SrcDataWidth; + qspi_gdma_lli[i].pNextLli = &qspi_gdma_lli[i + 1]; + } else { + qspi_gdma_lli[i].BlockSize = (Size - i * blocksize) >> GDMA_InitStruct->GDMA_SrcDataWidth; + qspi_gdma_lli[i].pNextLli = NULL; + } + } + GDMA_SetLLP(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct->MaxMuliBlock, qspi_gdma_lli, 0); + } + + return TRUE; +} + +/** + * @brief Deinit GDMA used by QSPI. + * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains + * the configuration information for the GDMA peripheral. + * @retval TRUE/FLASE + */ +int QSPI_GDMADeinit(GDMA_InitTypeDef *GDMA_InitStruct) +{ + GDMA_ChnlFree(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum); + GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, DISABLE); + + if (qspi_gdma_lli) { + rtos_mem_free(qspi_gdma_lli); + } + + return TRUE; +} + + +/** + * @brief start data transfer from GDMA to QSPI. + * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains + * the configuration information for the GDMA peripheral. + * @retval None. + */ +void QSPI_GDMAStart(GDMA_InitTypeDef *GDMA_InitStruct) +{ + GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE); +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_sdio.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_sdio.c new file mode 100644 index 00000000..1334bdb5 --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_sdio.c @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +/** @defgroup SDIO_Exported_Functions SDIO Exported Functions + * @{ + */ + +/** + * @brief Fills each SDIO_InitStruct member with its default value. + * @param SDIO_InitStruct: pointer to a SDIO_InitTypeDef structure which will be + * initialized. + * @retval None + */ +void SDIO_StructInit(SDIO_InitTypeDef *SDIO_InitStruct) +{ + /* TXBD */ + SDIO_InitStruct->TXBD_BAR = (u32)NULL; /* init txbd_bar */ + SDIO_InitStruct->TXBD_RING_SIZE = 20; /* init TXBD ring size */ + SDIO_InitStruct->TX_BUFFER_SIZE = 0xFF; /* init txbuf_size */ + + /* RXBD */ + SDIO_InitStruct->RXBD_BAR = (u32)NULL; /* init rxbd_bar reg */ + SDIO_InitStruct->RXBD_RING_SIZE = 32; /* init rxbd ring size */ + SDIO_InitStruct->RXBD_FREE_TH = 5; /* init AHB rx_blk_size */ +} + +/** + * @brief Initializes the SDIO registers according to the specified parameters + * in SDIO_InitStruct. Note that pinmux function and CCCR(if need) should be + * configured before this function. + * @param SDIO_InitStruct: pointer to a SDIO_InitTypeDef structure that contains + * the configuration information for the SDIO peripheral. + * @retval None + */ +void SDIO_Init(SDIO_TypeDef *SDIO, SDIO_InitTypeDef *SDIOInit_Struct) +{ + UNUSED(SDIO); + + u16 Temp = 0; + + /* Set PID to 0x8722 */ + HAL_WRITE16(SDIO_CCCR_REG_BASE, MANF_PID, 0x8722); + + /* CCCR Autoload done */ + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_CPU_IND, + HAL_READ8(SDIO_REG_BASE, REG_SPDIO_CPU_IND) | BIT_SYSTEM_READEE_DONE); + + /* SDIO pinmux funtion enable */ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_USB_SDIO_CTRL, + HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_USB_SDIO_CTRL) | LSYS_BIT_SDD_PMUX_FEN); + + /* Reset SDIO DMA */ + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_CPU_RST_DMA, BIT_CPU_RST_SDIO_DMA); + + /* initial TX BD */ + HAL_WRITE32(SDIO_REG_BASE, REG_SPDIO_TXBD_ADDR, SDIOInit_Struct->TXBD_BAR); + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_TXBD_SIZE, SDIOInit_Struct->TXBD_RING_SIZE); + + /* Set TX_BUFF_UNIT_SIZE */ + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_TX_BUF_UNIT_SZ, SDIOInit_Struct->TX_BUFFER_SIZE); + + /* Set DISPATCH_TXAGG_PKT */ + HAL_WRITE32(SDIO_REG_BASE, REG_SPDIO_AHB_DMA_CTRL, HAL_READ32(SDIO_REG_BASE, REG_SPDIO_AHB_DMA_CTRL) | DISPATCH_TXAGG_PKT); + + /* Reset HW TX BD pointer */ + HAL_WRITE32(SDIO_REG_BASE, REG_SPDIO_TXBD_RPTR, HAL_READ32(SDIO_REG_BASE, REG_SPDIO_TXBD_WPTR)); + + /* Init RX BD and RX Buffer */ + HAL_WRITE32(SDIO_REG_BASE, REG_SPDIO_RXBD_ADDR, SDIOInit_Struct->RXBD_BAR); + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_RXBD_SIZE, SDIOInit_Struct->RXBD_RING_SIZE); + + /* Reset HW RX BD pointer */ + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_RXBD_C2H_WPTR, HAL_READ16(SDIO_REG_BASE, REG_SPDIO_RXBD_C2H_RPTR)); + + /* Set the threshold of free RX BD count to trigger interrupt */ + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_RX_BD_FREE_CNT, SDIOInit_Struct->RXBD_FREE_TH); + + /* Indicate Host this is a iNIC FW */ + Temp = HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CCPWM2); + Temp |= CPWM2_INIC_FW_RDY_BIT; + Temp ^= CPWM2_TOGGLE_BIT; + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_CCPWM2, Temp); +} + +/** + * @brief SDIO interrupt clear + * @note clear all interrupt of SDIO + * @retval None + */ +void SDIO_INTClear(SDIO_TypeDef *SDIO, u16 IntStatus) +{ + UNUSED(SDIO); + + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_STAS, IntStatus); // clean the ISR +} + +/** + * @brief SDIO interrupt clear + * @note clear all interrupt of SDIO + * @retval None + */ +void SDIO_INTClearAll(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + u16 IntStatus; + + IntStatus = HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_STAS); + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_STAS, IntStatus); // clean the ISR +} + + +/** + * @brief SDIO disable or enable interrupt by modify the interrupt mask + * @param IntMask: The bit map to enable the interrupt. + * This parameter can be one or combinations of the following values: + * @arg BIT_TXFIFO_H2C_OVF: + * @arg BIT_H2C_BUS_RES_FAIL: + * @arg BIT_H2C_DMA_OK: + * @arg BIT_C2H_DMA_OK: + * @arg BIT_H2C_MSG_INT: + * @arg BIT_RPWM1_INT: + * @arg BIT_RPWM2_INT: + * @arg BIT_SDIO_RST_CMD_INT: + * @arg BIT_RXBD_FLAG_ERR_INT: + * @arg BIT_RX_BD_AVAI_INT: + * @arg BIT_HOST_WAKE_CPU_INT: + * @param NewState: ENABLE or DISABLE. + * @retval None + */ +void SDIO_INTConfig(SDIO_TypeDef *SDIO, u16 IntMask, u32 NewState) +{ + UNUSED(SDIO); + + u16 IntMaskTmp = HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_MASK); + + if (NewState == ENABLE) { + IntMaskTmp |= IntMask; + } else { + IntMaskTmp &= ~IntMask; + } + + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_MASK, IntMaskTmp); +} + +/** + * @brief Get SDIO interrupt status + * @param None. + * @retval Interrupt status + */ +u16 SDIO_INTStatus(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CPU_INT_STAS); +} + +/** + * @brief Get RPWM1 from host. + * @param None. + * @retval RPWM1 val. + */ +u8 SDIO_RPWM1_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ8(SDIO_REG_BASE, REG_SPDIO_CRPWM); +} + +/** + * @brief Get RPWM2 from host. + * @param None. + * @retval RPWM2 val. + */ +u16 SDIO_RPWM2_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CRPWM2); +} + +/** + * @brief Set CPWM1 to host + * @param Val: CPWM msg to send. + * @retval None + */ +void SDIO_CPWM1_Set(SDIO_TypeDef *SDIO, u8 Val) +{ + UNUSED(SDIO); + + u8 Temp = HAL_READ8(SDIO_REG_BASE, REG_SPDIO_CCPWM); + + Temp ^= CPWM1_TOGGLE_BIT; + Temp |= Val; + + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_CCPWM, Temp); +} + +/** + * @brief Set CPWM2 to host + * @param Val: CPWM msg to send. + * @param Newstate: DISABLE/ENABLE. + * @retval None + */ +void SDIO_CPWM2_Set(SDIO_TypeDef *SDIO, u16 Val, u32 Newstate) +{ + UNUSED(SDIO); + + u16 Temp = HAL_READ16(SDIO_REG_BASE, REG_SPDIO_CCPWM2); + + Temp ^= CPWM2_TOGGLE_BIT; + + if (Newstate == ENABLE) { + Temp |= Val; + } else { + Temp &= ~Val; + } + + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_CCPWM2, Temp); +} + +/** + * @brief Get H2C message from host. + * @param None. + * @retval H2C message val. + */ +u32 SDIO_H2C_MSG_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ32(SDIO_REG_BASE, REG_SPDIO_CPU_H2C_MSG); +} + +/** + * @brief Get RXBD read pointer, updated by SDIO IP. + * @param None + * @retval RXBD read pointer + */ +u16 SDIO_RXBD_RPTR_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ16(SDIO_REG_BASE, REG_SPDIO_RXBD_C2H_RPTR); +} + +/** + * @brief Set RXBD write pointer, updated by cpu CM4 driver. + * @param Val: RXBD write pointer + * @retval None + */ +void SDIO_RXBD_WPTR_Set(SDIO_TypeDef *SDIO, u16 Val) +{ + UNUSED(SDIO); + + HAL_WRITE16(SDIO_REG_BASE, REG_SPDIO_RXBD_C2H_WPTR, Val); +} + +/** + * @brief Get TXBD write pointer, updated by SDIO IP. + * @param None + * @retval TXBD write pointer + */ +u32 SDIO_TXBD_WPTR_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ32(SDIO_REG_BASE, REG_SPDIO_TXBD_WPTR); +} + +/** + * @brief Set TXBD read pointer, updated by CM4 driver. + * @param None + * @retval TXBD read pointer + */ +void SDIO_TXBD_RPTR_Set(SDIO_TypeDef *SDIO, u32 Val) +{ + UNUSED(SDIO); + + HAL_WRITE32(SDIO_REG_BASE, REG_SPDIO_TXBD_RPTR, Val); +} + +/** + * @brief Get TXBD read pointer. + * @param None + * @retval TXBD read pointer + */ +u32 SDIO_TXBD_RPTR_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ32(SDIO_REG_BASE, REG_SPDIO_TXBD_RPTR); +} + +/** + * @brief Reset SDIO DMA. + * @param None + * @retval TXBD read pointer + */ +void SDIO_DMA_Reset(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_CPU_RST_DMA, BIT_CPU_RST_SDIO_DMA); +} + +/** + * @brief Get AHB DMA control. + * @param None. + * @retval H2C message val. + */ +u32 SDIO_DMA_CTRL_Get(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + return HAL_READ32(SDIO_REG_BASE, REG_SPDIO_AHB_DMA_CTRL); +} + +/** + * @brief Set SDIO ready bit. + * @param ready: Set if SDIO is ready. It can be ENABLE/DISABLE. + * @retval None + */ +void SDIO_SetReady(SDIO_TypeDef *SDIO, int ready) +{ + UNUSED(SDIO); + + u8 reg; + + reg = HAL_READ8(SDIO_REG_BASE, REG_SPDIO_CPU_IND); + + if (ready == ENABLE) { + reg |= BIT_SYSTEM_TRX_RDY_IND; + } else { + reg &= ~BIT_SYSTEM_TRX_RDY_IND; + } + + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_CPU_IND, reg); +} + +/** + * @brief SDIO set Rx request. + * @param None + * @retval None + */ +void SDIO_RxReq(SDIO_TypeDef *SDIO) +{ + UNUSED(SDIO); + + HAL_WRITE8(SDIO_REG_BASE, REG_SPDIO_HCI_RX_REQ, BIT_HCI_RX_REQ); +} diff --git a/ameba/amebadplus/source/fwlib/ram_common/ameba_ups.c b/ameba/amebadplus/source/fwlib/ram_common/ameba_ups.c new file mode 100644 index 00000000..98d5f28d --- /dev/null +++ b/ameba/amebadplus/source/fwlib/ram_common/ameba_ups.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +/** @addtogroup Ameba_Periph_Driver + * @{ + */ + +/** @defgroup UPS + * @brief UPS driver modules + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup UPS_Exported_Functions UPS Exported Functions + * @{ + */ + +/** + * @brief Initializes the parameters in the UPS_InitStruct with default values. + * @param UPS_InitStruct: pointer to a UPS_InitTypeDef structure that contains + * the configuration information for the UPS. + * @retval None + */ +void UPS_StructInit(UPS_InitTypeDef *UPS_InitStruct) +{ + UPS_InitStruct->UPS_ProducerType = UPS_SRC_GPIO; + UPS_InitStruct->UPS_ConsumerType = UPS_DST_TIM_EN | UPS_DST_PWM_TRIG; + UPS_InitStruct->UPS_TimerOfIn = ENABLE; + UPS_InitStruct->UPS_ReverseSig = DISABLE; + UPS_InitStruct->UPS_DebounceCnt = 0x0; +} + +/** + * @brief Initializes the UPS according to the specified parameters in UPS_InitStruct. + * @param UPS_InitStruct: pointer to a UPS_InitTypeDef structure that contains + * the configuration information for the UPS. + * @retval None + */ +void UPS_Init(UPS_InitTypeDef *UPS_InitStruct) +{ + UPS_SrcConfig(UPS_InitStruct->UPS_ProducerType); + UPS_DstConfig(UPS_InitStruct->UPS_ConsumerType); + UPS_TimOfInCmd(UPS_InitStruct->UPS_TimerOfIn); + UPS_ReverseCmd(UPS_InitStruct->UPS_ReverseSig); + UPS_SetDbcCnt(UPS_InitStruct->UPS_DebounceCnt); +} + +/** + * @brief Specify the source signal type of UPS. + * @param SrcType: Specified signal source. + * This parameter can be a value of @ref UPS_Producer_Signal_Type_Definitions. + * @retval None + */ +void UPS_SrcConfig(u8 SrcType) +{ + assert_param(IS_UPS_PRODUCER_TYPE(SrcType)); + + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp &= ~LSYS_MASK_UPS_SRC_SEL; + Temp |= LSYS_UPS_SRC_SEL(SrcType); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); +} + +/** + * @brief Specify the destination signal type of UPS. + * @param DstType: Specified signal destination. + * This parameter can be a value or combinations of @ref UPS_Consumer_Signal_Type_Definitions. + * @retval None + */ +void UPS_DstConfig(u8 DstType) +{ + assert_param(IS_UPS_CONSUMER_TYPE(DstType)); + + if (DstType == UPS_DST_NONE) { + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp &= ~(LSYS_BIT_UPS_OUT_PWM_TRIG | LSYS_BIT_UPS_OUT_TIM_EN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); + return; + } + + if (DstType & UPS_DST_TIM_EN) { + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp |= LSYS_BIT_UPS_OUT_TIM_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); + } + + if (DstType & UPS_DST_PWM_TRIG) { + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp |= LSYS_BIT_UPS_OUT_PWM_TRIG; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); + } +} + +/** + * @brief Enable or disable basic timer overflow input. + * @param NewState: can be ENABLE or DISABLE. + * @retval None. + */ +void UPS_TimOfInCmd(u32 NewState) +{ + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + + if (NewState != DISABLE) { + Temp |= LSYS_BIT_UPS_IN_TIM_OF; + } else { + Temp &= ~LSYS_BIT_UPS_IN_TIM_OF; + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); +} + +/** + * @brief Enable or disable signal_reverse function in circuit. + * @param NewState: can be one of the following value: + * @arg ENABLE: Reverse source signal. + * @arg DISABLE: Do not reverse source signal. + * @retval None. + */ +void UPS_ReverseCmd(u32 NewState) +{ + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp &= ~LSYS_BIT_UPS_RVS_EN; + + if (NewState != DISABLE) { + Temp |= LSYS_BIT_UPS_RVS_EN; + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); +} + +/** + * @brief Set debounce counter under XTAL40M to realize signal deglitch. + * @param Dbc_Cnt: Debounce counter to be set. + * @note Dbc_Cnt = 0 means debounce function is disabled. + * @retval None + */ +void UPS_SetDbcCnt(u16 Dbc_Cnt) +{ + u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL); + Temp &= ~LSYS_MASK_UPS_DBC_CNT; + Temp |= LSYS_UPS_DBC_CNT(Dbc_Cnt); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LSYS_UPS_CTRL, Temp); +} diff --git a/ameba/amebadplus/source/swlib/log.c b/ameba/amebadplus/source/swlib/log.c index e69f3a1d..e729b66f 100644 --- a/ameba/amebadplus/source/swlib/log.c +++ b/ameba/amebadplus/source/swlib/log.c @@ -17,6 +17,713 @@ rtk_log_tag_t rtk_log_tag_array[LOG_TAG_CACHE_ARRAY_SIZE] = {0}; /* Count cache array usage */ static volatile uint32_t rtk_log_entry_count = 0; +#define get_num_va_args(_args, _lcount) \ + (((_lcount) > 1) ? va_arg(_args, long long int) : \ + (((_lcount) == 1) ? va_arg(_args, long int) : \ + va_arg(_args, int))) + +#define get_unum_va_args(_args, _lcount) \ + (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \ + (((_lcount) == 1) ? va_arg(_args, unsigned long int) : \ + va_arg(_args, unsigned int))) + +#define get_char_upper_lower(_upper, _rem) \ + (((_rem) < 0xa) ? ('0' + _rem) : \ + (((_upper) == 1) ? ('A' + (_rem - 0xa)) : \ + ('a' + (_rem - 0xa)))) + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +static int print_string(const char *str) +{ + int count = 0; + + //assert_param(str != NULL); + if (str == NULL) { + return -1; + } + for (; *str != '\0'; str++) { + DiagPutChar(*str); + count++; + } + return count; +} + +static int print_unsigned_num(unsigned long long int unum, unsigned int radix, + char padc, int padn, int upper, int sign) +{ + /* Just need enough space to store 64 bit decimal integer */ + char num_buf[20]; + int i = 0, count = 0; + unsigned int rem; + /* 1. convert num to str*/ + do { + rem = unum % radix; + num_buf[i] = get_char_upper_lower(upper, rem); + i++; + unum /= radix; + } while (unum > 0U); + /* 2. If there is a sign bit, subtract the padn by 1. */ + if (sign) { + count++; + padn--; + } + + /* 3. If fill 0, need to print the sign first, and then fill in 0 */ + if (sign && (padc == '0')) { + DiagPutChar('-'); + } + /* 4. Fill the character padc */ + if (padn > 0) { + while (i < padn) { + DiagPutChar(padc); + count++; + padn--; + } + } + /* 5.If fill a space, need to wait for step 4 to complete before filling the sign. */ + if (sign && (padc == ' ' || padc == '\0')) { + DiagPutChar('-'); + } + /* 6. Print the numbers*/ + while (--i >= 0) { + DiagPutChar(num_buf[i]); + count++; + } + + return count; +} + +static inline int pad_char_control(int padn, char padc) +{ + int count = 0; + while (padn > 0) { + DiagPutChar(padc); + padn--; + count++; + } + return count; +} + +static inline int pad_num_control(unsigned long long int unum, unsigned int radix, char padc, + int padn, int upper, int sign, int pad_on_right) +{ + int count = 0; + /* 1. if '-' left align was set, pad character in the right of num*/ + if (pad_on_right) { + int width = print_unsigned_num(unum, radix, padc, 0, upper, sign); + count += width; + //if padc is equal to '\space' and pad number is great than width of num, execute pad opration. Otherwise, no operation. + if ((padn > width) && (padc == ' ')) { + count += pad_char_control(padn - width, padc); + } + /* 2. Normally, pad operation is executed on the left of num.*/ + } else { + count += print_unsigned_num(unum, radix, padc, padn, upper, sign); + } + return count; +} +/******************************************************************* + * Reduced format print for Trusted firmware. + * The following type specifiers are supported by this print + * %lx - hexadecimal format + * %s - string format + * %lu or %i - signed decimal format + * %u - unsigned decimal format + * %p - pointer format + * + * The following length specifiers are supported by this print + * %l - long int (64-bit on AArch64) + * %ll - long long int (64-bit on AArch64) + * %z - size_t sized integer formats (64 bit on AArch64) + * + * The following padding specifiers are supported by this print + * %0NN - Left-pad the number with 0s (NN is a decimal number) + * %NN - Left-pad the number with spaces + * %-NN - Right-pad the number with spaces + * + * The print exits on all other formats specifiers other than valid + * combinations of the above specifiers. + *******************************************************************/ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +int DiagVprintf(const char *fmt, va_list args) +{ + int l_count; + long long int num; + unsigned long long int unum; + char *str; + + int count = 0; /* Number of printed characters */ + int upper = 0; + + // pad control + char padc = '\0'; /* Padding character */ + int padn; /* Number of characters to pad */ + int pad_on_right; + int sign = 0; + + char c = '\0'; + int percent_flag = 0; + char *tempstr = NULL; + int tempcount = 0; + + while (*fmt != '\0') { + l_count = 0; + percent_flag = pad_on_right = padn = sign = 0; + padc = '\0'; + + if (*fmt == '%') { + percent_flag = 1; + fmt++; + /* Check the format specifier */ +loop: + switch (*fmt) { + case 'i': /* Fall through to next one */ + case 'd': + num = get_num_va_args(args, l_count); + if (num < 0) { + sign = 1; + unum = (unsigned long long int) - num; + } else { + unum = (unsigned long long int)num; + } + count += pad_num_control(unum, 10, padc, padn, upper, sign, pad_on_right); + break; + case 'u': + unum = get_unum_va_args(args, l_count); + count += pad_num_control(unum, 10, padc, padn, upper, sign, pad_on_right); + break; + case 'B': + case 'b': + unum = get_unum_va_args(args, l_count); + count += pad_num_control(unum, 2, padc, padn, upper, sign, pad_on_right); + break; + case 'O': + case 'o': + unum = get_unum_va_args(args, l_count); + count += pad_num_control(unum, 8, padc, padn, upper, sign, pad_on_right); + break; + case 'X': + upper = 1; + case 'x': + unum = get_unum_va_args(args, l_count); + count += pad_num_control(unum, 16, padc, padn, upper, sign, pad_on_right); + break; + case 'p': + upper = 1; + unum = (uintptr_t)va_arg(args, void *); + if (sizeof(uintptr_t) == 4U) { + padc = '0'; + padn = 8; + } else { + padc = '0'; + padn = 16; + } + count += pad_num_control(unum, 16, padc, padn, upper, sign, pad_on_right); + break; + case 's': + str = va_arg(args, char *); + tempstr = str; + tempcount = 0; + while (*tempstr != '\0') { + tempstr++; + tempcount++; + } + // left pad + if (!pad_on_right && (padn - tempcount > 0)) { + count += pad_char_control(padn - tempcount, padc); + } + // print string + count += print_string(str); + // right pad + if (pad_on_right && (padn - tempcount > 0)) { + count += pad_char_control(padn - tempcount, padc); + } + break; + case 'c': + case 'C': + c = va_arg(args, int); + // left pad + if (!pad_on_right && (padn > 1)) { + count += pad_char_control(padn - 1, padc); + } + DiagPutChar(c); + count++; + //right pad + if (pad_on_right && (padn > 1)) { + count += pad_char_control(padn - 1, padc); + } + break; + case 'z': + if (sizeof(size_t) == 8U) { + goto not_support; + } + fmt++; + goto loop; + case 'L': + case 'l': + l_count++; + fmt++; + goto loop; + case '-': + fmt++; + pad_on_right++; + goto loop; + /*% is followed by a %. */ + case '%': + if (percent_flag) { + DiagPutChar('%'); + } + count++; + break; + case '0': + padc = '0'; + padn = 0; + fmt++; + goto pad_count; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + padc = ' '; + padn = 0; + goto pad_count; + /*% is followed by a spaces, so padc = \space. */ + case ' ': + padc = ' '; + padn = 0; + fmt++; +pad_count: + for (;;) { + char ch = *fmt; + if (ch == '\0') { // deal with case '% \0'. + goto exit; + } else if (!is_digit(ch)) { + goto loop; + } + padn = (padn * 10) + (ch - '0'); + fmt++; + } + case '\0': + break; + default: +not_support: + /* Exit on any other format specifier */ + return -1; + } + fmt++; + continue; + } + DiagPutChar(*fmt); + fmt++; + count++; + } +exit: + return count; +} + +static inline int print_decimal_num(unsigned int unum, int radix, char padc, int padn, int sign) +{ + /* Just need enough space to store 31 bit decimal integer */ + char num_buf[10]; + int i = 0, count = 0; + unsigned int rem; + /* 1. convert num to str*/ + do { + rem = unum % radix; + num_buf[i] = get_char_upper_lower(0, rem); + i++; + unum /= radix; + } while (unum > 0U); + + if (sign) { + count++; + padn--; + } + + if (sign && (padc == '0')) { + DiagPutChar('-'); + } + + /* 2. Fill the character padc */ + if (padn > 0) { + while (i < padn) { + DiagPutChar(padc); + count++; + padn--; + } + } + if (sign && (padc == ' ' || padc == '\0')) { + DiagPutChar('-'); + } + /* 3. Print the numbers*/ + while (--i >= 0) { + DiagPutChar(num_buf[i]); + count++; + } + + return count; +} + +/************************************************************************* + * Internal Nano format print to reduce stack size, num must within 32bits + * The following type specifiers are supported by this print + * %x - hexadecimal format + * %s - string format + * %c - char format + * %d or %i - signed decimal format + * + * The following padding specifiers are supported by this print + * %0NN - Left-pad the number with 0s (NN is a decimal number) + * %NN - Left-pad the number with space + * + * The print exits on all other formats specifiers other than valid + * combinations of the above specifiers. + **************************************************************************/ +int DiagVprintfNano(const char *fmt, va_list args) +{ + char *str; + + int count = 0; /* Number of printed characters */ + int sign = 0, num = 0; + // pad control + char padc = '\0'; /* Padding character */ + int padn; /* Number of characters to pad */ + int pad_on_right; + + char c = '\0'; + int percent_flag = 0; + char *tempstr = NULL; + int tempcount = 0; + + unsigned int unum; + while (*fmt != '\0') { + percent_flag = pad_on_right = padn = 0; + padc = '\0'; + sign = 0; + + if (*fmt == '%') { + percent_flag = 1; + fmt++; +loop: + /* Check the format specifier */ + switch (*fmt) { + case 'i': + case 'd': + num = get_num_va_args(args, 0); + if (num < 0) { + sign = 1; + unum = (unsigned int) - num; + } else { + unum = (unsigned int)num; + } + count += print_decimal_num(unum, 10, padc, padn, sign); + break; + case 'u': + unum = (unsigned int)get_unum_va_args(args, 0); + count += print_decimal_num(unum, 10, padc, padn, 0); + break; + case 'x': + unum = (unsigned int)get_unum_va_args(args, 0); + count += print_decimal_num(unum, 16, padc, padn, 0); + break; + case 's': + str = va_arg(args, char *); + tempstr = str; + tempcount = 0; + while (*tempstr != '\0') { + tempstr++; + tempcount++; + } + // left pad + if (!pad_on_right && (padn - tempcount > 0)) { + count += pad_char_control(padn - tempcount, padc); + } + // print string + count += print_string(str); + // right pad + if (pad_on_right && (padn - tempcount > 0)) { + count += pad_char_control(padn - tempcount, padc); + } + break; + case 'c': + case 'C': + c = va_arg(args, int); + // left pad + if (!pad_on_right && (padn > 1)) { + count += pad_char_control(padn - 1, padc); + } + DiagPutChar(c); + count++; + //right pad + if (pad_on_right && (padn > 1)) { + count += pad_char_control(padn - 1, padc); + } + break; + /*% is followed by a %. */ + case '%': + if (percent_flag) { + DiagPutChar('%'); + } + count++; + break; + case '0': + padc = '0'; + padn = 0; + fmt++; + goto pad_count; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + padc = ' '; + padn = 0; + goto pad_count; + /*% is followed by a spaces, so padc = \space. */ + case ' ': + padc = ' '; + padn = 0; + fmt++; +pad_count: + for (;;) { + char ch = *fmt; + if (ch == '\0') { // deal with case '% \0'. + return count; + } else if (!is_digit(ch)) { + goto loop; + } + padn = (padn * 10) + (ch - '0'); + fmt++; + } + + case '\0': + break; + default: + /* Exit on any other format specifier */ + return -1; + } + fmt++; + continue; + } + DiagPutChar(*fmt); + fmt++; + count++; + } + + return count; +} +#pragma GCC diagnostic pop + +u32 DiagPrintf(const char *fmt, ...) +{ + int ret; + va_list va; + + va_start(va, fmt); + ret = DiagVprintf(fmt, va); + va_end(va); + return ret; +} + +u32 DiagPrintfNano(const char *fmt, ...) +{ + int ret; + va_list va; + + va_start(va, fmt); + ret = DiagVprintfNano(fmt, va); + va_end(va); + return ret; +} + +/* support %s %d %x %c, %08x.*/ +int DiagSnPrintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list ap; + char *p, *s, *buf_end = NULL; + char padc = ' '; + int padn = 0; + + if (buf == NULL) { + return 0; + } + + va_start(ap, fmt); + s = buf; + buf_end = size ? (buf + size) : (char *)~0; + for (; *fmt != '\0'; ++fmt) { + padn = 0; + padc = ' '; + if (*fmt != '%') { + *s++ = *fmt; + + if (s >= buf_end) { + goto Exit; + } + + continue; + } + if (*++fmt == 's') { + p = va_arg(ap, char *); + while (*p != '\0') { + *s++ = *p++; + if (s >= buf_end) { + goto Exit; + } + } + } else { /* Length of item is bounded */ + + char tmp[20], *q = tmp; + int shift = 0;// = 12; + + int lpforchk = 0; + if ((*fmt == 'p') || (*fmt == 'P')) { + lpforchk = (uintptr_t)va_arg(ap, void *); + if (sizeof(uintptr_t) == 4U) { + padc = '0'; + padn = 8; + } else { + padc = '0'; + padn = 16; + } + } else { + lpforchk = va_arg(ap, int); + } + if ((lpforchk) < 0x10) { + shift = 0; + } else if (((lpforchk) >= 0x10) && ((lpforchk) < 0x100)) { + shift = 4; + } else if (((lpforchk) >= 0x100) && ((lpforchk) < 0x1000)) { + shift = 8; + } else if (((lpforchk) >= 0x1000) && ((lpforchk) < 0x10000)) { + shift = 12; + } else if (((lpforchk) >= 0x10000) && ((lpforchk) < 0x100000)) { + shift = 16; + } else if (((lpforchk) >= 0x100000) && ((lpforchk) < 0x1000000)) { + shift = 20; + } else if (((lpforchk) >= 0x1000000) && ((lpforchk) < 0x10000000)) { + shift = 24; + } else if ((lpforchk) >= 0x10000000) { + shift = 28; + } else { + shift = 28; + } + + if (*fmt == '0') { + fmt++; + padc = '0'; + } + + if ((*fmt > '0') && (*fmt <= '9')) { + int width; + unsigned char fch = *fmt; + for (width = 0; (fch >= '0') && (fch <= '9'); fch = *++fmt) { + width = width * 10 + fch - '0'; + } + padn = width; + } + /* + * Before each format q points to tmp buffer + * After each format q points past end of item + * Only %p and %x can be filled with digits 0 or spaces. + */ + if ((*fmt == 'x') || (*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) { + /* With x86 gcc, sizeof(long) == sizeof(int) */ + const int lp = lpforchk; + int h = lp; + int hex_count = 0; + unsigned int h_back = h; + int ncase = (*fmt & 0x20); + + if ((*fmt == 'p') || (*fmt == 'P')) { + *q++ = '0'; + *q++ = 'X' | ncase; + } + + while (h_back) { + hex_count += 1; + h_back = h_back >> 4; + } + while (padn-- > hex_count) { + *q++ = padc; + } + + for (; shift >= 0; shift -= 4) { + *q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase; + } + } else if (*fmt == 'd') { + int i = lpforchk; + char *r; + int digit_space = 0; + + if (i < 0) { + *q++ = '-'; + i = -i; + digit_space++; + } + + p = q; /* save beginning of digits */ + + do { + *q++ = '0' + (i % 10); + i /= 10; + digit_space++; + } while (i); + + + for (; shift >= 0; shift -= 4) { + + if (digit_space-- > 0) { + ; //do nothing + } else { + *q++ = '0'; + } + } + + /* reverse digits, stop in middle */ + r = q; /* don't alter q */ + + while (--r > p) { + i = *r; + *r = *p; + *p++ = i; + } + } else if (*fmt == 'c') { + *q++ = lpforchk; + } else { + *q++ = *fmt; + } + + /* now output the saved string */ + for (p = tmp; p < q; ++p) { + *s++ = *p; + + if (s >= buf_end) { + goto Exit; + } + } + } + } +Exit: + + if (buf) { + *s = '\0'; + } + va_end(ap); + return (s - buf); +} + /*** * @brief Print the modules' tag/level set by the rtk_log_level_set() * diff --git a/ameba/amebadplus/source/swlib/sscanf_minimal.c b/ameba/amebadplus/source/swlib/sscanf_minimal.c new file mode 100644 index 00000000..02cb7cd6 --- /dev/null +++ b/ameba/amebadplus/source/swlib/sscanf_minimal.c @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +#include +#include + +#define USHRT_MAX_INTERNAL ((u16)(~0U)) +#define BUF_MAX ((s16)(USHRT_MAX_INTERNAL>>1)) +#define STR_STORE_MAX_LEN 24 +#define KSTRTOX_OVERFLOW (1U << 31) + +#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',') + + +/** + * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder + * + * This is commonly provided by 32bit archs to provide an optimized 64bit + * divide. + */ +static u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +{ + *remainder = (u32)dividend % divisor; + return (u32)dividend / divisor; +} + +/** + * div_s64_rem - signed 64bit divide with 32bit divisor with remainder + */ +static s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) +{ + *remainder = (s32)dividend % divisor; + return (s32)dividend / divisor; +} + +/** + * div_u64 - unsigned 64bit divide with 32bit divisor + * + * This is the most common 64bit divide and should be used if possible, + * as many 32bit archs can optimize this variant better than a full 64bit + * divide. + */ + +static u64 div_u64(u64 dividend, u32 divisor) +{ + u32 remainder; + return div_u64_rem(dividend, divisor, &remainder); +} + +/** + * div_s64 - signed 64bit divide with 32bit divisor + */ + +static s64 div_s64(s64 dividend, s32 divisor) +{ + s32 remainder; + return div_s64_rem(dividend, divisor, &remainder); +} + + +static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) +{ + if (*base == 0) { + if (s[0] == '0') { + if (_tolower(s[1]) == 'x' && isxdigit(s[2])) { + *base = 16; + } else { + *base = 8; + } + } else { + *base = 10; + } + } + if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') { + s += 2; + } + return s; +} + +static char *skip_spaces(const char *str) +{ + while (isspace(*str)) { + ++str; + } + + return (char *)str; +} +static int skip_atoi(const char **s) +{ + int i = 0; + + while (isdigit(**s)) { + i = i * 10 + *((*s)++) - '0'; + } + + return i; +} + +static int judge_digit_width(const char *str, unsigned int base) +{ + + int width = 0; + + if ((base == 16 || base == 0) && str[0] == '0' && _tolower(str[1]) == 'x') { + str += 2; + width += 2; + + while (isxdigit(*str)) { + width++; + str++; + } + } else if (base == 16) { + while (isxdigit(*str)) { + width++; + str++; + } + } else if (base == 8 || (base == 0 && str[0] == '0')) { + while (isdigit(*str) && (*str) < '8') { + width++; + str++; + } + } else { + while (isdigit(*str)) { + width++; + str++; + } + } + + return width; +} + +//_OPTIMIZE_NONE_ +int _vsscanf_minimal(const char *buf, const char *fmt, va_list args) +{ + const char *str = buf; + char *next; + char digit; + int num = 0; + int i = 0; + u8 qualifier; + unsigned int base; + union { + long long s; + unsigned long long u; + } val; + s16 field_width; + bool is_sign; + + char str_store[STR_STORE_MAX_LEN] = {0}; + + while (*fmt) { + /* skip any white space in format */ + /* white space in format matchs any amount of + * white space, including none, in the input. + */ + if (isspace(*fmt)) { + fmt = skip_spaces(++fmt); + str = skip_spaces(str); + } + + /* anything that is not a conversion must match exactly */ + if (*fmt != '%' && *fmt) { + if (*fmt++ != *str++) { + break; + } + + continue; + } + + if (!*fmt) { + break; + } + + ++fmt; + + /* skip this conversion. + * advance both strings to next white space + */ + if (*fmt == '*') { + if (!*str) { + break; + } + + while (!isspace(*fmt) && *fmt != '%' && *fmt) { + fmt++; + } + while (!isspace(*str) && *str) { + str++; + } + + continue; + } + + /* get field width */ + field_width = -1; + + if (isdigit(*fmt)) { + + field_width = skip_atoi(&fmt); + + if (field_width <= 0) { + break; + } + } + + /* get conversion qualifier */ + qualifier = -1; + + if (*fmt == 'h' || _tolower(*fmt) == 'l' || _tolower(*fmt) == 'z') { + qualifier = *fmt++; + + if (qualifier == *fmt) { + if (qualifier == 'h') { + qualifier = 'H'; + fmt++; + } else if (qualifier == 'l') { + qualifier = 'L'; + fmt++; + } + } + } + + if (!*fmt) { + break; + } + + if (*fmt == 'n') { + /* return number of characters read so far */ + *va_arg(args, int *) = str - buf; + ++fmt; + continue; + } + + if (!*str) { + break; + } + + base = 10; + is_sign = 0; + + switch (*fmt++) { + case 'c': { + char *s = (char *)va_arg(args, char *); + + if (field_width == -1) { + field_width = 1; + } + + do { + *s++ = *str++; + } while (--field_width > 0 && *str); + + num++; + } + + continue; + + case 's': { + char *s = (char *)va_arg(args, char *); + if (field_width == -1) { + field_width = SHRT_MAX; + } + /* first, skip leading white space in buffer */ + str = skip_spaces(str); + + /* now copy until next white space */ + while (*str && !isspace(*str) && field_width--) { + *s++ = *str++; + } + + *s = '\0'; + num++; + } + continue; + + case 'o': + base = 8; + break; + + case 'x': + case 'X': + base = 16; + break; + + case 'i': + base = 0; + is_sign = 1; + break; + + case 'd': + is_sign = 1; + break; + + case 'u': + break; + + case '%': + /* looking for '%' in str */ + if (*str++ != '%') { + return num; + } + continue; + + default: + /* invalid format; stop here */ + return num; + } + + /* have some sort of integer conversion. + * first, skip white space in buffer. + */ + str = skip_spaces(str); + + digit = *str; + + if (is_sign && digit == '-') { + if (field_width == -1) { + field_width = judge_digit_width(str + 1, base); + field_width++; + } else { + field_width = (judge_digit_width(str + 1, base) + 1) < field_width ? + (judge_digit_width(str + 1, base) + 1) : + field_width; + } + digit = *(str + 1); + } else if (field_width == -1) { + field_width = judge_digit_width(str, base); + } else { + field_width = judge_digit_width(str, base) < field_width ? + judge_digit_width(str, base) : + field_width; + } + + if (!digit + || (base == 16 && !isxdigit(digit)) + || (base == 10 && !isdigit(digit)) + || (base == 8 && (!isdigit(digit) || digit > '7')) + || (base == 0 && !isdigit(digit))) { + break; + } + + //assert_param (field_width <= STR_STORE_MAX_LEN); + for (i = 0; i < field_width ; i++) { + str_store[i] = str[i]; + } + + if (is_sign) { + val.s = qualifier != 'L' ? + strtol(str_store, &next, base) : + strtoll(str_store, &next, base); + } else { + val.u = qualifier != 'L' ? + _strtoul(str_store, &next, base) : + strtoull(str_store, &next, base); + } + + /* standard strtoul need this */ + next = (char *)str + field_width; + + for (i = 0; i < STR_STORE_MAX_LEN ; i++) { + str_store[i] = 0; + } + + + //判断转换的字符串的宽度是否大于 %2d + if (field_width > 0 && next - str > field_width) { + if (base == 0) { + _parse_integer_fixup_radix(str, &base); + } + + while (next - str > field_width) { + if (is_sign) { + val.s = div_s64(val.s, base); + } else { + val.u = div_u64(val.u, base); + } + + --next; + } + } + + switch (qualifier) { + case 'H': /* that's 'hh' in format */ + if (is_sign) { + *va_arg(args, signed char *) = val.s; + } else { + *va_arg(args, unsigned char *) = val.u; + } + break; + + case 'h': + if (is_sign) { + memcpy(va_arg(args, short *), &(val.s), sizeof(short)); + } else { + memcpy(va_arg(args, unsigned short *), &(val.u), sizeof(unsigned short)); + } + break; + + case 'l': + if (is_sign) { + memcpy(va_arg(args, long *), &(val.s), sizeof(long)); + } else { + memcpy(va_arg(args, unsigned long *), &(val.u), sizeof(unsigned long)); + } + break; + + case 'L': + if (is_sign) { + memcpy(va_arg(args, long long *), &(val.s), sizeof(long long)); + } else { + memcpy(va_arg(args, unsigned long long *), &(val.u), sizeof(unsigned long long)); + } + break; + + case 'Z': + case 'z': + memcpy(va_arg(args, size_t *), &(val.u), sizeof(size_t)); + break; + + default: + if (is_sign) { + memcpy(va_arg(args, int *), &(val.s), sizeof(int)); + } else { + memcpy(va_arg(args, unsigned int *), &(val.u), sizeof(unsigned int)); + } + break; + } + + num++; + + if (!next) { + break; + } + + str = next; + } + + return num; +} + +/** +* sscanf - Unformat a buffer into a list of arguments +* @buf: input buffer +* @fmt: formatting of buffer +* @...: resulting arguments +*/ +/* support %* %x %c %s %o %x %i %d %u %h %z and %l(within len 24) */ +/* for internal use, not support [] and ^ */ +int _sscanf_ss(const char *buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = _vsscanf_minimal(buf, fmt, args); + va_end(args); + + return i; +} diff --git a/ameba/amebadplus/source/swlib/sscanf_minimal.h b/ameba/amebadplus/source/swlib/sscanf_minimal.h new file mode 100644 index 00000000..434ca782 --- /dev/null +++ b/ameba/amebadplus/source/swlib/sscanf_minimal.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SSCANF_MINIMAL_H_ +#define _SSCANF_MINIMAL_H_ + +extern int _sscanf_ss(const char *buf, const char *fmt, ...); + +#endif diff --git a/ameba/amebaG2/CMakeLists.txt b/ameba/amebag2/CMakeLists.txt similarity index 66% rename from ameba/amebaG2/CMakeLists.txt rename to ameba/amebag2/CMakeLists.txt index f8a69c25..302d245a 100644 --- a/ameba/amebaG2/CMakeLists.txt +++ b/ameba/amebag2/CMakeLists.txt @@ -1,8 +1,20 @@ -# +# Copyright (c) 2024 Realtek Semiconductor Corp. # SPDX-License-Identifier: Apache-2.0 zephyr_compile_options(-mcmse) +set(LIB_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/blobs/ameba/${CONFIG_SOC_SERIES}/lib) + +set(WIFI_LIB_PATH ${LIB_PATH}) +zephyr_link_libraries_ifdef(CONFIG_WIFI_AMEBA + ${WIFI_LIB_PATH}/lib_wifi_whc_ap.a + ${WIFI_LIB_PATH}/lib_rtw_event.a + ${WIFI_LIB_PATH}/lib_wifi_api.a + ${WIFI_LIB_PATH}/lib_wpa_lite.a + ${WIFI_LIB_PATH}/lib_wifi_common.a + ${WIFI_LIB_PATH}/lib_coex_api.a + ${WIFI_LIB_PATH}/lib_wifi_rtk_app.a +) zephyr_include_directories( include source/fwlib/include @@ -17,6 +29,9 @@ zephyr_library_sources( source/fwlib/ram_common/ameba_clk.c source/fwlib/ram_common/ameba_rcc.c source/fwlib/ram_common/ameba_rtc.c + source/fwlib/ram_common/ameba_arch.c + source/fwlib/ram_common/ameba_ipc_api.c + source/fwlib/ram_common/ameba_ipc_ram.c ) # used by driver, need use zephyr_library_sources_ifdef @@ -40,40 +55,15 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_TMR_AMEBA source/fwlib/ram_common/am zephyr_library_sources_ifdef(CONFIG_COUNTER_TMR_AMEBA source/fwlib/ram_common/ameba_ups.c) zephyr_library_sources_ifdef(CONFIG_UART_AMEBA source/fwlib/ram_common/ameba_uart.c) zephyr_library_sources_ifdef(CONFIG_TEMP_AMEBA source/fwlib/ram_common/ameba_thermal.c) -zephyr_library_sources_ifdef(CONFIG_REALTEK_AMEBA_ZEPHYR_USB source/fwlib/ram_common/ameba_usb.c) zephyr_library_sources_ifdef(CONFIG_WIFI_AMEBA source/fwlib/ram_common/ameba_pmu.c) zephyr_library_sources_ifdef(CONFIG_WIFI_AMEBA source/fwlib/ram_common/ameba_pmctimer.c) zephyr_library_sources_ifdef(CONFIG_AMEBA_PPE source/fwlib/ram_common/ameba_ppe.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_AMEBA source/fwlib/ram_common/ameba_sd.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_AMEBA source/fwlib/ram_common/ameba_sd_host.c) zephyr_link_libraries( - -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_bcut_s.ld + -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_bcut.ld -T${CMAKE_CURRENT_SOURCE_DIR}/ld/ameba_rom_symbol_bcut_wifi.ld ) -# west sign -if(CONFIG_SOC_AMEBA_NP_IMAGE) - file(GLOB blob_bin_file "${ZEPHYR_HAL_REALTEK_MODULE_DIR}/zephyr/blobs/${CONFIG_SOC_SERIES}/bin/*.bin") - - if(blob_bin_file) - set(python_script_args - --soc ${CONFIG_SOC_SERIES} - --bin-file ${ZEPHYR_BINARY_DIR}/${KERNEL_BIN_NAME} - --out-dir ${CMAKE_BINARY_DIR} - --module-dir ${ZEPHYR_HAL_REALTEK_MODULE_DIR} - ) - - add_custom_target(zephyr.raw.map ALL - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - ) - - add_custom_command( - OUTPUT ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_NM} ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} | sort > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_OBJDUMP} -d ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.asm - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/scripts/merge_bin.py ${python_script_args} - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${blob_bin_file} ${CMAKE_CURRENT_SOURCE_DIR}/manifest.json5 - ) - else() - message(WARNING "Missing Realtek blobs. Run: `west blobs fetch hal_realtek`") - endif() -endif() +add_subdirectory_ifdef(CONFIG_AMEBA_MJPEG source/fwlib/jpeg_decoder) diff --git a/ameba/amebaG2/Kconfig b/ameba/amebag2/Kconfig similarity index 100% rename from ameba/amebaG2/Kconfig rename to ameba/amebag2/Kconfig diff --git a/ameba/amebaG2/ameba_layout.ld b/ameba/amebag2/ameba_layout.ld similarity index 100% rename from ameba/amebaG2/ameba_layout.ld rename to ameba/amebag2/ameba_layout.ld diff --git a/ameba/amebaG2/include/platform_autoconf.h b/ameba/amebag2/include/platform_autoconf.h similarity index 83% rename from ameba/amebaG2/include/platform_autoconf.h rename to ameba/amebag2/include/platform_autoconf.h index e7d32c98..2ce39ea9 100644 --- a/ameba/amebaG2/include/platform_autoconf.h +++ b/ameba/amebag2/include/platform_autoconf.h @@ -20,8 +20,6 @@ #define CONFIG_SUPPORT_ATCMD 1 #define CONFIG_ATCMD_MANUAL_TEST 1 #define CONFIG_ATCMD_NETWORK 1 -#define CONFIG_ASSERTION_ENABLE 1 -#define CONFIG_VFS_LITTLEFS_INCLUDED 1 #define CONFIG_BACK_TRACE_DEPTH_LIMIT 8 #define CONFIG_WHC_WIFI_API_PATH 1 #define CONFIG_KM4TZ_AS_AP 1 @@ -29,11 +27,7 @@ #define CONFIG_WLAN 1 #define CONFIG_WHC_INTF_IPC 1 #define CONFIG_LWIP_LAYER 1 - #define CONFIG_USE_MBEDTLS_ROM_ALG 1 -#define CONFIG_MBEDTLS_ENABLED 1 -#define CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN 16384 -#define CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN 4096 //#define CONFIG_BT_COEXIST 1 #define CONFIG_COEXIST_HOST 1 #define CONFIG_LINK_ROM_SYMB 1 diff --git a/ameba/amebaG2/ld/ameba_rom_symbol_bcut.ld b/ameba/amebag2/ld/ameba_rom_symbol_bcut.ld similarity index 100% rename from ameba/amebaG2/ld/ameba_rom_symbol_bcut.ld rename to ameba/amebag2/ld/ameba_rom_symbol_bcut.ld diff --git a/ameba/amebaG2/ld/ameba_rom_symbol_bcut_s.ld b/ameba/amebag2/ld/ameba_rom_symbol_bcut_s.ld similarity index 100% rename from ameba/amebaG2/ld/ameba_rom_symbol_bcut_s.ld rename to ameba/amebag2/ld/ameba_rom_symbol_bcut_s.ld diff --git a/ameba/amebaG2/ld/ameba_rom_symbol_bcut_wifi.ld b/ameba/amebag2/ld/ameba_rom_symbol_bcut_wifi.ld similarity index 100% rename from ameba/amebaG2/ld/ameba_rom_symbol_bcut_wifi.ld rename to ameba/amebag2/ld/ameba_rom_symbol_bcut_wifi.ld diff --git a/ameba/amebaG2/manifest.json5 b/ameba/amebag2/manifest.json5 similarity index 100% rename from ameba/amebaG2/manifest.json5 rename to ameba/amebag2/manifest.json5 diff --git a/ameba/amebaG2/source/fwlib/include/ameba.h b/ameba/amebag2/source/fwlib/include/ameba.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba.h rename to ameba/amebag2/source/fwlib/include/ameba.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_a2c.h b/ameba/amebag2/source/fwlib/include/ameba_a2c.h similarity index 97% rename from ameba/amebaG2/source/fwlib/include/ameba_a2c.h rename to ameba/amebag2/source/fwlib/include/ameba_a2c.h index ecc508ae..4f9c1a3f 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_a2c.h +++ b/ameba/amebag2/source/fwlib/include/ameba_a2c.h @@ -567,23 +567,12 @@ typedef struct { u32 DLC; /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value between 0 to 8 */ - - u32 ESI; /*!< Specifies the FD frame esi bit, indicate error passive of message sending node, - read bit, should always write 0, hardware automatic fill*/ - - u32 BRS; /*!< Specifies the FD frame brs bit, indicate switch bit timing*/ - - u32 EDL; /*!< Specifies the FD frame edl bit, indicate it's a FD frame*/ - - __attribute__((aligned(4))) - u8 Data[64]; /*!< Contains the data to be transmitted. It ranges from 0 - to 0xFF. */ - - u32 IDE_MASK; /*!< Specifies the IDE MASK, ####*/ - - u32 ID_MASK; /*!< Specifies the ID MASK, ####*/ - - u32 RTR_Mask; /*!< Specifies the RTR MASK, ####*/ + union { + /** Payload data accessed as unsigned 8 bit values. */ + uint8_t Data[64]; + /** Payload data accessed as unsigned 32 bit values. */ + uint32_t Data_32[16]; + }; } A2C_TxMsgTypeDef; /** @@ -618,16 +607,12 @@ typedef struct { u32 DLC; /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value between 0 to 8*/ - u32 ESI; /*!< Specifies the FD frame esi bit, indicate error passive of message sending node, - read bit, should always write 0, hardware automatic fill*/ - - u32 BRS; /*!< Specifies the FD frame brs bit, indicate switch bit timing*/ - - u32 EDL; /*!< Specifies the FD frame edl bit, indicate it's a FD frame*/ - - __attribute__((aligned(4))) - u8 Data[64]; /*!< Contains the data to be transmitted. It ranges from 0 - to 0xFF. */ + union { + /** Payload data accessed as unsigned 8 bit values. */ + uint8_t Data[64]; + /** Payload data accessed as unsigned 32 bit values. */ + uint32_t Data_32[16]; + }; u32 ID_MASK; /*!< Specifies the ID MASK*/ @@ -652,10 +637,10 @@ typedef struct { /** @defgroup A2C_WORK_MODE_define * @{ */ -#define A2C_NORMAL_MODE ((u32)0x00000000) -#define A2C_SILENCE_MODE ((u32)0x00000001) -#define A2C_EXT_LOOPBACK_MODE ((u32)0x00000002) -#define A2C_INT_LOOPBACK_MODE ((u32)0x00000003) +#define A2C_NORMAL_MODE ((u32)0x00000000) +#define A2C_SILENCE_MODE ((u32)0x00000000) +#define A2C_EXT_LOOPBACK_MODE ((u32)0x00000001) +#define A2C_INT_LOOPBACK_MODE ((u32)0x00000002) #define IS_A2C_WORK_MODE(MODE) (((MODE) == A2C_NORMAL_MODE) || \ ((MODE) == A2C_SILENCE_MODE) || \ ((MODE) == A2C_EXT_LOOPBACK_MODE) || \ @@ -964,4 +949,4 @@ struct A2C_DevTable { extern const struct A2C_DevTable A2C_DEV_TABLE[MAX_A2C_INDEX]; -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_adc.h b/ameba/amebag2/source/fwlib/include/ameba_adc.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_adc.h rename to ameba/amebag2/source/fwlib/include/ameba_adc.h index c92d16f1..372be27a 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_adc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_adc.h @@ -900,4 +900,4 @@ _LONG_CALL_ u32 ADC_GetSampleValue(s32 VolMV); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_aes.h b/ameba/amebag2/source/fwlib/include/ameba_aes.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_aes.h rename to ameba/amebag2/source/fwlib/include/ameba_aes.h index 44501a2b..6e2343bc 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_aes.h +++ b/ameba/amebag2/source/fwlib/include/ameba_aes.h @@ -868,4 +868,4 @@ _LONG_CALL_ int crypto_gcm_auth_decrypt(u8 key_id, u32 key_len_bits, u32 len, u8 /** @} */ /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_aontimer.h b/ameba/amebag2/source/fwlib/include/ameba_aontimer.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_aontimer.h rename to ameba/amebag2/source/fwlib/include/ameba_aontimer.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_arch.h b/ameba/amebag2/source/fwlib/include/ameba_arch.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_arch.h rename to ameba/amebag2/source/fwlib/include/ameba_arch.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_audio.h b/ameba/amebag2/source/fwlib/include/ameba_audio.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_audio.h rename to ameba/amebag2/source/fwlib/include/ameba_audio.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_audio_clock.h b/ameba/amebag2/source/fwlib/include/ameba_audio_clock.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_audio_clock.h rename to ameba/amebag2/source/fwlib/include/ameba_audio_clock.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_backup_reg.h b/ameba/amebag2/source/fwlib/include/ameba_backup_reg.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_backup_reg.h rename to ameba/amebag2/source/fwlib/include/ameba_backup_reg.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_boot.h b/ameba/amebag2/source/fwlib/include/ameba_boot.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_boot.h rename to ameba/amebag2/source/fwlib/include/ameba_boot.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_bor.h b/ameba/amebag2/source/fwlib/include/ameba_bor.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_bor.h rename to ameba/amebag2/source/fwlib/include/ameba_bor.h index a08ebf87..19dfa415 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_bor.h +++ b/ameba/amebag2/source/fwlib/include/ameba_bor.h @@ -100,4 +100,4 @@ void BOR_DbncSet(u32 Option, u32 Dbnc_Value); void BOR_ClearINT(void); void BOR_ModeSet(u32 Option); -#endif //_AMEBA_BOR_H_ \ No newline at end of file +#endif //_AMEBA_BOR_H_ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_cache.h b/ameba/amebag2/source/fwlib/include/ameba_cache.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_cache.h rename to ameba/amebag2/source/fwlib/include/ameba_cache.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_captouch.h b/ameba/amebag2/source/fwlib/include/ameba_captouch.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_captouch.h rename to ameba/amebag2/source/fwlib/include/ameba_captouch.h index bddc2b30..6989d9fd 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_captouch.h +++ b/ameba/amebag2/source/fwlib/include/ameba_captouch.h @@ -821,4 +821,4 @@ u8 CapTouch_RXGDMA_Init(CAPTOUCH_TypeDef *CapTouch, GDMA_InitTypeDef *GDMA_InitS /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_chipinfo.h b/ameba/amebag2/source/fwlib/include/ameba_chipinfo.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_chipinfo.h rename to ameba/amebag2/source/fwlib/include/ameba_chipinfo.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_clk.h b/ameba/amebag2/source/fwlib/include/ameba_clk.h similarity index 96% rename from ameba/amebaG2/source/fwlib/include/ameba_clk.h rename to ameba/amebag2/source/fwlib/include/ameba_clk.h index b4e1e93d..a3121fc1 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_clk.h +++ b/ameba/amebag2/source/fwlib/include/ameba_clk.h @@ -7,6 +7,10 @@ #ifndef _AMEBA_CLK_H_ #define _AMEBA_CLK_H_ +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup AmebaD_Platform * @{ */ @@ -109,6 +113,17 @@ * @} */ +/** @defgroup SDM_USER_DEFINED_param_definitions + * @{ + */ +#define SDM_OBS_CYC_DEFAULT 1024 +#define SDM_OBS_REF_CYC_DEFAULT 312500 +#define SDM_OBS_REF_CYC_MODIFY 312503 +#define SDM_XTAL_PERIOD_DEFAULT 102400 +/** + * @} + */ + /** @defgroup XTAL_CLK_definitions * @{ */ @@ -179,6 +194,7 @@ */ _LONG_CALL_ void SDM32K_Enable(void); _LONG_CALL_ void SDM32K_TimerCalEnable(u32 RTCCalibration); +_LONG_CALL_ void SDM32K_CalFactorModify(u32 newstatus); /** * @} */ @@ -336,4 +352,8 @@ u32 OSC_CalResult_Get(u8 cal_clk); void XTAL_INIT(void); void XTAL_AACK(void); +#ifdef __cplusplus +} +#endif + #endif //_AMEBA_CLK_H_ \ No newline at end of file diff --git a/ameba/amebaG2/source/fwlib/include/ameba_crypto.h b/ameba/amebag2/source/fwlib/include/ameba_crypto.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_crypto.h rename to ameba/amebag2/source/fwlib/include/ameba_crypto.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_data_flash.h b/ameba/amebag2/source/fwlib/include/ameba_data_flash.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_data_flash.h rename to ameba/amebag2/source/fwlib/include/ameba_data_flash.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_data_nand_flash.h b/ameba/amebag2/source/fwlib/include/ameba_data_nand_flash.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_data_nand_flash.h rename to ameba/amebag2/source/fwlib/include/ameba_data_nand_flash.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_debug_port.h b/ameba/amebag2/source/fwlib/include/ameba_debug_port.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_debug_port.h rename to ameba/amebag2/source/fwlib/include/ameba_debug_port.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_debugtimer.h b/ameba/amebag2/source/fwlib/include/ameba_debugtimer.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_debugtimer.h rename to ameba/amebag2/source/fwlib/include/ameba_debugtimer.h index 993f0583..2605087a 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_debugtimer.h +++ b/ameba/amebag2/source/fwlib/include/ameba_debugtimer.h @@ -288,4 +288,4 @@ __STATIC_INLINE void DTimer_ScratchSet(u32 NewVaule) /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_delay.h b/ameba/amebag2/source/fwlib/include/ameba_delay.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_delay.h rename to ameba/amebag2/source/fwlib/include/ameba_delay.h index 064ee7e3..c8eeb455 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_delay.h +++ b/ameba/amebag2/source/fwlib/include/ameba_delay.h @@ -58,4 +58,4 @@ _LONG_CALL_ void DelayNop(u32 count); extern u32 RBSS_UDELAY_CLK; extern u8 RBSS_UDELAY_DIV; -#endif//_AMEBA_DELAY_H_ \ No newline at end of file +#endif//_AMEBA_DELAY_H_ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ethernet.h b/ameba/amebag2/source/fwlib/include/ameba_ethernet.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_ethernet.h rename to ameba/amebag2/source/fwlib/include/ameba_ethernet.h index bbf0c247..d9a076f8 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ethernet.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ethernet.h @@ -2243,10 +2243,18 @@ typedef struct { /* MANUAL_GEN_START */ // Please add your definitions here -/// Defines the packet buffer size -#define ETH_PKT_BUFF_SZ 1600 //1514? -/// Defines the MAC address length -#define ETH_MAC_ADDR_LEN 6 +/* Define Ethernet Packet Field length */ +#define ETH_MAC_ADDR_LEN (6) +#define ETH_HEADER_LEN (2 * ETH_MAC_ADDR_LEN + 2) /* Ethernet frame header size: Dest addr(6 Bytes) + Src addr(6 Bytes) + length/type(2 Bytes) */ +#define ETH_VLAN_TAG_LEN (4) /* Optional 802.1q VLAN Tag length */ +#define ETH_CRC_LEN (4) /* Ethernet frame CRC length */ + +#define ETH_PAYLOAD_MAX_LEN (1500) /*< Ethernet maximum payload size (bytes) */ +#define ETH_PAYLOAD_MIN_LEN (46) /* Minimum Ethernet payload size */ +#define ETH_JUMBO_FRAME_PAYLOAD_LEN (16*1024) /* Jumbo frame payload size */ + +#define ETH_PKT_MAX_SIZE (ETH_HEADER_LEN + ETH_VLAN_TAG_LEN + ETH_PAYLOAD_MAX_LEN + ETH_CRC_LEN) /* Maximum frame size (1522 Bytes) */ + /// Defines the delay period when checking the own bit of the Tx/Rx descriptors #define ETH_OWN_BIT_UPDATE_PERIOD 10 /// Defines the max. timeout value when checking the flag of MDIO operations @@ -2369,24 +2377,28 @@ typedef struct { \brief Defines FEMAC Tx command descriptor */ #define FEMAC_TX_DSC_SHIFT_OWN 31 -#define FEMAC_TX_DSC_BIT_OWN ((u32)0x00000001 << 31) +#define FEMAC_TX_DSC_BIT_OWN ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_OWN) #define FEMAC_TX_DSC_SHIFT_EOR 30 -#define FEMAC_TX_DSC_BIT_EOR ((u32)0x00000001 << 30) +#define FEMAC_TX_DSC_BIT_EOR ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_EOR) #define FEMAC_TX_DSC_SHIFT_FS 29 -#define FEMAC_TX_DSC_BIT_FS ((u32)0x00000001 << 29) +#define FEMAC_TX_DSC_BIT_FS ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_FS) #define FEMAC_TX_DSC_SHIFT_LS 28 -#define FEMAC_TX_DSC_BIT_LS ((u32)0x00000001 << 28) +#define FEMAC_TX_DSC_BIT_LS ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_LS) +#define FEMAC_TX_DSC_SHIFT_IPCS 27 +#define FEMAC_TX_DSC_BIT_IPCS ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_IPCS) +#define FEMAC_TX_DSC_SHIFT_L4CS 26 +#define FEMAC_TX_DSC_BIT_L4CS ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_L4CS) #define FEMAC_TX_DSC_SHIFT_CRC 23 -#define FEMAC_TX_DSC_BIT_CRC ((u32)0x00000001 << 23) - +#define FEMAC_TX_DSC_BIT_CRC ((u32)0x00000001 << FEMAC_TX_DSC_SHIFT_CRC) +#define FEMAC_TX_DSC_BIT_SIZE(dw1) ((u32)((dw1) & 0x1FFFF)) /** \brief Defines FEMAC Rx command descriptor */ #define FEMAC_RX_DSC_SHIFT_OWN 31 -#define FEMAC_RX_DSC_BIT_OWN ((u32)0x00000001 << 31) +#define FEMAC_RX_DSC_BIT_OWN ((u32)0x00000001 << FEMAC_RX_DSC_SHIFT_OWN) #define FEMAC_RX_DSC_SHIFT_EOR 30 -#define FEMAC_RX_DSC_BIT_EOR ((u32)0x00000001 << 30) - +#define FEMAC_RX_DSC_BIT_EOR ((u32)0x00000001 << FEMAC_RX_DSC_SHIFT_EOR) +#define FEMAC_RX_DSC_LEN(dw1) ((u32)((dw1) & 0x0FFF)) /** \brief Defines FEPHY register page number */ @@ -2422,6 +2434,11 @@ typedef struct { * @} */ +/** + \brief Defines MDIO Wait Time(us) +*/ +#define MDIO_WAIT_TIME (64) + /** \brief Defines the FEPHY register address */ @@ -2747,8 +2764,8 @@ void Ethernet_SetDescAddr(ETH_InitTypeDef *ETH_InitStruct); void Ethernet_SetMacAddr(u8 *ETH_MacAddr); void Ethernet_StructInit(ETH_InitTypeDef *ETH_InitStruct); u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct); -u16 Ethernet_Read_PhyReg(u16 page, u16 reg_addr); -u32 Ethernet_Write_PhyReg(u16 page, u16 reg_addr, u16 data); +int Ethernet_ReadPhyReg(uint8_t phy_id, uint8_t reg_addr, uint16_t *data); +int Ethernet_WritePhyReg(uint8_t phy_id, uint8_t reg_addr, uint16_t data); u32 Ethernet_GetLinkStatus(void); void Ethernet_SetRefclkDirec(u32 refclk_mode); void Ethernet_OutputClk2Phy(u32 pin); @@ -2772,4 +2789,4 @@ extern int link_is_up; /** @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_flashclk.h b/ameba/amebag2/source/fwlib/include/ameba_flashclk.h similarity index 95% rename from ameba/amebaG2/source/fwlib/include/ameba_flashclk.h rename to ameba/amebag2/source/fwlib/include/ameba_flashclk.h index 752cce1c..0831d0d5 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_flashclk.h +++ b/ameba/amebag2/source/fwlib/include/ameba_flashclk.h @@ -30,4 +30,4 @@ typedef struct { void flash_highspeed_setup(void); void Combo_SPIC_Init(void); -#endif //_AMEBA_FLASH_CLK_H \ No newline at end of file +#endif //_AMEBA_FLASH_CLK_H diff --git a/ameba/amebaG2/source/fwlib/include/ameba_gdma.h b/ameba/amebag2/source/fwlib/include/ameba_gdma.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_gdma.h rename to ameba/amebag2/source/fwlib/include/ameba_gdma.h index 812b75a9..0db4fbe6 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_gdma.h +++ b/ameba/amebag2/source/fwlib/include/ameba_gdma.h @@ -1309,6 +1309,7 @@ _LONG_CALL_ void GDMA_Resume(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ u8 GDMA_Abort(u8 GDMA_Index, u8 GDMA_ChNum); _LONG_CALL_ void GDMA_SourceGather(u8 GDMA_Index, u8 GDMA_ChNum, u32 Src_GatherCount, u32 Src_GatherInterval); _LONG_CALL_ void GDMA_DestinationScatter(u8 GDMA_Index, u8 GDMA_ChNum, u32 Dst_ScatterCount, u32 Dst_ScatterInterval); +_LONG_CALL_ u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum); /** * @} */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_gpio.h b/ameba/amebag2/source/fwlib/include/ameba_gpio.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_gpio.h rename to ameba/amebag2/source/fwlib/include/ameba_gpio.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_i2c.h b/ameba/amebag2/source/fwlib/include/ameba_i2c.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_i2c.h rename to ameba/amebag2/source/fwlib/include/ameba_i2c.h index 9e176bed..e52a9b35 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_i2c.h +++ b/ameba/amebag2/source/fwlib/include/ameba_i2c.h @@ -939,4 +939,4 @@ extern u32 IC_FS_SCL_LCNT_TRIM; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_inic.h b/ameba/amebag2/source/fwlib/include/ameba_inic.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_inic.h rename to ameba/amebag2/source/fwlib/include/ameba_inic.h index 19e4506b..3117708a 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_inic.h +++ b/ameba/amebag2/source/fwlib/include/ameba_inic.h @@ -154,4 +154,4 @@ typedef struct { * @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ipc.h b/ameba/amebag2/source/fwlib/include/ameba_ipc.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_ipc.h rename to ameba/amebag2/source/fwlib/include/ameba_ipc.h index 1fc08d22..ab19fae9 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ipc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ipc.h @@ -322,4 +322,4 @@ extern const IPC_INIT_TABLE ipc_init_config[]; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ipc_api.h b/ameba/amebag2/source/fwlib/include/ameba_ipc_api.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_ipc_api.h rename to ameba/amebag2/source/fwlib/include/ameba_ipc_api.h index 25b55ef4..14fa1a03 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ipc_api.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ipc_api.h @@ -64,4 +64,4 @@ u32 ipc_send_message(u32 IPC_Dir, u8 IPC_ChNum, PIPC_MSG_STRUCT IPC_Msg); PIPC_MSG_STRUCT ipc_get_message(u32 IPC_Dir, u8 IPC_ChNum); extern IPC_IRQ_FUN IPC_IrqHandler[32]; -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ipccfg.h b/ameba/amebag2/source/fwlib/include/ameba_ipccfg.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_ipccfg.h rename to ameba/amebag2/source/fwlib/include/ameba_ipccfg.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ir.h b/ameba/amebag2/source/fwlib/include/ameba_ir.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_ir.h rename to ameba/amebag2/source/fwlib/include/ameba_ir.h index 2cb291ff..cbd63c0b 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ir.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ir.h @@ -453,4 +453,4 @@ void IR_ClearRxFIFO(IR_TypeDef *IRx); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_key_management_aes.h b/ameba/amebag2/source/fwlib/include/ameba_key_management_aes.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_key_management_aes.h rename to ameba/amebag2/source/fwlib/include/ameba_key_management_aes.h index 812589e7..9d035d22 100755 --- a/ameba/amebaG2/source/fwlib/include/ameba_key_management_aes.h +++ b/ameba/amebag2/source/fwlib/include/ameba_key_management_aes.h @@ -175,4 +175,4 @@ typedef struct { ((ID) == KM_AES_KEY_NS_SW2)) /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_key_management_hmac.h b/ameba/amebag2/source/fwlib/include/ameba_key_management_hmac.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_key_management_hmac.h rename to ameba/amebag2/source/fwlib/include/ameba_key_management_hmac.h index 4655031b..ac1c34bd 100755 --- a/ameba/amebaG2/source/fwlib/include/ameba_key_management_hmac.h +++ b/ameba/amebag2/source/fwlib/include/ameba_key_management_hmac.h @@ -140,4 +140,4 @@ typedef struct { ((ID) == KM_HMAC_KEY_NS_SW)) /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_lcdc.h b/ameba/amebag2/source/fwlib/include/ameba_lcdc.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_lcdc.h rename to ameba/amebag2/source/fwlib/include/ameba_lcdc.h index 9586beaa..dd63ad11 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_lcdc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_lcdc.h @@ -1163,4 +1163,4 @@ extern u32 LCDC_SYS_CLK;// = 400000000; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ledc_pro.h b/ameba/amebag2/source/fwlib/include/ameba_ledc_pro.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_ledc_pro.h rename to ameba/amebag2/source/fwlib/include/ameba_ledc_pro.h index 322df799..0d6b8560 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ledc_pro.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ledc_pro.h @@ -168,4 +168,4 @@ _LONG_CALL_ void pseudo_i2c_set_len(u32 len); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_loguart.h b/ameba/amebag2/source/fwlib/include/ameba_loguart.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_loguart.h rename to ameba/amebag2/source/fwlib/include/ameba_loguart.h index 62e5d1a8..5184f6ff 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_loguart.h +++ b/ameba/amebag2/source/fwlib/include/ameba_loguart.h @@ -865,4 +865,4 @@ _LONG_CALL_ void LOGUART_PutChar_RAM(u8 c); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_osc131k.h b/ameba/amebag2/source/fwlib/include/ameba_osc131k.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_osc131k.h rename to ameba/amebag2/source/fwlib/include/ameba_osc131k.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ota.h b/ameba/amebag2/source/fwlib/include/ameba_ota.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_ota.h rename to ameba/amebag2/source/fwlib/include/ameba_ota.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_otpc.h b/ameba/amebag2/source/fwlib/include/ameba_otpc.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_otpc.h rename to ameba/amebag2/source/fwlib/include/ameba_otpc.h index f1f39cac..a7b2c0a2 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_otpc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_otpc.h @@ -358,4 +358,4 @@ _LONG_CALL_ int OTP_Write8(u32 Addr, u8 Data); _LONG_CALL_ int OTP_Read32(u32 Addr, u32 *Data); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebag2/source/fwlib/include/ameba_phy.h b/ameba/amebag2/source/fwlib/include/ameba_phy.h new file mode 100644 index 00000000..a5216888 --- /dev/null +++ b/ameba/amebag2/source/fwlib/include/ameba_phy.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +enum eth_phy_type { + RTL_8721F, + RTL_8721G, +}; + +enum eth_mode { + ETH_MAC_MODE, + ETH_PHY_MODE, +}; + +enum phy_clk_mode { + EXTERNAL_50M, + EXTERNAL_25M, + INTERNAL_XTAL, +}; + +enum phy_MMD_type { + RTK_MMD_TYPE, + +}; + +enum phy_address { + PHYID_0, + PHYID_1, + PHYID_2, + PHYID_3, +}; + +enum phy_mmd_access_mode { + PHY_MMD_ADDR, + PHY_MMD_DATA_NO_POST_INC, + PHY_MMD_DATA_RD_WR_POST_INC, + PHY_MMD_DATA_RD_POST_INC +}; + +/* MMD register mapping table */ +enum rtl8201fr_mmd_device_t { + RTL8201FR_MMD_DEV_PCS = 3, /* PCS (Physical Coding Sublayer) MMD device address */ + RTL8201FR_MMD_DEV_EEE_ADV = 7 /* EEE advertisement/ability MMD device address */ +}; + +enum rtl8201fr_mmd_reg_t { + RTL8201FR_MMD_REG_EEEPC1R = 0x0, /* EEE PCS Control 1 Register Offset */ + RTL8201FR_MMD_REG_EEEPS1R = 0x01, /* EEE PCS Status 1 Register Offset */ + RTL8201FR_MMD_REG_EEECR = 0x14, /* EEE Capability Register Offset */ + RTL8201FR_MMD_REG_EEEWER = 0x16, /* EEE Wake Error Register Offset */ + RTL8201FR_MMD_REG_EEEAR = 0x3c, /* EEE Advertisement Register Offset */ + RTL8201FR_MMD_REG_EEELPAR = 0x3d /* EEE Link Partner Ability Register Offset */ +}; + +/* RTL8201FR Page0 Register 13: MACR Register (0x0D) */ +#define RTL8201FR_MACR_FUNC_ADDR_MASK (0x3 << 14) /*[15:14] Function selection for MMD access*/ +#define RTL8201FR_MACR_FUNC_ADDR(x) (((x) & 0x3) << 14) +#define RTL8201FR_MACR_FUNC_ADDR_GET(x) (((x) & 0x3) >> 14) +#define RTL8201FR_MACR_DEVAD_MASK (0x1F << 0) /*[4:0] MMD device address*/ +#define RTL8201FR_MACR_DEVAD(x) (((x) & 0x1F) << 0) +#define RTL8201FR_MACR_DEVAD_GET(x) (((x) & 0x1F) >> 0) + +/* RTL8201FR Page0 Register 14: MAADR (MMD Access Address/Data Register) */ +#define RTL8201FR_MAADR_DATA_MASK (0xFFFF << 0) /* [15:0] Address/Data field, used for MMD management via MACR/MAADR pair */ +#define RTL8201FR_MAADR_DATA(x) (((x) & 0xFFFF) << 0) +#define RTL8201FR_MAADR_DATA_GET(x) (((x) & 0xFFFF) >> 0) + + +/* --- Page 4: Energy Efficient Ethernet (EEE) --- */ +#define RTL8201FR_PAGE4_REG_EEE_CAP_EN (0x10) /*!< EEE Capability Register (Page 4, Reg 21) */ +#define RTL8201FR_PAGE4_REG_EEE_CAP (0x15) /*!< EEE Capability Register (Page 4, Reg 21) */ + +/* --- Page 7: Special/Custom registers --- */ +#define RTL8201FR_PAGE7_REG_RMII_MODE_SET (0x10) /*!< LED Mode Register (Page 7, Reg 11) */ +#define RTL8201FR_PAGE7_REG_CUSTOM_LED_SET (0x11) /*!< LED Mode Register (Page 7, Reg 11) */ + +/******************************************************************************* + * RTL8201FR PAGE4 Registers + ******************************************************************************/ + +/* Page4 Register 16: EEE Capability Enable Register */ +#define RTL8201FR_P4_16_EEE_10_CAP (1U << 13) /* [13] Enable EEE 10M capability */ +#define RTL8201FR_P4_16_EEE_NWAY_EN (1U << 12) /* [12] Enable Next Page Exchange for EEE 100M */ +#define RTL8201FR_P4_16_TX_QUIET_EN (1U << 9) /* [9] Enable turning off 100TX when TX Quiet State (recommended for EEE) */ +#define RTL8201FR_P4_16_RX_QUIET_EN (1U << 8) /* [8] Enable turning off 100RX when RX Quiet State (recommended for EEE) */ + +/* Page4 Register 21: EEE Capability Register */ +#define RTL8201FR_P4_21_RG_DIS_LDVT (1U << 12) /* [12] Set 1: Disable line driver of the analog circuit */ +#define RTL8201FR_P4_21_EEE_100_CAP_GET(x) (((x) >> 0) & 0x1) /* [0] Indicate link partner supports EEE 100M (NWay result, Read Only) */ + + +/******************************************************************************* + * RTL8201FR PAGE7 Registers + ******************************************************************************/ + +/* Page7 Register 16: RMII Mode Setting Register (RMSR) */ +#define RTL8201FR_P7_16_RMII_CLK_DIR (1U << 12) /* [12] This bit sets type of TXC in RMII mode. */ +#define RTL8201FR_P7_16_RMII_TX_OFFSET(x) (((x) & 0xF) << 8) /* [11:8] Adjust RMII TX interface timing */ +#define RTL8201FR_P7_16_RMII_RX_OFFSET(x) (((x) & 0xF) << 4) /* [7:4] Adjust RMII RX interface timing */ +#define RTL8201FR_P7_16_RMII_MODE (1U << 3) /* [3] 1: Set RMII mode (Must keep to 1) */ +#define RTL8201FR_P7_16_RMII_RXDV_SEL (1U << 2) /* [2] 1: CRS_DV pin is RXDV; 0: CRS_DV is CRS_DV signal */ +#define RTL8201FR_P7_16_RMII_RXDSEL (1U << 1) /* [1] 1: RMII data with SSD error; 0: RMII data only */ + +/******************************************************************************* + * RTL8201FR MMD Register Mapping (accessed via MACR/MAADR) + ******************************************************************************/ +/* Device 3, Offset 0: EEEPCS Control 1 Register */ +#define RTL8201FR_EEEPC1R_CLK_STOP_EN (0x1 << 10) /* [10] Enable RXC clock stop in LPI mode */ + +/* Device 3, Offset 1: EEEPCS Status 1 Register (Read Only) */ +#define RTL8201FR_EEEPS1R_TX_LPI_RCVD_GET(x) (((x) >> 11) & 0x1) /* [11] TX PCS received LPI indication */ +#define RTL8201FR_EEEPS1R_RX_LPI_RCVD_GET(x) (((x) >> 10) & 0x1) /* [10] RX PCS received LPI indication */ +#define RTL8201FR_EEEPS1R_TX_LPI_IND_GET(x) (((x) >> 9) & 0x1) /* [9] TX PCS LPI indication in progress */ +#define RTL8201FR_EEEPS1R_RX_LPI_IND_GET(x) (((x) >> 8) & 0x1) /* [8] RX PCS LPI indication in progress */ +#define RTL8201FR_EEEPS1R_CLK_STOP_CAP_GET(x) (((x) >> 6) & 0x1) /* [6] LPI TXC clock stop capability */ + +/* Device 3, Offset 0x14: EEE Capability Register (Read Only) */ +#define RTL8201FR_EEECR_100BT_EEE_SUP_GET(x) (((x) >> 1) & 0x1) /* [1] 100Base-TX EEE support */ + +/* Device 3, Offset 0x16: EEE Wake Error Register (Read Clear)*/ +#define RTL8201FR_EEEWER_WAKE_ERR_CNT_MASK (0xFFFF) /* [15:0] EEE Wake error counter */ +#define RTL8201FR_EEEWER_WAKE_ERR_CNT(x) ((x) & 0xFFFF) +#define RTL8201FR_EEEWER_WAKE_ERR_CNT_GET(x) ((x) & 0xFFFF) + +/* Device 7, Offset 0x3c: EEE Advertisement Register */ +#define RTL8201FR_EEEAR_100BT_EEE_ADV_MASK (0x1 << 1) /* [1] Advertise 100Base-TX EEE capability */ +#define RTL8201FR_EEEAR_100BT_EEE_ADV(x) (((x) & 0x1) << 1) +#define RTL8201FR_EEEAR_100BT_EEE_ADV_GET(x) (((x) >> 1) & 0x1) + +/* Device 7, Offset 0x3d: EEE Link Partner Ability Register */ +#define RTL8201FR_EEELPAR_LP_100BT_EEE_GET(x) (((x) >> 1) & 0x1) /* [1] Link partner advertises 100Base-TX EEE */ + + +/* RTL8211F Page 0xA43 Register 0x19: PHY Specific Control Register 2*/ +#define RTL8211F_PHY_MODE_PAGE (0xA43) +#define RTL8211F_PHYCR2_ADDR (0x19) +#define RTL8211F_PHCR2_PHY_MODE (0x0863) +#define RTL8211F_PHCR2_MAC_MODE (0x0843) + + +int PHY_SoftWareReset(uint8_t phy_id); +int PHY_RestartAutoNego(uint8_t phy_id); +int PHY_SetMmdReg(uint8_t phy_id, uint8_t mmd_dev, uint16_t mmd_addr, uint16_t data); +int PHY_GetMmdReg(uint8_t phy_id, uint8_t mmd_dev, uint16_t mmd_addr, uint16_t *p_data); +int PHY_EnableEEE(uint8_t phy_id, u32 status); +int PHY_SetEEEMode(uint8_t phy_id, uint8_t eth_mode); +int PHY_SetRefclkDir(uint8_t phy_id, u32 mac_dir); diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pinmap.h b/ameba/amebag2/source/fwlib/include/ameba_pinmap.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_pinmap.h rename to ameba/amebag2/source/fwlib/include/ameba_pinmap.h index aaeeba02..a0d8b4ca 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pinmap.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pinmap.h @@ -63,4 +63,4 @@ void pinmap_init(void); /* Other definations --------------------------------------------------------*/ #define GPIO_PuPd_KEEP 0xFF /* keep pupd unchanged */ -#endif //_AMEBA_PINMAP_H_ \ No newline at end of file +#endif //_AMEBA_PINMAP_H_ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pinmux.h b/ameba/amebag2/source/fwlib/include/ameba_pinmux.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_pinmux.h rename to ameba/amebag2/source/fwlib/include/ameba_pinmux.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pke.h b/ameba/amebag2/source/fwlib/include/ameba_pke.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_pke.h rename to ameba/amebag2/source/fwlib/include/ameba_pke.h index c22c8955..8c62120b 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pke.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pke.h @@ -450,4 +450,4 @@ _LONG_CALL_ int pke_eddsa_ed25519_read_signature(uint8_t *message, size_t msg_le /** @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebag2/source/fwlib/include/ameba_plic.h b/ameba/amebag2/source/fwlib/include/ameba_plic.h new file mode 100644 index 00000000..e6e8c73c --- /dev/null +++ b/ameba/amebag2/source/fwlib/include/ameba_plic.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __AMEBA_PLIC_H__ +#define __AMEBA_PLIC_H__ + +#define PLIC_INT_PRI_BITS 3 // Interrupt priority bits, max interrupt priority = 2^PLIC_INT_PRI_BITS-1. 2 ~ 4 +#define PLIC_INT_PRIS ((1 << PLIC_INT_PRI_BITS) - 1) + +#define PLIC_INT_PRI_REG_OFFSET 0x0800 // the address offset of Interrupt Priority Register +#define PLIC_INT_PEND_REG_OFFSET 0x0C00 // the address offset of Interrupt Pending Register +#define PLIC_INT_CLAIMED_REG_OFFSET 0x0C20 // the address offset of Interrupt Claimed Register +#define PLIC_INT_PEND_CLEAR_REG_OFFSET 0x0C40 // the address offset of Interrupt Pending Clear Register +#define PLIC_INT_PEND_SET_REG_OFFSET 0x0C60 // the address offset of Interrupt Pending Set Register +#define PLIC_INT_SIP_REG_OFFSET MSIP_ADDR // the address offset of Software Interrupt Pending Register +#define PLIC_INT_CLAIM_REG_OFFSET 0x0014 // the address offset of Interrupt Claim Register (Pending IRQ ID reading) +#define PLIC_INT_COMP_REG_OFFSET 0x0018 // the address offset of Interrupt Complete Register (IRQ Ack) +#define PLIC_INT_THRD_REG_OFFSET 0x001C // the address offset of Interrupt Threshold Register +#define PLIC_INT_EN_REG_OFFSET 0x0020 // the address offset of Interrupt Enable Register + +#define MAX_HART_NUM 8 // Max HART number supported +#define PLIC_HART_SELF 0xFFFFFFFFUL // Get PLIC self id from mhartid + + +#define PLIC_HART_REG(hart, reg) REG32((PLIC_BASE) + ((hart) << 8) + (reg)) + +#define PLIC_HART_IRQ_READ(reg, hart, irq) \ + PLIC_HART_REG((hart), (reg) + (((irq) >> 5) << 2)) + +#define PLIC_HART_IRQ_SET(reg, hart, irq) \ +do { \ + PLIC_HART_REG((hart), (reg) + (((irq) >> 5) << 2)) |= (1 << ((irq) & 0x1f)); \ +} while(0) + +#define PLIC_HART_IRQ_CLEAR(reg, hart, irq) \ +do { \ + PLIC_HART_REG((hart), (reg) + (((irq) >> 5) << 2)) &= ~(1 << ((irq) & 0x1f)); \ +} while(0) + +#define PLIC_IRQ_REG(reg, irq) REG32((PLIC_BASE) + (reg) + ((irq) << 2)) +#define PLIC_IRQ_PEND_REG(irq) \ + REG32((PLIC_BASE) + (PLIC_INT_PEND_REG_OFFSET) + ((irq >> 5) << 2)) +#define PLIC_IRQ_PEND_CLEAR_REG(irq) \ + REG32((PLIC_BASE) + (PLIC_INT_PEND_CLEAR_REG_OFFSET) + ((irq >> 5) << 2)) +#define PLIC_IRQ_PEND_SET_REG(irq) \ + REG32((PLIC_BASE) + (PLIC_INT_PEND_SET_REG_OFFSET) + ((irq >> 5) << 2)) +#define PLIC_IRQ_CLAIMED_REG(irq) \ + REG32((PLIC_BASE) + (PLIC_INT_CLAIMED_REG_OFFSET) + ((irq >> 5) << 2)) + +#define PLIC_IRQ_SET(reg, irq) \ +do { \ + REG32((reg) + ((irq) << 2)) |= (1 << ((irq) & 0x1f)); \ +} while(0) + +#define PLIC_IRQ_CLEAR(reg, irq) \ +do { \ + REG32((reg) + ((irq) << 2)) &= ~(1 << ((irq) & 0x1f)); \ +} while(0) + +/** + \brief Enable an Interrupt. + \details To enable an interrupt whith a given IRQ ID. + \param irq_id the interrupt ID. + */ +extern void plic_enable_irq(uint32_t irq_id); + +/** + \brief Disable an Interrupt. + \details To disable an interrupt whith a given IRQ ID. + \param irq_id the interrupt ID. + */ +extern void plic_disable_irq(uint32_t irq_id); + +/** + \brief Get the enabling of an Interrupt. + \details To enable an interrupt whith a given IRQ ID. + \param irq_id the interrupt ID. + \return The status of the interrupt enabling. + */ +extern uint32_t plic_get_irq_enable(uint32_t irq_id); + +/** + \brief Set the enable status of 32 Interrupts in the same register. + \details To set 32 interrupt enable bits with a given register id + \param irq_id the interrupt ID. + \return The status of the interrupt enabling. + */ +extern void plic_set_enable(uint32_t reg_id, uint32_t interrupt); + +/** + \brief Get the enable status of 32 Interrupts in the same register. + \details To get 32 interrupt enable bits with a given register id + \param irq_id the interrupt ID. + \return The status of the interrupt enabling. + */ +extern uint32_t plic_get_enable(uint32_t reg_id); + + + +/** + \brief Write the interrupt enable bit maps. + \details To write the interrupt enble bit maps + \param enable the buffer of the interrupt enable bits map. + */ +extern void plic_write_enables(uint32_t *enable); + +/** + \brief Set Interrupt Priority. + \details Set the Priority of a given Interrupt ID. IRQ ID 0 is reserved. + \param irq_id the interrupt ID. + \param priority the priority of the interrupt ID. + */ +extern void plic_set_irq_priority(uint32_t irq_id, uint32_t priority); + +/** + \brief Get Interrupt Priority of given IRQ ID. + \details Get the Priority of a given Interrupt ID. IRQ ID 0 is reserved. + \param irq_id the interrupt ID. + \return The priority of given IRQ ID. + */ +extern uint32_t plic_get_irq_priority(uint32_t irq_id); + +/** + \brief Get the pending status of 32 Interrupts in the same register. + \details To get 32 interrupt pending bits with a given register id + \param reg_id the register ID. + \return The status of the interrupt pending. + */ +extern uint32_t plic_get_pending(uint32_t reg_id); + +/** + \brief Get the pending status of an interrupt. + \details Get the pending status of the given IRQ ID. + \param irq_id the IRQ ID. + \return The interrupt pending status of the given IRQ ID. + 0: interrupt is not pending + 1: interrupt is pending. + */ +extern uint32_t plic_get_irq_pending(uint32_t irq_id); + +/** + \brief Clear the pending status of an interrupt. + \details Clear he pending status of the given IRQ ID. + \param irq_id the IRQ ID. + */ +extern void plic_clear_irq_pending(uint32_t irq_id); + +/** + \brief Clear the pending status of an interrupt. + \details Clear he pending status of the given IRQ ID. + \param irq_id the IRQ ID. + */ +extern void plic_set_irq_pending(uint32_t irq_id); + +/** + \brief Check interrupt claim status + \details Check whether IRQ ID is claimed but not completed yet + \para irq_id the IRQ ID. + \return 0: IRQ ID is not claimed + 1: IRQ ID is claimed + */ +extern uint32_t plic_get_irq_claimed(uint32_t irq_id); + +/** + \brief To claim the highest priority pending interrupt. + \details Claims the highest priority pending interrupt and get its IRQ ID. + \return The IRQ ID of the highest priority pending interrupt. + */ +extern uint32_t plic_claim_irq(void); + +/** + \brief To complete an interrupt. + \details Completes an interrupt handleing and clean its pending status. + \param irq_id The given IRQ ID of the interrupt to be completed. + \return void. + */ +extern void plic_complete_irq(uint32_t irq_id); + +/** + \brief Set interrupt priority threshold. + \details Set the interrupt priority threshold. Only interrupts with its + priority higher than this threshold can active. + \param priority The interrupt priority threshold. + \return void. + */ +extern void plic_set_threshold(uint32_t priority); + +/** + \brief Get interrupt priority threshold. + \details Get the interrupt priority threshold. Only interrupts with its + priority higher than this threshold can active. + \param priority The interrupt priority threshold. + \return void. + */ +extern uint32_t plic_get_threshold(void); + +/** + \brief Set software interrupt pending. + \details To assert the software interrupt pending signal of the Hardware Architecture Target. + \param hart The hart target to set software interrupt. + \return void. + */ +extern void plic_set_sip(uint32_t hart); + +/** + \brief Clear software interrupt pending. + \details To clear the software interrupt pending signal of the Hardware Architecture Target. + \param hart The hart target to clear software interrupt. + \return void. + */ +extern void plic_clear_sip(uint32_t hart); + +/** + \brief PLIC HAL initialization + \details To initial the PLIC HAL code. + \return void. + */ +extern void plic_init(void); + +/** + \brief PLIC get active IRQ Id. + \details To get currently active IRQ Id. + \return The active IRQ Id. + */ +extern uint32_t plic_get_active_irq_id(void); + +#endif /* end of #define __PLIC_H */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pmc.h b/ameba/amebag2/source/fwlib/include/ameba_pmc.h similarity index 95% rename from ameba/amebaG2/source/fwlib/include/ameba_pmc.h rename to ameba/amebag2/source/fwlib/include/ameba_pmc.h index c2e190a5..af70581e 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pmc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pmc.h @@ -7,6 +7,10 @@ #ifndef _AMEBA_PMC_H_ #define _AMEBA_PMC_H_ +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup AmebaD_Platform * @{ */ @@ -191,12 +195,6 @@ enum PMC_AP_WAKE_STATUS { * @} */ -struct PSCFG_TypeDef { - u8 keep_osc4m_on_in_sleep; /* keep OSC4M on or off for sleep*/ - u8 xtal_mode_in_sleep; /* see enum xtal_mode_sleep for detail */ - u8 regu_state_in_sleep; /* set work state of regu(SWR+LDO) in sleep, default sleep to 0.7V(SWR:PFM mode, LDO:power cut)*/ -}; - int ap_suspend(void); void ap_resume(void); u32 ap_status_on(void); @@ -218,4 +216,9 @@ void SOCPS_PeriPermissionEntry(uint32_t ip_mask, u32 enable); void SOCPS_BitPermissionEntry(uint32_t ip_mask, u32 enable); extern SLEEP_ParamDef sleep_param; -#endif //_AMEBA_PMC_H_ \ No newline at end of file + +#ifdef __cplusplus +} +#endif + +#endif //_AMEBA_PMC_H_ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pmctimer.h b/ameba/amebag2/source/fwlib/include/ameba_pmctimer.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_pmctimer.h rename to ameba/amebag2/source/fwlib/include/ameba_pmctimer.h index 4c570145..62bcbb77 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pmctimer.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pmctimer.h @@ -192,4 +192,4 @@ void PMCTimer_Reset(void); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pmu.h b/ameba/amebag2/source/fwlib/include/ameba_pmu.h similarity index 92% rename from ameba/amebaG2/source/fwlib/include/ameba_pmu.h rename to ameba/amebag2/source/fwlib/include/ameba_pmu.h index ffa3eb48..5ddafb62 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pmu.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pmu.h @@ -7,13 +7,18 @@ #ifndef _AMEBA_PMU_H_ #define _AMEBA_PMU_H_ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { PMU_OS = 0, PMU_WLAN_DEVICE, PMU_CPU0_RUN, PMU_CPU1_RUN, PMU_WLAN_FW_DEVICE, - PMU_BT_DEVICE, + PMU_BT_CONTROLLER, + PMU_BT_HOST, PMU_WHC_WIFI, PMU_DHCP_PROCESS, PMU_LWIP_STACK, @@ -41,7 +46,7 @@ typedef struct { uint32_t pmu_yield_os_check(void); uint32_t pmu_exec_sleep_hook_funs(void); -void pmu_exec_wakeup_hook_funs(uint32_t nDeviceIdMax); +void pmu_exec_wakeup_hook_funs(uint32_t nDeviceIdMax, uint32_t common_param); uint32_t pmu_set_sleep_type(uint32_t type); uint32_t pmu_get_sleep_type(void); uint32_t pmu_get_sleep_time(void); @@ -83,4 +88,10 @@ extern void Systick_Cmd(uint32_t enable); extern uint32_t SYSTIMER_GetPassTick(uint32_t start); extern uint32_t system_can_yield; +extern uint32_t cur_device_id; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ppe.h b/ameba/amebag2/source/fwlib/include/ameba_ppe.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_ppe.h rename to ameba/amebag2/source/fwlib/include/ameba_ppe.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_psphy.h b/ameba/amebag2/source/fwlib/include/ameba_psphy.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_psphy.h rename to ameba/amebag2/source/fwlib/include/ameba_psphy.h index 7b8c5c9b..200ff890 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_psphy.h +++ b/ameba/amebag2/source/fwlib/include/ameba_psphy.h @@ -262,4 +262,4 @@ typedef struct { /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_psram.h b/ameba/amebag2/source/fwlib/include/ameba_psram.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_psram.h rename to ameba/amebag2/source/fwlib/include/ameba_psram.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_pwmtimer.h b/ameba/amebag2/source/fwlib/include/ameba_pwmtimer.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_pwmtimer.h rename to ameba/amebag2/source/fwlib/include/ameba_pwmtimer.h index 35d4ae0c..f625e611 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_pwmtimer.h +++ b/ameba/amebag2/source/fwlib/include/ameba_pwmtimer.h @@ -624,4 +624,4 @@ extern u32 TIM_IT_CCx[PWM_CHAN_MAX]; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_rcc.h b/ameba/amebag2/source/fwlib/include/ameba_rcc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_rcc.h rename to ameba/amebag2/source/fwlib/include/ameba_rcc.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_reset.h b/ameba/amebag2/source/fwlib/include/ameba_reset.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_reset.h rename to ameba/amebag2/source/fwlib/include/ameba_reset.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_rsip.h b/ameba/amebag2/source/fwlib/include/ameba_rsip.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_rsip.h rename to ameba/amebag2/source/fwlib/include/ameba_rsip.h index 92bd6705..23fe551f 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_rsip.h +++ b/ameba/amebag2/source/fwlib/include/ameba_rsip.h @@ -544,4 +544,4 @@ _LONG_CALL_ void RSIP_MMU_Cache_Clean(void); /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_rtc.h b/ameba/amebag2/source/fwlib/include/ameba_rtc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_rtc.h rename to ameba/amebag2/source/fwlib/include/ameba_rtc.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_rxi300.h b/ameba/amebag2/source/fwlib/include/ameba_rxi300.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_rxi300.h rename to ameba/amebag2/source/fwlib/include/ameba_rxi300.h index 795eb602..a592cc4c 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_rxi300.h +++ b/ameba/amebag2/source/fwlib/include/ameba_rxi300.h @@ -873,4 +873,4 @@ typedef struct { /** @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sd.h b/ameba/amebag2/source/fwlib/include/ameba_sd.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_sd.h rename to ameba/amebag2/source/fwlib/include/ameba_sd.h index 4c645b48..15303b9d 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_sd.h +++ b/ameba/amebag2/source/fwlib/include/ameba_sd.h @@ -450,6 +450,7 @@ typedef struct { */ SD_RESULT SD_Init(void); SD_RESULT SD_DeInit(void); +u32 SD_IRQHandler(void *pData); /** * @} */ @@ -495,7 +496,8 @@ SD_RESULT SD_GetCardCSD(SD_HdlTypeDef *hsd, SD_CardCSDTypeDef *pCSD); SD_RESULT SD_GetSDStatus(SD_HdlTypeDef *hsd, SD_StatusTypeDef *pStatus); _LONG_CALL_ void SD_SetSema(int (*sema_take_fn)(u32), int (*sema_give_isr_fn)(u32)); -u32 SD_WaitTransDone(SD_HdlTypeDef *hsd, u32 timeout_us); +_LONG_CALL_ void SD_PreDMATrans(SD_HdlTypeDef *hsd); +_LONG_CALL_ u32 SD_WaitTransDone(SD_HdlTypeDef *hsd, u32 timeout_us); _LONG_CALL_ SD_RESULT SD_Status(void); _LONG_CALL_ int SD_CheckStatusTO(SD_HdlTypeDef *hsd, u32 timeout_us); _LONG_CALL_ SD_RESULT SD_ReadBlocks(u32 sector, u8 *data, u32 count); diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sd_host.h b/ameba/amebag2/source/fwlib/include/ameba_sd_host.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_sd_host.h rename to ameba/amebag2/source/fwlib/include/ameba_sd_host.h index 2c75b8c4..94d2a987 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_sd_host.h +++ b/ameba/amebag2/source/fwlib/include/ameba_sd_host.h @@ -1602,12 +1602,11 @@ typedef struct { #define SDMMC_R6_ILLEGAL_CMD 0x00004000U #define SDMMC_R6_COM_CRC_FAILED 0x00008000U -#define SDMMC_VOLTAGE_WINDOW_SD 0x80100000U #define SDMMC_HIGH_CAPACITY 0x40000000U -#define SDMMC_STD_CAPACITY 0x00000000U -#define SDMMC_CHECK_PATTERN 0x000001AAU -#define SDMMC_SWITCH_1_8V_CAPACITY 0x01000000U +#define SDMMC_SWITCH_1_8V_CAPACITY 0x10000000U +#define SDMMC_VOLTAGE_WINDOW_SD 0x00100000U // 3.2-3.3V +#define SDMMC_CHECK_PATTERN 0x000001AAU /** * @brief Masks for SCR */ @@ -1967,7 +1966,7 @@ u32 SDMMC_CmdSetWrBlkEraseCnt(SDIOHOST_TypeDef *SDIOx, u32 BlockCnt); u32 SDMMC_CmdSendSCR(SDIOHOST_TypeDef *SDIOx); u32 SDMMC_CmdSendCID(SDIOHOST_TypeDef *SDIOx); u32 SDMMC_CmdSendCSD(SDIOHOST_TypeDef *SDIOx, u32 Argument); -u32 SDMMC_CmdSetRelAdd(SDIOHOST_TypeDef *SDIOx, u16 *pRCA); +u32 SDMMC_CmdSetRelAdd(SDIOHOST_TypeDef *SDIOx); u32 SDMMC_CmdSendStatus(SDIOHOST_TypeDef *SDIOx, u32 Argument); u32 SDMMC_CmdStatusRegister(SDIOHOST_TypeDef *SDIOx); u32 SDMMC_CmdSwitch(SDIOHOST_TypeDef *SDIOx, u32 Argument); @@ -1978,15 +1977,10 @@ u32 SDIO_CmdRWDirect(SDIOHOST_TypeDef *SDIOx, u32 Argument); u32 SDIO_CmdRWExtended(SDIOHOST_TypeDef *SDIOx, u32 Argument); /* SDMMC Responses management functions */ -u32 SDMMC_GetCmdError(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp1(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp1B(SDIOHOST_TypeDef *SDIOx, u32 Timeout); -u32 SDMMC_GetCmdResp2(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp3(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp4(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp5(SDIOHOST_TypeDef *SDIOx); -u32 SDMMC_GetCmdResp6(SDIOHOST_TypeDef *SDIOx, u16 *pRCA); -u32 SDMMC_GetCmdResp7(SDIOHOST_TypeDef *SDIOx); +u32 SDIO_WaitResp(SDIOHOST_TypeDef *SDIOx, u8 RespType, u32 TimeOutUs); +u32 SDMMC_CheckErrResp1(u32 resp); +u32 SDMMC_CheckErrResp5(u32 resp); +u32 SDMMC_CheckErrResp6(u32 resp); /** * @} diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sdio_bt.h b/ameba/amebag2/source/fwlib/include/ameba_sdio_bt.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_sdio_bt.h rename to ameba/amebag2/source/fwlib/include/ameba_sdio_bt.h index 34b8f31b..574b9d24 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_sdio_bt.h +++ b/ameba/amebag2/source/fwlib/include/ameba_sdio_bt.h @@ -236,4 +236,4 @@ /** @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sdio_device.h b/ameba/amebag2/source/fwlib/include/ameba_sdio_device.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_sdio_device.h rename to ameba/amebag2/source/fwlib/include/ameba_sdio_device.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sdio_wifi.h b/ameba/amebag2/source/fwlib/include/ameba_sdio_wifi.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_sdio_wifi.h rename to ameba/amebag2/source/fwlib/include/ameba_sdio_wifi.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_secure_boot.h b/ameba/amebag2/source/fwlib/include/ameba_secure_boot.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_secure_boot.h rename to ameba/amebag2/source/fwlib/include/ameba_secure_boot.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sema_rom.h b/ameba/amebag2/source/fwlib/include/ameba_sema_rom.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_sema_rom.h rename to ameba/amebag2/source/fwlib/include/ameba_sema_rom.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sha.h b/ameba/amebag2/source/fwlib/include/ameba_sha.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_sha.h rename to ameba/amebag2/source/fwlib/include/ameba_sha.h index d6e5de3c..044552b8 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_sha.h +++ b/ameba/amebag2/source/fwlib/include/ameba_sha.h @@ -697,4 +697,4 @@ _LONG_CALL_ int crypto_hmac_sha2_final(SHA_context *ctx, u8 *output); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_soc.h b/ameba/amebag2/source/fwlib/include/ameba_soc.h similarity index 93% rename from ameba/amebaG2/source/fwlib/include/ameba_soc.h rename to ameba/amebag2/source/fwlib/include/ameba_soc.h index 419e6684..99e1f6b6 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_soc.h +++ b/ameba/amebag2/source/fwlib/include/ameba_soc.h @@ -19,7 +19,7 @@ #ifndef CONFIG_BUILD_ROM /* ram headers */ #include "ameba_ota.h" -// #include "os_wrapper.h" +#include "os_wrapper.h" #include "ameba_pmu.h" #endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_soc_ps.h b/ameba/amebag2/source/fwlib/include/ameba_soc_ps.h similarity index 90% rename from ameba/amebaG2/source/fwlib/include/ameba_soc_ps.h rename to ameba/amebag2/source/fwlib/include/ameba_soc_ps.h index d8e0ea88..fc6324d4 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_soc_ps.h +++ b/ameba/amebag2/source/fwlib/include/ameba_soc_ps.h @@ -7,6 +7,11 @@ #ifndef _AMEBA_SOCPS_H_ #define _AMEBA_SOCPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + enum wakeup_mask { WAKEUP_NULL = 0, WAKEUP_NP = 1, @@ -16,7 +21,13 @@ enum wakeup_mask { struct WakeEvent_TypeDef { u32 Module; enum wakeup_mask Wakeup; -} ; +}; + +struct PSCFG_TypeDef { + u8 keep_osc4m_on; /* keep OSC4M on or off for sleep and dslp*/ + u8 xtal_mode_in_sleep; /* set xtal mode during sleep mode*/ + u8 sleep_to_08V; /* default sleep to 0.7V, set this option to TRUE will sleep to 0.8V */ +}; struct MPU_BackUp_TypeDef { u32 CTRL; @@ -94,4 +105,8 @@ void SOCPS_USBSuspendWakeControl(u8 status); void SOCPS_PowerStateSetInSleep(u8 pwr_sts); void SOCPS_PowerStateSetInNormal(u8 pwr_sts); void SOCPS_SetMemMode(u32 module, u32 mem_mode); + +#ifdef __cplusplus +} +#endif #endif //_AMEBA_SOCPS_H_ \ No newline at end of file diff --git a/ameba/amebaG2/source/fwlib/include/ameba_spi.h b/ameba/amebag2/source/fwlib/include/ameba_spi.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_spi.h rename to ameba/amebag2/source/fwlib/include/ameba_spi.h index 86f41f49..40b9b0b1 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_spi.h +++ b/ameba/amebag2/source/fwlib/include/ameba_spi.h @@ -689,4 +689,4 @@ extern const SPI_DevTable SPI_DEV_TABLE[2]; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_spic.h b/ameba/amebag2/source/fwlib/include/ameba_spic.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_spic.h rename to ameba/amebag2/source/fwlib/include/ameba_spic.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_spinand.h b/ameba/amebag2/source/fwlib/include/ameba_spinand.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_spinand.h rename to ameba/amebag2/source/fwlib/include/ameba_spinand.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_sport.h b/ameba/amebag2/source/fwlib/include/ameba_sport.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_sport.h rename to ameba/amebag2/source/fwlib/include/ameba_sport.h index 41226758..fa874f21 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_sport.h +++ b/ameba/amebag2/source/fwlib/include/ameba_sport.h @@ -1321,4 +1321,4 @@ extern const AUDIO_DevTable AUDIO_DEV_TABLE[1]; /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_syscfg.h b/ameba/amebag2/source/fwlib/include/ameba_syscfg.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_syscfg.h rename to ameba/amebag2/source/fwlib/include/ameba_syscfg.h index 98ff811c..0536209b 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_syscfg.h +++ b/ameba/amebag2/source/fwlib/include/ameba_syscfg.h @@ -181,8 +181,8 @@ _LONG_CALL_ u32 SYSCFG_OTP_RomPatchEn(void); #define SYSCFG_OTP_BOOT_FROM_EXT 2 /******************* Macro definition for Lifecycle ********************/ -#define PSA_LIFECYCLE_RMA 1 -#define PSA_LIFECYCLE_DECOMMISSIONED 2 +#define RTK_PSA_LIFECYCLE_RMA 1 +#define RTK_PSA_LIFECYCLE_DECOMMISSIONED 2 /******************* Macro definition for RSIP MODE ********************/ #define RSIP_XTS_MODE 0 diff --git a/ameba/amebaG2/source/fwlib/include/ameba_thermal.h b/ameba/amebag2/source/fwlib/include/ameba_thermal.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_thermal.h rename to ameba/amebag2/source/fwlib/include/ameba_thermal.h index 31f68e73..51371b7d 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_thermal.h +++ b/ameba/amebag2/source/fwlib/include/ameba_thermal.h @@ -357,4 +357,4 @@ _LONG_CALL_ float TM_GetFdegree(u32 Data); /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_trng.h b/ameba/amebag2/source/fwlib/include/ameba_trng.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_trng.h rename to ameba/amebag2/source/fwlib/include/ameba_trng.h index 64a36ffc..65efb26b 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_trng.h +++ b/ameba/amebag2/source/fwlib/include/ameba_trng.h @@ -317,4 +317,4 @@ _LONG_CALL_ u32 __wrap_rand(void); /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_trustzone.h b/ameba/amebag2/source/fwlib/include/ameba_trustzone.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_trustzone.h rename to ameba/amebag2/source/fwlib/include/ameba_trustzone.h index 7730b153..ef7b70b0 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_trustzone.h +++ b/ameba/amebag2/source/fwlib/include/ameba_trustzone.h @@ -57,9 +57,9 @@ typedef enum { */ #define SAU_INIT_CTRL_ALLNS 0 -#define SAU_ENTRYS_NUM 8 +#define SAU_ENTRY_NUM 8 -#define MPC_ENTRYS_NUM 6 +#define MPC_ENTRY_NUM 6 #define MPC_CNT 3 /** diff --git a/ameba/amebaG2/source/fwlib/include/ameba_uart.h b/ameba/amebag2/source/fwlib/include/ameba_uart.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_uart.h rename to ameba/amebag2/source/fwlib/include/ameba_uart.h index 923e04c8..c3edaea3 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_uart.h +++ b/ameba/amebag2/source/fwlib/include/ameba_uart.h @@ -701,6 +701,8 @@ _LONG_CALL_ void UART_RxDebounceCmd(UART_TypeDef *UARTx, u32 NewState); _LONG_CALL_ void UART_RxDMADummyDataConfig(UART_TypeDef *UARTx, u8 Byte); _LONG_CALL_ u32 UART_GetRxDMADummyFlag(UART_TypeDef *UARTx); _LONG_CALL_ void UART_RxClearDMADummyFlag(UART_TypeDef *UARTx); +_LONG_CALL_ void UART_RxToThreConfig(UART_TypeDef *UARTx, u32 RxTimeout); +_LONG_CALL_ void UART_REToThreConfig(UART_TypeDef *UARTx, u32 RxTimeout); /* Other Definitions --------------------------------------------------------*/ @@ -738,4 +740,4 @@ UART_GetRxFlag(u32 UartIdx) /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_ups.h b/ameba/amebag2/source/fwlib/include/ameba_ups.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_ups.h rename to ameba/amebag2/source/fwlib/include/ameba_ups.h index f5ee5e84..a7749bdf 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_ups.h +++ b/ameba/amebag2/source/fwlib/include/ameba_ups.h @@ -216,4 +216,4 @@ _LONG_CALL_ void UPS_SetDbcCnt(u16 Dbc_Cnt, u8 idx); /** @} */ /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/ameba_usb.h b/ameba/amebag2/source/fwlib/include/ameba_usb.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_usb.h rename to ameba/amebag2/source/fwlib/include/ameba_usb.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_uvc.h b/ameba/amebag2/source/fwlib/include/ameba_uvc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_uvc.h rename to ameba/amebag2/source/fwlib/include/ameba_uvc.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_vector.h b/ameba/amebag2/source/fwlib/include/ameba_vector.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_vector.h rename to ameba/amebag2/source/fwlib/include/ameba_vector.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_vector_table.h b/ameba/amebag2/source/fwlib/include/ameba_vector_table.h similarity index 98% rename from ameba/amebaG2/source/fwlib/include/ameba_vector_table.h rename to ameba/amebag2/source/fwlib/include/ameba_vector_table.h index 19e84156..65ea967a 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_vector_table.h +++ b/ameba/amebag2/source/fwlib/include/ameba_vector_table.h @@ -23,6 +23,7 @@ typedef enum APIRQn { MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SecureFault_IRQn = -9, /**< Cortex-M33 Secure Fault Interrupt */ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ diff --git a/ameba/amebaG2/source/fwlib/include/ameba_wakepin.h b/ameba/amebag2/source/fwlib/include/ameba_wakepin.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/ameba_wakepin.h rename to ameba/amebag2/source/fwlib/include/ameba_wakepin.h diff --git a/ameba/amebaG2/source/fwlib/include/ameba_wdg.h b/ameba/amebag2/source/fwlib/include/ameba_wdg.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/ameba_wdg.h rename to ameba/amebag2/source/fwlib/include/ameba_wdg.h index f0a83015..0ccd65d3 100644 --- a/ameba/amebaG2/source/fwlib/include/ameba_wdg.h +++ b/ameba/amebag2/source/fwlib/include/ameba_wdg.h @@ -210,4 +210,4 @@ _LONG_CALL_ void WDG_Cmd(WDG_TypeDef *WDG, u32 NewState); /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/basic_types.h b/ameba/amebag2/source/fwlib/include/basic_types.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/basic_types.h rename to ameba/amebag2/source/fwlib/include/basic_types.h diff --git a/ameba/amebaG2/source/fwlib/include/cmsis.h b/ameba/amebag2/source/fwlib/include/cmsis.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/cmsis.h rename to ameba/amebag2/source/fwlib/include/cmsis.h diff --git a/ameba/amebaG2/source/fwlib/include/cmsis_cpu.h b/ameba/amebag2/source/fwlib/include/cmsis_cpu.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/cmsis_cpu.h rename to ameba/amebag2/source/fwlib/include/cmsis_cpu.h diff --git a/ameba/amebaG2/source/fwlib/include/cmsis_ridr.h b/ameba/amebag2/source/fwlib/include/cmsis_ridr.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/cmsis_ridr.h rename to ameba/amebag2/source/fwlib/include/cmsis_ridr.h diff --git a/ameba/amebaG2/source/fwlib/include/hal_platform.h b/ameba/amebag2/source/fwlib/include/hal_platform.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/hal_platform.h rename to ameba/amebag2/source/fwlib/include/hal_platform.h diff --git a/ameba/amebaG2/source/fwlib/include/mpu_config.h b/ameba/amebag2/source/fwlib/include/mpu_config.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/mpu_config.h rename to ameba/amebag2/source/fwlib/include/mpu_config.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/ameba_dump_stack.h b/ameba/amebag2/source/fwlib/include/rom/ameba_dump_stack.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/ameba_dump_stack.h rename to ameba/amebag2/source/fwlib/include/rom/ameba_dump_stack.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/ameba_monitor.h b/ameba/amebag2/source/fwlib/include/rom/ameba_monitor.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/ameba_monitor.h rename to ameba/amebag2/source/fwlib/include/rom/ameba_monitor.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/ameba_rv32_crashdump.h b/ameba/amebag2/source/fwlib/include/rom/ameba_rv32_crashdump.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/ameba_rv32_crashdump.h rename to ameba/amebag2/source/fwlib/include/rom/ameba_rv32_crashdump.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/ameba_shell.h b/ameba/amebag2/source/fwlib/include/rom/ameba_shell.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/ameba_shell.h rename to ameba/amebag2/source/fwlib/include/rom/ameba_shell.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/ameba_v8m_crashdump.h b/ameba/amebag2/source/fwlib/include/rom/ameba_v8m_crashdump.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/ameba_v8m_crashdump.h rename to ameba/amebag2/source/fwlib/include/rom/ameba_v8m_crashdump.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/bootutil_misc.h b/ameba/amebag2/source/fwlib/include/rom/bootutil_misc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/bootutil_misc.h rename to ameba/amebag2/source/fwlib/include/rom/bootutil_misc.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/diag.h b/ameba/amebag2/source/fwlib/include/rom/diag.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/diag.h rename to ameba/amebag2/source/fwlib/include/rom/diag.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/fault_injection_hardening.h b/ameba/amebag2/source/fwlib/include/rom/fault_injection_hardening.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/fault_injection_hardening.h rename to ameba/amebag2/source/fwlib/include/rom/fault_injection_hardening.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/fault_injection_hardening_delay_rng.h b/ameba/amebag2/source/fwlib/include/rom/fault_injection_hardening_delay_rng.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/fault_injection_hardening_delay_rng.h rename to ameba/amebag2/source/fwlib/include/rom/fault_injection_hardening_delay_rng.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/log.h b/ameba/amebag2/source/fwlib/include/rom/log.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/log.h rename to ameba/amebag2/source/fwlib/include/rom/log.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/memproc.h b/ameba/amebag2/source/fwlib/include/rom/memproc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/memproc.h rename to ameba/amebag2/source/fwlib/include/rom/memproc.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/rand.h b/ameba/amebag2/source/fwlib/include/rom/rand.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/rand.h rename to ameba/amebag2/source/fwlib/include/rom/rand.h diff --git a/ameba/amebag2/source/fwlib/include/rom/sscanf_minimal.h b/ameba/amebag2/source/fwlib/include/rom/sscanf_minimal.h new file mode 100644 index 00000000..434ca782 --- /dev/null +++ b/ameba/amebag2/source/fwlib/include/rom/sscanf_minimal.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SSCANF_MINIMAL_H_ +#define _SSCANF_MINIMAL_H_ + +extern int _sscanf_ss(const char *buf, const char *fmt, ...); + +#endif diff --git a/ameba/amebaG2/source/fwlib/include/rom/strproc.h b/ameba/amebag2/source/fwlib/include/rom/strproc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/strproc.h rename to ameba/amebag2/source/fwlib/include/rom/strproc.h diff --git a/ameba/amebaG2/source/fwlib/include/rom/strproc_private.h b/ameba/amebag2/source/fwlib/include/rom/strproc_private.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/rom/strproc_private.h rename to ameba/amebag2/source/fwlib/include/rom/strproc_private.h diff --git a/ameba/amebaG2/source/fwlib/include/section_config.h b/ameba/amebag2/source/fwlib/include/section_config.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/section_config.h rename to ameba/amebag2/source/fwlib/include/section_config.h diff --git a/ameba/amebaG2/source/fwlib/include/sysreg.h b/ameba/amebag2/source/fwlib/include/sysreg.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/sysreg.h rename to ameba/amebag2/source/fwlib/include/sysreg.h diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_aon.h b/ameba/amebag2/source/fwlib/include/sysreg_aon.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_aon.h rename to ameba/amebag2/source/fwlib/include/sysreg_aon.h index 103eebcf..7a67a0dc 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_aon.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_aon.h @@ -662,4 +662,4 @@ /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_cpu_mmu.h b/ameba/amebag2/source/fwlib/include/sysreg_cpu_mmu.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/sysreg_cpu_mmu.h rename to ameba/amebag2/source/fwlib/include/sysreg_cpu_mmu.h diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_ldo.h b/ameba/amebag2/source/fwlib/include/sysreg_ldo.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_ldo.h rename to ameba/amebag2/source/fwlib/include/sysreg_ldo.h index 45a14610..cd43b4e6 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_ldo.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_ldo.h @@ -435,4 +435,4 @@ bool LDO_MemSetInSleep(u8 sleep_mode); /** @} */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_lsys.h b/ameba/amebag2/source/fwlib/include/sysreg_lsys.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/sysreg_lsys.h rename to ameba/amebag2/source/fwlib/include/sysreg_lsys.h diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_mem_ctrl.h b/ameba/amebag2/source/fwlib/include/sysreg_mem_ctrl.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_mem_ctrl.h rename to ameba/amebag2/source/fwlib/include/sysreg_mem_ctrl.h index b24de727..21091c13 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_mem_ctrl.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_mem_ctrl.h @@ -1443,4 +1443,4 @@ /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_pad.h b/ameba/amebag2/source/fwlib/include/sysreg_pad.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_pad.h rename to ameba/amebag2/source/fwlib/include/sysreg_pad.h index 657dffce..aa1030d4 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_pad.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_pad.h @@ -298,4 +298,4 @@ /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_pll.h b/ameba/amebag2/source/fwlib/include/sysreg_pll.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_pll.h rename to ameba/amebag2/source/fwlib/include/sysreg_pll.h index a9d76701..50cc5594 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_pll.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_pll.h @@ -406,4 +406,4 @@ typedef struct { /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_pmc.h b/ameba/amebag2/source/fwlib/include/sysreg_pmc.h similarity index 100% rename from ameba/amebaG2/source/fwlib/include/sysreg_pmc.h rename to ameba/amebag2/source/fwlib/include/sysreg_pmc.h diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_sdm.h b/ameba/amebag2/source/fwlib/include/sysreg_sdm.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_sdm.h rename to ameba/amebag2/source/fwlib/include/sysreg_sdm.h index f8b0c40f..684e94e0 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_sdm.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_sdm.h @@ -134,4 +134,4 @@ typedef struct { /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_sec.h b/ameba/amebag2/source/fwlib/include/sysreg_sec.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_sec.h rename to ameba/amebag2/source/fwlib/include/sysreg_sec.h index f56f4a97..0a3a1a96 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_sec.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_sec.h @@ -614,4 +614,4 @@ /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_swr.h b/ameba/amebag2/source/fwlib/include/sysreg_swr.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_swr.h rename to ameba/amebag2/source/fwlib/include/sysreg_swr.h index d6d83063..4c32d64c 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_swr.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_swr.h @@ -443,4 +443,4 @@ enum SWR_Mode { /* MANUAL_GEN_END */ -#endif \ No newline at end of file +#endif diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_wlafe.h b/ameba/amebag2/source/fwlib/include/sysreg_wlafe.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_wlafe.h rename to ameba/amebag2/source/fwlib/include/sysreg_wlafe.h index 3434abd5..88291f91 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_wlafe.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_wlafe.h @@ -381,4 +381,4 @@ typedef struct { /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/include/sysreg_xtal.h b/ameba/amebag2/source/fwlib/include/sysreg_xtal.h similarity index 99% rename from ameba/amebaG2/source/fwlib/include/sysreg_xtal.h rename to ameba/amebag2/source/fwlib/include/sysreg_xtal.h index 73f1ddc2..11892b0c 100644 --- a/ameba/amebaG2/source/fwlib/include/sysreg_xtal.h +++ b/ameba/amebag2/source/fwlib/include/sysreg_xtal.h @@ -461,4 +461,4 @@ enum xtal_mode_sleep { /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_a2c.c b/ameba/amebag2/source/fwlib/ram_common/ameba_a2c.c similarity index 96% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_a2c.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_a2c.c index d004e1e9..b8bd412f 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_a2c.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_a2c.c @@ -333,7 +333,6 @@ void A2C_WriteMsg(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) u32 a2c_ram_arb = 0; u32 a2c_ram_cmd = 0; u32 a2c_ram_cs = 0; - u32 i; assert_param(IS_A2C_ALL_PERIPH(A2Cx)); assert_param(IS_A2C_FRAME_TYPE(TxMsg->RTR)); @@ -341,7 +340,7 @@ void A2C_WriteMsg(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) assert_param(TxMsg->DLC <= 64); assert_param(TxMsg->MsgBufferIdx <= 15); - /*configure cmd register, enable access*/ + /* Enable Msg buf[x] access*/ a2c_ram_cmd |= (A2C_BIT_RAM_BUFFER_EN | A2C_BIT_RAM_ACC_ARB | A2C_BIT_RAM_ACC_CS | A2C_BIT_RAM_ACC_MASK | \ A2C_BIT_RAM_ACC_DATA_MASK | A2C_BIT_RAM_DIR); a2c_ram_cmd |= TxMsg->MsgBufferIdx; @@ -369,12 +368,12 @@ void A2C_WriteMsg(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) /*fill data, can2.0 8 bytes, can fd 64 bytes*/ if (TxMsg->RTR == A2C_DATA_FRAME) { - for (i = 0; i < 16; i++) { - HAL_WRITE32(&A2Cx->A2C_RAM_FDDATA_x[i], 0, *(u32 *)(&TxMsg->Data[(16 - i - 1) * 4])); + for (int i = 0; i < 16; i++) { + A2Cx->A2C_RAM_FDDATA_x[16 - i - 1] = TxMsg->Data_32[i]; } } - /*finally, operate cmd register to write frame info in register into the ram message buffer*/ + /* Write frame info in register into the ram message buffer */ a2c_ram_cmd |= A2C_BIT_RAM_START; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); @@ -415,12 +414,17 @@ void A2C_SetRxMsgBuf(A2C_TypeDef *A2Cx, A2C_RxMsgTypeDef *RxMsg) /*configure MASK ID register*/ - a2c_ram_mask |= A2C_RAM_ID_MASK(RxMsg->ID_MASK); + if (RxMsg->IDE == A2C_STANDARD_FRAME) { + A2Cx->A2C_RAM_MASK = A2C_RAM_ID_MASK(RxMsg->ID_MASK << 18); + } else { + A2Cx->A2C_RAM_MASK = A2C_RAM_ID_MASK(RxMsg->ID_MASK); + } + a2c_ram_mask |= RxMsg->IDE_Mask; a2c_ram_mask |= RxMsg->RTR_Mask; A2Cx->A2C_RAM_MASK = a2c_ram_mask; - /*finally, operate cmd register to write RX setting info in register into the ram message buffer*/ + /* Write RX setting info in register into the ram message buffer */ a2c_ram_cmd |= A2C_BIT_RAM_START; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); @@ -443,11 +447,12 @@ void A2C_ReadMsg(A2C_TypeDef *A2Cx, A2C_RxMsgTypeDef *RxMsg) assert_param(IS_A2C_ALL_PERIPH(A2Cx)); assert_param(RxMsg->MsgBufferIdx <= 15); - /*configure cmd register, enable access*/ + /* Enable Msg buf[x] access */ a2c_ram_cmd |= (A2C_BIT_RAM_BUFFER_EN | A2C_BIT_RAM_ACC_ARB | A2C_BIT_RAM_ACC_CS | A2C_BIT_RAM_ACC_MASK | A2C_BIT_RAM_ACC_DATA_MASK); a2c_ram_cmd |= RxMsg->MsgBufferIdx; a2c_ram_cmd |= A2C_BIT_RAM_START; - A2Cx->A2C_RAM_CMD = a2c_ram_cmd;/*firstly, operate cmd register to read frame into register from ram message buffer*/ + A2Cx->A2C_RAM_CMD = a2c_ram_cmd; + /* Read frame into register from ram message buffer */ while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); /*read ARB register*/ @@ -488,7 +493,7 @@ void A2C_ReadMsg(A2C_TypeDef *A2Cx, A2C_RxMsgTypeDef *RxMsg) /*configure DATA register: can2.0 8 bytes, can fd 64 bytes*/ if (RxMsg->RTR == A2C_DATA_FRAME) { for (i = 0; i < 16; i++) { - *((u32 *)(&RxMsg->Data[(16 - i - 1) * 4])) = HAL_READ32(&A2Cx->A2C_RAM_FDDATA_x[i], 0); + RxMsg->Data_32[i] = A2Cx->A2C_RAM_FDDATA_x[16 - i - 1]; } } } @@ -512,7 +517,7 @@ void A2C_TxAutoReply(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) assert_param(TxMsg->DLC <= 64); assert_param(TxMsg->MsgBufferIdx <= 15); - /*configure cmd register, enable access*/ + /* Enable Msg buf[x] access */ a2c_ram_cmd |= (A2C_BIT_RAM_BUFFER_EN | A2C_BIT_RAM_ACC_ARB | A2C_BIT_RAM_ACC_CS | A2C_BIT_RAM_ACC_MASK | \ A2C_BIT_RAM_ACC_DATA_MASK | A2C_BIT_RAM_DIR); a2c_ram_cmd |= TxMsg->MsgBufferIdx; @@ -548,7 +553,7 @@ void A2C_TxAutoReply(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) } } - /*finally, operate cmd register to write frame info in register into the ram message buffer*/ + /* Write frame info in register into the ram message buffer*/ a2c_ram_cmd |= A2C_BIT_RAM_START; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); @@ -576,7 +581,6 @@ void A2C_RxAutoReply(A2C_TypeDef *A2Cx, A2C_RxMsgTypeDef *RxMsg) a2c_ram_cmd |= (A2C_BIT_RAM_BUFFER_EN | A2C_BIT_RAM_ACC_ARB | A2C_BIT_RAM_ACC_CS | A2C_BIT_RAM_ACC_MASK | \ A2C_BIT_RAM_ACC_DATA_MASK | A2C_BIT_RAM_DIR); a2c_ram_cmd |= RxMsg->MsgBufferIdx; - //A2Cx->A2C_RAM_CMD = a2c_ram_cmd; /*configure frame ARB register*/ a2c_ram_arb = A2Cx->A2C_RAM_ARB; @@ -607,7 +611,7 @@ void A2C_RxAutoReply(A2C_TypeDef *A2Cx, A2C_RxMsgTypeDef *RxMsg) a2c_ram_mask |= RxMsg->RTR_Mask; A2Cx->A2C_RAM_MASK = a2c_ram_mask; - /*finally, operate cmd register to write RX setting info in register into the ram message buffer*/ + /* Write RX setting into the ram message buffer*/ a2c_ram_cmd |= A2C_BIT_RAM_START; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); @@ -1150,7 +1154,7 @@ void A2C_FillTXDmaBuffer(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) /*configure cmd register, enable access*/ a2c_ram_cmd |= (A2C_BIT_RAM_BUFFER_EN | A2C_BIT_RAM_ACC_ARB | A2C_BIT_RAM_ACC_CS | A2C_BIT_RAM_ACC_MASK | \ - /* A2C_RAM_ACC_DAT_MASK | */ A2C_BIT_RAM_DIR); + A2C_BIT_RAM_ACC_DATA_MASK | A2C_BIT_RAM_DIR); a2c_ram_cmd |= TxMsg->MsgBufferIdx; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; @@ -1179,16 +1183,15 @@ void A2C_FillTXDmaBuffer(A2C_TypeDef *A2Cx, A2C_TxMsgTypeDef *TxMsg) /*fill data, can2.0 8 bytes, can fd 64 bytes*/ if (TxMsg->RTR == A2C_DATA_FRAME) { - for (i = 0; i < 2; i++) { - // A2Cx->A2C_RAM_FDDATA_x[i] = TxMsg->Data[(16 - i - 1) * 4]; - A2Cx->A2C_RAM_FDDATA_x[i] = TxMsg->Data[(2 - i - 1) * 4]; + for (i = 0; i < 16; i++) { + A2Cx->A2C_RAM_FDDATA_x[16 - i - 1] = TxMsg->Data_32[i]; } } - /*finally, operate cmd register to write frame info in register into the ram message buffer*/ + /* Write frame info into the ram message buffer*/ a2c_ram_cmd |= A2C_BIT_RAM_START; A2Cx->A2C_RAM_CMD = a2c_ram_cmd; - //while(A2CxBufer->A2C_RAM_CMD&A2C_BIT_RAM_START); + while (A2Cx->A2C_RAM_CMD & A2C_BIT_RAM_START); } @@ -1221,4 +1224,4 @@ void A2C_RamBufferMapConfig(A2C_TypeDef *A2Cx, u32 *pPara) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_adc.c b/ameba/amebag2/source/fwlib/ram_common/ameba_adc.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_adc.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_adc.c index 4f849216..bd3fafb0 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_adc.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_adc.c @@ -905,4 +905,4 @@ u32 ADC_GetSampleValue(s32 VolMV) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_aontimer.c b/ameba/amebag2/source/fwlib/ram_common/ameba_aontimer.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_aontimer.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_aontimer.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_arch.c b/ameba/amebag2/source/fwlib/ram_common/ameba_arch.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_arch.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_arch.c index eb6c3d76..0f27540f 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_arch.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_arch.c @@ -156,4 +156,3 @@ void irq_enable_restore(u32 PrevStatus) { __set_PRIMASK(PrevStatus); } - diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_audio_clock.c b/ameba/amebag2/source/fwlib/ram_common/ameba_audio_clock.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_audio_clock.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_audio_clock.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_bor.c b/ameba/amebag2/source/fwlib/ram_common/ameba_bor.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_bor.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_bor.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_captouch.c b/ameba/amebag2/source/fwlib/ram_common/ameba_captouch.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_captouch.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_captouch.c index 7675e823..a136b8dc 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_captouch.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_captouch.c @@ -1175,4 +1175,4 @@ u8 CapTouch_RXGDMA_Init( /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_clk.c b/ameba/amebag2/source/fwlib/ram_common/ameba_clk.c similarity index 94% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_clk.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_clk.c index e192f36d..95a437b6 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_clk.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_clk.c @@ -15,9 +15,14 @@ void SDM32K_Enable(void) { SDM_TypeDef *SDM = SDM_DEV; + u32 temp = SDM->SDM_CTRL0; SDM->SDM_TIMEOUT = SDM_TIEMRCAL_INTERVAL_1MIN; - SDM->SDM_CTRL0 |= SDM_BIT_EN | SDM_BIT_RST | SDM_BIT_ALWAYS_CAL_EN | SDM_BIT_TIMER_CAL_EN; + temp |= SDM_BIT_EN | SDM_BIT_RST | SDM_BIT_ALWAYS_CAL_EN | SDM_BIT_TIMER_CAL_EN; + + /*Switch sdm32k mode from user_defined parameter mode to default mode.*/ + temp &= ~SDM_BIT_MOD_SEL; + SDM->SDM_CTRL0 = temp; } /** @@ -38,6 +43,32 @@ void SDM32K_TimerCalEnable(u32 newstatus) } } +/** + * @brief 32K clock calibration factor modify + * @param newstatus: can be one of the following values: + * @arg ENABLE + * @arg FALSE + * @note + * From HW Experiment, add 3 to SDM_OBS_REF_CYC(default 312500) + */ +void SDM32K_CalFactorModify(u32 newstatus) +{ + SDM_TypeDef *SDM = SDM_DEV; + u32 temp = 0; + + if (newstatus == ENABLE) { + SDM->SDM_CTRL1 = SDM_OBS_CYC_DEFAULT; + SDM->SDM_CTRL2 = SDM_OBS_REF_CYC_MODIFY; + SDM->SDM_CTRL3 = SDM_XTAL_PERIOD_DEFAULT; + temp = SDM->SDM_CTRL0 | SDM_BIT_MOD_SEL; + SDM->SDM_CTRL0 = temp; + } else { + temp = SDM->SDM_CTRL0 & ~SDM_BIT_MOD_SEL; + SDM->SDM_CTRL0 = temp; + } + +} + /** * @brief Get osc calibration result. * @param Option: can be one of the following values: diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_codec.c b/ameba/amebag2/source/fwlib/ram_common/ameba_codec.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_codec.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_codec.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_flash_ram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_flash_ram.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_flash_ram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_flash_ram.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_gdma_memcpy.c b/ameba/amebag2/source/fwlib/ram_common/ameba_gdma_memcpy.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_gdma_memcpy.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_gdma_memcpy.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_gdma_ram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_gdma_ram.c similarity index 97% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_gdma_ram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_gdma_ram.c index cc5bc757..99aab93f 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_gdma_ram.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_gdma_ram.c @@ -600,9 +600,9 @@ u32 GDMA_GetBlkSize(u8 GDMA_Index, u8 GDMA_ChNum) /* Check the parameters */ assert_param(IS_GDMA_Index(GDMA_Index)); assert_param(IS_GDMA_ChannelNum(GDMA_ChNum)); - /* block size = DSRx_H(high 5 bit) + SGRx_H(Low 16 bit)*/ - BlkSize = (GDMA_GET_DSRx_H_BLOCK_TS_H(GDMA->CH[GDMA_ChNum].GDMA_DSRx_H) << 16) + GDMA_GET_SGRx_H_BLOCK_TS_L(GDMA->CH[GDMA_ChNum].GDMA_SGRx_H); - return BlkSize; + + BlkSize = GDMA->CH[GDMA_ChNum].GDMA_CTLx_H; + return BlkSize; } /** @@ -931,7 +931,30 @@ void GDMA_DestinationScatter(u8 GDMA_Index, u8 GDMA_ChNum, u32 Dst_ScatterCount, GDMA->CH[GDMA_ChNum].GDMA_CTLx_L |= GDMA_BIT_CTLx_L_DST_SCATTER_EN; GDMA->CH[GDMA_ChNum].GDMA_DSRx_L = GDMA_DSRx_L_DSC(Dst_ScatterCount) | GDMA_DSRx_L_DSI(Dst_ScatterInterval); } +/** + * @brief Check if the channel is active + * + * @param GDMA_Index 0 + * @param GDMA_ChNum 0 ~ 7 + * @retval TRUE/FALSE + */ +__weak +u8 GDMA_ChannelIsActive(u8 GDMA_Index, u8 GDMA_ChNum) +{ + GDMA_TypeDef *GDMA = ((GDMA_TypeDef *) GDMA_BASE); + if (TrustZone_IsSecure()) { + GDMA = ((GDMA_TypeDef *) GDMA0_REG_BASE_S); + } + /* Check the parameters */ + assert_param(IS_GDMA_Index(GDMA_Index)); + assert_param(IS_GDMA_ChannelNum(GDMA_ChNum)); + if ((GDMA_GET_CHENREG_L_1_CH_EN(GDMA->GDMA_CHENREG_L_1) & BIT(GDMA_ChNum)) && \ + ((GDMA->CH[GDMA_ChNum].GDMA_CFGx_L & GDMA_BIT_CFGx_L_INACTIVE) == 0)) { + return TRUE; + } + return FALSE; +} /** * @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_gpio_ram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_gpio_ram.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_gpio_ram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_gpio_ram.c index 9c7d039c..e6c6e975 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_gpio_ram.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_gpio_ram.c @@ -179,4 +179,4 @@ void GPIO_UserUnRegIrq(u32 GPIO_Pin) /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_i2c.c b/ameba/amebag2/source/fwlib/ram_common/ameba_i2c.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_i2c.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_i2c.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_api.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ipc_api.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_api.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ipc_api.c index 26496028..65004c0a 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_api.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_ipc_api.c @@ -180,4 +180,4 @@ PIPC_MSG_STRUCT ipc_get_message(u32 IPC_Dir, u8 IPC_ChNum) DCache_Invalidate((u32)&IPC_MSG[msg_idx], sizeof(IPC_MSG_STRUCT)); return &IPC_MSG[msg_idx]; -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_ram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ipc_ram.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_ram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ipc_ram.c index 1008ef60..5bc4968b 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_ipc_ram.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_ipc_ram.c @@ -196,4 +196,4 @@ IPC_TypeDef *IPC_GetDevById(u32 cpu_id) } else { return IPCNP_DEV; } -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ir.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ir.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ir.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ir.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_lcdc.c b/ameba/amebag2/source/fwlib/ram_common/ameba_lcdc.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_lcdc.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_lcdc.c index d8b103a0..ac3a4684 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_lcdc.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_lcdc.c @@ -1197,4 +1197,4 @@ void LCDC_MCUCtrlSwap(LCDC_TypeDef *LCDCx, u8 Status) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ldo.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ldo.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ldo.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ldo.c index 26b82f46..116d143e 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_ldo.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_ldo.c @@ -84,4 +84,4 @@ bool LDO_MemSetInSleep(u8 sleep_mode) HAL_WRITE32(PMC_BASE, AIP_TRIGGER, Rtemp); ret = TRUE; return ret; -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_loguart.c b/ameba/amebag2/source/fwlib/ram_common/ameba_loguart.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_loguart.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_loguart.c index d65b93a8..045c87e6 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_loguart.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_loguart.c @@ -259,4 +259,4 @@ void LOGUART_PutChar_RAM(u8 c) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_mpu_ram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_mpu_ram.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_mpu_ram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_mpu_ram.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_pll.c b/ameba/amebag2/source/fwlib/ram_common/ameba_pll.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_pll.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_pll.c index 4b97dac0..cb41ff25 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_pll.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_pll.c @@ -393,3 +393,5 @@ void RCC_PeriphClockSource_SPORT(AUDIO_SPORT_TypeDef *Sportx, u32 Source) RTK_LOGE(TAG, "invaild clk source!!!"); } } + +/******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_pmc_com.c b/ameba/amebag2/source/fwlib/ram_common/ameba_pmc_com.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_pmc_com.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_pmc_com.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_pmctimer.c b/ameba/amebag2/source/fwlib/ram_common/ameba_pmctimer.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_pmctimer.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_pmctimer.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_pmu.c b/ameba/amebag2/source/fwlib/ram_common/ameba_pmu.c similarity index 84% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_pmu.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_pmu.c index b61b6313..b134f6fa 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_pmu.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_pmu.c @@ -7,7 +7,7 @@ #include "platform_autoconf.h" #include "ameba_soc.h" -uint32_t missing_tick = 0; +uint32_t cur_device_id = 0; static uint32_t wakelock = DEFAULT_WAKELOCK; static uint32_t sleep_type = SLEEP_PG; /* 0 is power gate, 1 is clock gate */ @@ -45,7 +45,7 @@ uint32_t pmu_exec_sleep_hook_funs(void) return nDeviceIdOffset; } -void pmu_exec_wakeup_hook_funs(uint32_t nDeviceIdMax) +void pmu_exec_wakeup_hook_funs(uint32_t nDeviceIdMax, uint32_t common_param) { PSM_DD_HOOK_INFO *pPsmDdHookInfo = NULL; uint32_t nDeviceIdOffset = 0; @@ -55,7 +55,7 @@ void pmu_exec_wakeup_hook_funs(uint32_t nDeviceIdMax) /*if this device register and sleep_hook_fun not NULL*/ if (pPsmDdHookInfo && pPsmDdHookInfo->wakeup_hook_fun) { - pPsmDdHookInfo->wakeup_hook_fun(0, pPsmDdHookInfo->wakeup_param_ptr); + pPsmDdHookInfo->wakeup_hook_fun(common_param, pPsmDdHookInfo->wakeup_param_ptr); } } } @@ -65,7 +65,13 @@ uint32_t pmu_set_sysactive_time(uint32_t timeout) uint32_t New_Cnt = 0; PMCTIMER_TpyeDef *PMC_TIMER = PMC_TIMER_DEV; - New_Cnt = (u32)((((u64)timeout) << 15) / 1000); /*convert ms to cnt*/ + /*convert ms to cnt: + method: the ticks/ms equals 32 + 197/256 = 32.7695, and the deviation is 32.7695 - 32.768 = 0.0046%. + The error is 46µs per second.The reason for using bit shift operations is to avoid division and + improve the speed of operation. + */ + New_Cnt = (timeout << 5) + (((timeout << 7) + (timeout << 6) + (timeout << 2) + timeout) >> 8); + PMCTimerCnt_Set(PMC_TIMER, PMC_SLEEP_TIMER, New_Cnt); return 0; @@ -218,13 +224,19 @@ void pmu_pre_sleep_processing(uint32_t *tick_before_sleep) #endif sleep_param.dlps_enable = DISABLE; } - /* Store gtimer timestamp before sleep */ *tick_before_sleep = SYSTIMER_TickGet(); /*Disable systick interrupt to avoid interrupting sleep flow*/ Systick_Cmd(DISABLE); + /* exec sleep hook functions */ + cur_device_id = pmu_exec_sleep_hook_funs(); + + if (cur_device_id != PMU_MAX) { + RTK_LOGS(NOTAG, RTK_LOG_ALWAYS, "Sleep blocked because Dev %x busy\n", cur_device_id); + return; + } -#if defined(CONFIG_WIFI_HOST_CONTROL) +#if (!defined (CONFIG_WHC_INTF_IPC) && defined (CONFIG_WHC_DEV)) SOCPS_Sleep_FULLMAC(sleep_type); #else if (sleep_type == SLEEP_PG) { @@ -233,7 +245,6 @@ void pmu_pre_sleep_processing(uint32_t *tick_before_sleep) SOCPS_SleepCG(); } #endif - Systick_Cmd(ENABLE); } /* -------- FreeRTOS macro implementation -------- */ @@ -313,7 +324,7 @@ u32 pmc_wakeuptimer_int_hdl(void *Data) void pmu_init_wakeup_timer(void) { - InterruptRegister(pmc_wakeuptimer_int_hdl, PMC_TIMER_IRQ, (uint32_t)NULL, PMC_TIMER_INT_PRIO); + InterruptRegister(pmc_wakeuptimer_int_hdl, PMC_TIMER_IRQ, 0, PMC_TIMER_INT_PRIO); InterruptEn(PMC_TIMER_IRQ, PMC_TIMER_INT_PRIO); PMCTimer_INTConfig(PMC_TIMER_DEV, PMC_WAKEUP_TIMER, ENABLE); } @@ -322,8 +333,12 @@ void pmu_set_wakeup_timer(uint32_t timeout_ms) { uint32_t timeout_cnt = 0; PMCTIMER_TpyeDef *PMC_TIMER = PMC_TIMER_DEV; - - timeout_cnt = (timeout_ms << 15) / 1000; /*convert ms to cnt*/ + /*convert ms to cnt: + method: the ticks/ms equals 32 + 197/256 = 32.7695, and the deviation is 32.7695 - 32.768 = 0.0046%. + The error is 46µs per second.The reason for using bit shift operations is to avoid division and + improve the speed of operation. + */ + timeout_cnt = (timeout_ms << 5) + (((timeout_ms << 7) + (timeout_ms << 6) + (timeout_ms << 2) + timeout_ms) >> 8); PMCTimerCnt_Set(PMC_TIMER, PMC_WAKEUP_TIMER, timeout_cnt); } @@ -340,7 +355,13 @@ void pmu_set_dsleep_active_time(uint32_t TimeOutMs) uint32_t New_Cnt = 0; PMCTIMER_TpyeDef *PMC_TIMER = PMC_TIMER_DEV; - New_Cnt = (TimeOutMs << 15) / 1000; /*convert ms to cnt*/ + /*convert ms to cnt: + method: the ticks/ms equals 32 + 197/256 = 32.7695, and the deviation is 32.7695 - 32.768 = 0.0046%. + The error is 46µs per second.The reason for using bit shift operations is to avoid division and + improve the speed of operation. + */ + New_Cnt = (TimeOutMs << 5) + (((TimeOutMs << 7) + (TimeOutMs << 6) + (TimeOutMs << 2) + TimeOutMs) >> 8); + PMCTimerCnt_Set(PMC_TIMER, PMC_DSLP_TIMER, New_Cnt); } diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ppe.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ppe.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ppe.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ppe.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_pseduo_i2c.c b/ameba/amebag2/source/fwlib/ram_common/ameba_pseduo_i2c.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_pseduo_i2c.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_pseduo_i2c.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_psram.c b/ameba/amebag2/source/fwlib/ram_common/ameba_psram.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_psram.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_psram.c index 7559e942..fd1a99b6 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_psram.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_psram.c @@ -22,8 +22,8 @@ u8 WB_WR_INIT_LATENCY_SPEC[8] = { WB_WR_INIT_LATENCY_5CLK, WB_WR_INIT_LATENCY_6CLK, WB_WR_INIT_LATENCY_7CLK, - NULL, - NULL, + 0, //NULL, + 0, //NULL, WB_WR_INIT_LATENCY_10CLK }; diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_rcc.c b/ameba/amebag2/source/fwlib/ram_common/ameba_rcc.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_rcc.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_rcc.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_reset.c b/ameba/amebag2/source/fwlib/ram_common/ameba_reset.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_reset.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_reset.c index 47a6916b..6738e0a5 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_reset.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_reset.c @@ -203,4 +203,4 @@ void System_Reset(void) /* wait for reset */ while (1); -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_rtc.c b/ameba/amebag2/source/fwlib/ram_common/ameba_rtc.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_rtc.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_rtc.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_sd.c b/ameba/amebag2/source/fwlib/ram_common/ameba_sd.c similarity index 98% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_sd.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_sd.c index b5592890..2e48edd8 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_sd.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_sd.c @@ -27,7 +27,6 @@ static u32 SD_WideBus_Disable(SD_HdlTypeDef *hsd); static u32 SD_GetCardSCR(SD_HdlTypeDef *hsd); static void SD_Write_IT(SD_HdlTypeDef *hsd); static void SD_Read_IT(SD_HdlTypeDef *hsd); -static u32 SD_IRQHandler(void *pData); static u8 is_timeout(u32 start_us, u32 timeout_us) { @@ -128,7 +127,7 @@ static void SDIOH_Pinmux(void) } } -static void SD_PreDMATrans(SD_HdlTypeDef *hsd) +void SD_PreDMATrans(SD_HdlTypeDef *hsd) { if ((CPU_InInterrupt() == 0) && (rtos_sched_get_state() == RTOS_SCHED_RUNNING) && (sd_sema_take_fn != NULL)) { wait_for_sema = 1; @@ -274,7 +273,7 @@ SD_RESULT SD_Init(void) /* Wait until func1 is ready */ while (1) { - ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_IORDY, NULL, &val); + ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_IORDY, (u8)0x0, &val); if (ret != SD_OK) { return SD_ERROR; } @@ -470,10 +469,12 @@ static SD_RESULT SD_InitCard(SD_HdlTypeDef *hsd) /* Send CMD3 SET_REL_ADDR with argument 0 */ /* CMD3: SD Card publishes its RCA. */ - errorstate = SDMMC_CmdSetRelAdd(SDIOx, &sd_rca); + errorstate = SDMMC_CmdSetRelAdd(SDIOx); if (errorstate != SD_ERROR_NONE) { hsd->ErrorCode |= errorstate; return SD_ERROR; + } else { + sd_rca = SDIO_GetResponse(SDIOx, SDIO_RESP0) >> 16; } /* Get the SD card RCA */ @@ -1733,7 +1734,7 @@ __weak void SD_IRQ_NOTIFY(void) * @param hsd: Pointer to SD handle * @retval None */ -static u32 SD_IRQHandler(void *pData) +u32 SD_IRQHandler(void *pData) { SD_HdlTypeDef *hsd = (SD_HdlTypeDef *)pData; SDIOHOST_TypeDef *SDIOx = hsd->Instance; @@ -2106,7 +2107,7 @@ static SD_RESULT SD_SendSDStatus(SD_HdlTypeDef *hsd, u32 *pSDstatus) /* Configure the SD DPSM (Data Path State Machine) */ config.TransType = SDIO_TRANS_SINGLE_BLK; config.TransDir = SDIO_TRANS_CARD_TO_HOST; - config.BlockSize = 512U; + config.BlockSize = 64U; // 512bit/8 config.BlockCnt = 1U; // DON'T CARE config.AutoCmdEn = SDIO_TRANS_AUTO_DIS; config.DmaEn = SDIO_TRANS_DMA_DIS; @@ -2319,7 +2320,7 @@ SD_RESULT SD_ConfigBusSpeed(SD_HdlTypeDef *hsd, u8 BusSpeed) if (BusSpeed == SD_SPEED_HS) { if (hsd->Card.CardType == CARD_SDIO_ONLY) { - ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_SPEED_CONTROL, NULL, &val); + ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_SPEED_CONTROL, (u8)0x0, &val); if (ret != SD_OK) { return ret; } @@ -2348,7 +2349,7 @@ SD_RESULT SD_ConfigBusSpeed(SD_HdlTypeDef *hsd, u8 BusSpeed) } } else if (BusSpeed == SD_SPEED_DS) { if (hsd->Card.CardType == CARD_SDIO_ONLY) { - ret = SD_IO_RW_Direct(hsd, BUS_WRITE, SDIO_FUNC0, SDIOD_CCCR_SPEED_CONTROL, 0x0, &val); + ret = SD_IO_RW_Direct(hsd, BUS_WRITE, SDIO_FUNC0, SDIOD_CCCR_SPEED_CONTROL, (u8)0x0, &val); if (ret != SD_OK) { return ret; } @@ -2453,7 +2454,7 @@ static u32 SD_WideBus_Enable(SD_HdlTypeDef *hsd) if (hsd->Card.CardType == CARD_SDIO_ONLY) { - ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_BICTRL, NULL, &val); + ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_BICTRL, (u8)0x0, &val); if (ret != SD_OK) { return SD_ERROR; } @@ -2506,7 +2507,7 @@ static u32 SD_WideBus_Disable(SD_HdlTypeDef *hsd) if (hsd->Card.CardType == CARD_SDIO_ONLY) { - ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_BICTRL, NULL, &val); + ret = SD_IO_RW_Direct(hsd, BUS_READ, SDIO_FUNC0, SDIOD_CCCR_BICTRL, (u8)0x0, &val); if (ret != SD_OK) { return SD_ERROR; } @@ -2550,10 +2551,8 @@ static u32 SD_GetCardSCR(SD_HdlTypeDef *hsd) SDIOHOST_TypeDef *SDIOx = hsd->Instance; SDIO_DataInitTypeDef config; u32 errorstate; - u32 tickstart = DTimestamp_Get(); - u32 index = 0U; - u32 tempscr[2U] = {0U, 0U}; - u32 dataremaining; + /* 32byte for cache operation, only the first 2bytes are valid */ + u32 tempscr[8]__attribute__((aligned(32))) = {0U}; // avoid crc_err_sts is set during ACMD51 SDIO_ConfigErrIntSts(SDIOx, SDIOHOST_BIT_DATA_CRC_ERR_STATUS_EN, DISABLE); @@ -2569,35 +2568,30 @@ static u32 SD_GetCardSCR(SD_HdlTypeDef *hsd) config.BlockSize = 8U; // 64bit/8 config.BlockCnt = 0U; // DON'T CARE when TRANS_SINGLE_BLK config.AutoCmdEn = SDIO_TRANS_AUTO_DIS; - config.DmaEn = SDIO_TRANS_DMA_DIS; + config.DmaEn = SDIO_TRANS_DMA_EN; SDIO_ConfigData(SDIOx, &config); + errorstate = SDIO_ConfigDMA(SDIOx, SDIO_SDMA_MODE, (u32)tempscr); + if (errorstate != HAL_OK) { + hsd->ErrorCode |= SD_ERROR_INVALID_PARAMETER; + hsd->State = SD_STATE_READY; + return SD_ERROR; + } + SD_PreDMATrans(hsd); + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ errorstate = SDMMC_CmdSendSCR(SDIOx); if (errorstate != SD_ERROR_NONE) { return errorstate; } - dataremaining = 8U; // size of SCR: 8Bytes - - /* SDIOHOST_BIT_XFER_COMPLETE will not be set under this case */ - while (!((SDIO_GetErrSts(SDIOx) & SDIO_DAT_ERR))) { - - if (dataremaining == 0U) { - break; - } - - if ((SDIO_GetStatus(SDIOx) & SDIOHOST_BIT_BUFF_READ_EN) && (dataremaining > 0U)) { - *(tempscr + index) = SDIO_ReadFIFO(SDIOx); - index++; - dataremaining -= 4U; - } - - if (is_timeout(tickstart, SDMMC_DAT_TIMEOUT)) { - return SD_ERROR_TIMEOUT; - } + if (SD_WaitTransDone(hsd, SDMMC_DAT_TIMEOUT) != HAL_OK) { + RTK_LOGE(TAG, "%s WaitTransDone error!\n", __FUNCTION__); + return SD_ERROR; } + DCache_Invalidate((u32)tempscr, sizeof(tempscr)); + if (SDIO_GetErrSts(SDIOx) & SDIOHOST_BIT_DATA_TIMEOUT_ERR) { SDIO_ClearErrSts(SDIOx, SDIOHOST_BIT_DATA_TIMEOUT_ERR); return SD_ERROR_DATA_TIMEOUT; diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_sd_host.c b/ameba/amebag2/source/fwlib/ram_common/ameba_sd_host.c similarity index 70% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_sd_host.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_sd_host.c index da852047..3564fa55 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_sd_host.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_sd_host.c @@ -476,7 +476,7 @@ u32 SDIO_CmdSendOpCond(SDIOHOST_TypeDef *SDIOx, u32 Ocr) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp4(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -494,7 +494,7 @@ u32 SDIO_CmdRWDirect(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp5(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -512,7 +512,7 @@ u32 SDIO_CmdRWExtended(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp5(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -665,7 +665,7 @@ u32 SDMMC_CmdBlockLength(SDIOHOST_TypeDef *SDIOx, u32 BlockSize) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -689,7 +689,7 @@ u32 SDMMC_CmdReadSingleBlock(SDIOHOST_TypeDef *SDIOx, u32 ReadAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -713,7 +713,7 @@ u32 SDMMC_CmdReadMultiBlock(SDIOHOST_TypeDef *SDIOx, u32 ReadAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -737,7 +737,7 @@ u32 SDMMC_CmdWriteSingleBlock(SDIOHOST_TypeDef *SDIOx, u32 WriteAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -761,7 +761,7 @@ u32 SDMMC_CmdWriteMultiBlock(SDIOHOST_TypeDef *SDIOx, u32 WriteAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -785,7 +785,7 @@ u32 SDMMC_CmdSDEraseStartAdd(SDIOHOST_TypeDef *SDIOx, u32 StartAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -809,7 +809,7 @@ u32 SDMMC_CmdSDEraseEndAdd(SDIOHOST_TypeDef *SDIOx, u32 EndAdd) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -834,7 +834,7 @@ u32 SDMMC_CmdErase(SDIOHOST_TypeDef *SDIOx, u32 BlockCnt) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1B(SDIOx, SDMMC_ERASE_TIMEOUT * BlockCnt); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_ERASE_TIMEOUT * BlockCnt); return errorstate; } @@ -858,7 +858,7 @@ u32 SDMMC_CmdStopTransfer(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1B(SDIOx, SDMMC_STOP_TRANS_TIMEOUT); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_STOP_TRANS_TIMEOUT); return errorstate; } @@ -888,11 +888,7 @@ u32 SDMMC_CmdSelDesel(SDIOHOST_TypeDef *SDIOx, u32 Addr) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - if (Addr != 0x0) { - errorstate = SDMMC_GetCmdResp1B(SDIOx, SDMMC_DAT_TIMEOUT); - } else { - errorstate = SDMMC_GetCmdResp1(SDIOx); - } + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_DAT_TIMEOUT); return errorstate; } @@ -915,7 +911,7 @@ u32 SDMMC_CmdGoIdleState(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdError(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -943,7 +939,7 @@ u32 SDMMC_CmdOperCond(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp7(SDIOx); // R7 + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -972,7 +968,7 @@ u32 SDMMC_CmdAppCommand(SDIOHOST_TypeDef *SDIOx, u32 Argument) /* If there is a HAL_ERR_PARA, it is a MMC card, else it is a SD card: SD card 2.0 (voltage range mismatch) or SD card 1.x */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -989,7 +985,7 @@ u32 SDMMC_CmdAppOperCommand(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_CmdInitTypeDef sdmmc_cmdinit; u32 errorstate; - sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | Argument; + sdmmc_cmdinit.Argument = Argument; sdmmc_cmdinit.CmdIndex = SDMMC_APP_OP_COND; // ACMD41(CMD55 + CMD41) sdmmc_cmdinit.CmdType = SDMMC_CMD_NORMAL; sdmmc_cmdinit.RespType = SDMMC_RSP_R3; @@ -997,7 +993,7 @@ u32 SDMMC_CmdAppOperCommand(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp3(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1021,7 +1017,7 @@ u32 SDMMC_CmdBusWidth(SDIOHOST_TypeDef *SDIOx, u32 BusWidth) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1045,7 +1041,7 @@ u32 SDMMC_CmdSetWrBlkEraseCnt(SDIOHOST_TypeDef *SDIOx, u32 BlockCnt) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1069,7 +1065,7 @@ u32 SDMMC_CmdSendSCR(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1093,7 +1089,7 @@ u32 SDMMC_CmdSendCID(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp2(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1118,7 +1114,7 @@ u32 SDMMC_CmdSendCSD(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp2(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1129,7 +1125,7 @@ u32 SDMMC_CmdSendCSD(SDIOHOST_TypeDef *SDIOx, u32 Argument) * @param pRCA: Card RCA * @retval HAL status */ -u32 SDMMC_CmdSetRelAdd(SDIOHOST_TypeDef *SDIOx, u16 *pRCA) +u32 SDMMC_CmdSetRelAdd(SDIOHOST_TypeDef *SDIOx) { SDIO_CmdInitTypeDef sdmmc_cmdinit; u32 errorstate; @@ -1143,7 +1139,7 @@ u32 SDMMC_CmdSetRelAdd(SDIOHOST_TypeDef *SDIOx, u16 *pRCA) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp6(SDIOx, pRCA); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1167,7 +1163,7 @@ u32 SDMMC_CmdSendStatus(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1190,7 +1186,7 @@ u32 SDMMC_CmdStatusRegister(SDIOHOST_TypeDef *SDIOx) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } @@ -1217,213 +1213,194 @@ u32 SDMMC_CmdSwitch(SDIOHOST_TypeDef *SDIOx, u32 Argument) SDIO_SendCommand(SDIOx, &sdmmc_cmdinit); /* Check for error conditions */ - errorstate = SDMMC_GetCmdResp1(SDIOx); + errorstate = SDIO_WaitResp(SDIOx, sdmmc_cmdinit.RespType, SDMMC_CMD_TIMEOUT); return errorstate; } /** - * @brief Checks for error conditions for CMD0. + * @brief Checks for error conditions after sending CMD. * @param SDIOx Pointer to SDIO host + * @param RespType Response type, which can be a value of @ref SDIO_LL_Response_Type. + * @param TimeOutUs Timeout value in us. * @retval SD Card error state */ -u32 SDMMC_GetCmdError(SDIOHOST_TypeDef *SDIOx) +u32 SDIO_WaitResp(SDIOHOST_TypeDef *SDIOx, u8 RespType, u32 TimeOutUs) { + u32 response_r0; u32 count = 0; + u32 norm_int, err_int; - while (!(SDIO_GetNormSts(SDIOx) & SDIOHOST_BIT_CMD_COMPLETE)) { - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); + assert_param(IS_SD_RESP_TYPE(RespType)); - return SD_ERROR_NONE; -} + switch (RespType) { + case SDMMC_RSP_R1: + case SDMMC_RSP_R2: + case SDMMC_RSP_R3: + case SDMMC_RSP_R4: + case SDMMC_RSP_R5: + case SDMMC_RSP_R6: + case SDMMC_RSP_R7: + while (1) { + norm_int = SDIO_GetNormSts(SDIOx); + err_int = SDIO_GetErrSts(SDIOx); -/** - * @brief Checks for error conditions for R1 response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp1(SDIOHOST_TypeDef *SDIOx) -{ - u32 response_r0; - u32 count = 0; - u32 norm_int, err_int; + if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { + break; + } - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); + if (count++ >= TimeOutUs) { + RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); + return SD_ERROR_TIMEOUT; + } - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; + /* exit while-loop ASAP */ + DelayUs(1); } - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; + if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { + SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); } - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } + if (err_int & SDIO_CMD_ERR) { + if (RespType == SDMMC_RSP_R7) { + DelayUs(10); // avoid cmd_err sts is set again after clear + } + SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); + if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { + return SD_ERROR_CMD_RSP_TIMEOUT; + } else { + return SD_ERROR_GENERAL_UNKNOWN_ERR; + } + } - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; + if (RespType == SDMMC_RSP_R2 || RespType == SDMMC_RSP_R3 || RespType == SDMMC_RSP_R4 || RespType == SDMMC_RSP_R7) { + return SD_ERROR_NONE; } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; + response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); + if (RespType == SDMMC_RSP_R1) { + return SDMMC_CheckErrResp1(response_r0); + } else if (RespType == SDMMC_RSP_R5) { + return SDMMC_CheckErrResp5(response_r0); + } else if (RespType == SDMMC_RSP_R6) { + return SDMMC_CheckErrResp6(response_r0); + } } - } - - /* We have received response, retrieve it for analysis */ - response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); + break; + case SDMMC_RSP_R1B: + case SDMMC_RSP_R5B: + while (1) { + norm_int = SDIO_GetNormSts(SDIOx); + err_int = SDIO_GetErrSts(SDIOx); - if ((response_r0 & SDMMC_R1_ERRORBITS) == SDMMC_ALLZERO) { - return SD_ERROR_NONE; - } else if ((response_r0 & SDMMC_R1_ADDR_OUT_OF_RANGE) == SDMMC_R1_ADDR_OUT_OF_RANGE) { - return SD_ERROR_ADDR_OUT_OF_RANGE; - } else if ((response_r0 & SDMMC_R1_ADDR_MISALIGNED) == SDMMC_R1_ADDR_MISALIGNED) { - return SD_ERROR_ADDR_MISALIGNED; - } else if ((response_r0 & SDMMC_R1_BLOCK_LEN_ERR) == SDMMC_R1_BLOCK_LEN_ERR) { - return SD_ERROR_BLOCK_LEN_ERR; - } else if ((response_r0 & SDMMC_R1_ERASE_SEQ_ERR) == SDMMC_R1_ERASE_SEQ_ERR) { - return SD_ERROR_ERASE_SEQ_ERR; - } else if ((response_r0 & SDMMC_R1_BAD_ERASE_PARAM) == SDMMC_R1_BAD_ERASE_PARAM) { - return SD_ERROR_BAD_ERASE_PARAM; - } else if ((response_r0 & SDMMC_R1_WRITE_PROT_VIOLATION) == SDMMC_R1_WRITE_PROT_VIOLATION) { - return SD_ERROR_WRITE_PROT_VIOLATION; - } else if ((response_r0 & SDMMC_R1_LOCK_UNLOCK_FAILED) == SDMMC_R1_LOCK_UNLOCK_FAILED) { - return SD_ERROR_LOCK_UNLOCK_FAILED; - } else if ((response_r0 & SDMMC_R1_COM_CRC_FAILED) == SDMMC_R1_COM_CRC_FAILED) { - return SD_ERROR_COM_CRC_FAILED; - } else if ((response_r0 & SDMMC_R1_ILLEGAL_CMD) == SDMMC_R1_ILLEGAL_CMD) { - return SD_ERROR_ILLEGAL_CMD; - } else if ((response_r0 & SDMMC_R1_CARD_ECC_FAILED) == SDMMC_R1_CARD_ECC_FAILED) { - return SD_ERROR_CARD_ECC_FAILED; - } else if ((response_r0 & SDMMC_R1_CC_ERROR) == SDMMC_R1_CC_ERROR) { - return SD_ERROR_CC_ERR; - } else if ((response_r0 & SDMMC_R1_STREAM_READ_UNDERRUN) == SDMMC_R1_STREAM_READ_UNDERRUN) { - return SD_ERROR_STREAM_READ_UNDERRUN; - } else if ((response_r0 & SDMMC_R1_STREAM_WRITE_OVERRUN) == SDMMC_R1_STREAM_WRITE_OVERRUN) { - return SD_ERROR_STREAM_WRITE_OVERRUN; - } else if ((response_r0 & SDMMC_R1_CID_CSDMMC_OVERWRITE) == SDMMC_R1_CID_CSDMMC_OVERWRITE) { - return SD_ERROR_CID_CSDMMC_OVERWRITE; - } else if ((response_r0 & SDMMC_R1_WP_ERASE_SKIP) == SDMMC_R1_WP_ERASE_SKIP) { - return SD_ERROR_WP_ERASE_SKIP; - } else if ((response_r0 & SDMMC_R1_CARD_ECC_DISABLED) == SDMMC_R1_CARD_ECC_DISABLED) { - return SD_ERROR_CARD_ECC_DISABLED; - } else if ((response_r0 & SDMMC_R1_ERASE_RESET) == SDMMC_R1_ERASE_RESET) { - return SD_ERROR_ERASE_RESET; - } else if ((response_r0 & SDMMC_R1_AKE_SEQ_ERROR) == SDMMC_R1_AKE_SEQ_ERROR) { - return SD_ERROR_AKE_SEQ_ERR; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } -} + if ((norm_int & SDIOHOST_BIT_XFER_COMPLETE) || (err_int & (SDIO_CMD_ERR | SDIOHOST_BIT_DATA_TIMEOUT_ERR))) { + break; + } -/** - * @brief Checks for error conditions for R1 response. - * @param SDIOx Pointer to SDIO host - * @param Timeout: Timeout value in us. - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp1B(SDIOHOST_TypeDef *SDIOx, u32 Timeout) -{ - u32 response_r0; - u32 count = 0; - u32 norm_int, err_int; + if (count++ >= TimeOutUs) { + RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); + return SD_ERROR_TIMEOUT; + } - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); + /* exit while-loop ASAP */ + DelayUs(1); + } - if ((norm_int & SDIOHOST_BIT_XFER_COMPLETE) || (err_int & (SDIO_CMD_ERR | SDIOHOST_BIT_DATA_TIMEOUT_ERR))) { - break; + if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { + SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); } - if (count++ >= Timeout) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; + if (norm_int & SDIOHOST_BIT_XFER_COMPLETE) { + SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_XFER_COMPLETE); } - /* exit while-loop ASAP */ - DelayUs(1); - } + if (!(norm_int & SDIOHOST_BIT_XFER_COMPLETE) && (err_int & SDIOHOST_BIT_DATA_TIMEOUT_ERR)) { + RTK_LOGE(TAG, "%s busy\n", __FUNCTION__); + return SD_ERROR_BUSY; + } - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } + if (err_int & SDIO_CMD_ERR) { + SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); + if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { + return SD_ERROR_CMD_RSP_TIMEOUT; + } else { + return SD_ERROR_GENERAL_UNKNOWN_ERR; + } + } - if (norm_int & SDIOHOST_BIT_XFER_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_XFER_COMPLETE); - } + response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); + if (RespType == SDMMC_RSP_R1B) { + return SDMMC_CheckErrResp1(response_r0); + } else if (RespType == SDMMC_RSP_R5B) { + return SDMMC_CheckErrResp5(response_r0); + } + break; + case SDMMC_RSP_NONE: + while (!(SDIO_GetNormSts(SDIOx) & SDIOHOST_BIT_CMD_COMPLETE)) { + if (count++ >= TimeOutUs) { + RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); + return SD_ERROR_TIMEOUT; + } + + /* exit while-loop ASAP */ + DelayUs(1); + } - if (!(norm_int & SDIOHOST_BIT_XFER_COMPLETE) && (err_int & SDIOHOST_BIT_DATA_TIMEOUT_ERR)) { - RTK_LOGE(TAG, "%s busy\n", __FUNCTION__); - return SD_ERROR_BUSY; - } + SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } + return SD_ERROR_NONE; + break; + default: + RTK_LOGE(TAG, "%s: Invalid response type!!!\n", __FUNCTION__); } - /* We have received response, retrieve it for analysis */ - response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); + return SD_ERROR_GENERAL_UNKNOWN_ERR; +} - if ((response_r0 & SDMMC_R1_ERRORBITS) == SDMMC_ALLZERO) { +/** + * @brief Checks for error conditions for R1 response. + * @param resp R1 Response of CMD. + * @retval SD Card error state. + */ +u32 SDMMC_CheckErrResp1(u32 resp) +{ + if ((resp & SDMMC_R1_ERRORBITS) == SDMMC_ALLZERO) { return SD_ERROR_NONE; - } else if ((response_r0 & SDMMC_R1_ADDR_OUT_OF_RANGE) == SDMMC_R1_ADDR_OUT_OF_RANGE) { + } else if ((resp & SDMMC_R1_ADDR_OUT_OF_RANGE) == SDMMC_R1_ADDR_OUT_OF_RANGE) { return SD_ERROR_ADDR_OUT_OF_RANGE; - } else if ((response_r0 & SDMMC_R1_ADDR_MISALIGNED) == SDMMC_R1_ADDR_MISALIGNED) { + } else if ((resp & SDMMC_R1_ADDR_MISALIGNED) == SDMMC_R1_ADDR_MISALIGNED) { return SD_ERROR_ADDR_MISALIGNED; - } else if ((response_r0 & SDMMC_R1_BLOCK_LEN_ERR) == SDMMC_R1_BLOCK_LEN_ERR) { + } else if ((resp & SDMMC_R1_BLOCK_LEN_ERR) == SDMMC_R1_BLOCK_LEN_ERR) { return SD_ERROR_BLOCK_LEN_ERR; - } else if ((response_r0 & SDMMC_R1_ERASE_SEQ_ERR) == SDMMC_R1_ERASE_SEQ_ERR) { + } else if ((resp & SDMMC_R1_ERASE_SEQ_ERR) == SDMMC_R1_ERASE_SEQ_ERR) { return SD_ERROR_ERASE_SEQ_ERR; - } else if ((response_r0 & SDMMC_R1_BAD_ERASE_PARAM) == SDMMC_R1_BAD_ERASE_PARAM) { + } else if ((resp & SDMMC_R1_BAD_ERASE_PARAM) == SDMMC_R1_BAD_ERASE_PARAM) { return SD_ERROR_BAD_ERASE_PARAM; - } else if ((response_r0 & SDMMC_R1_WRITE_PROT_VIOLATION) == SDMMC_R1_WRITE_PROT_VIOLATION) { + } else if ((resp & SDMMC_R1_WRITE_PROT_VIOLATION) == SDMMC_R1_WRITE_PROT_VIOLATION) { return SD_ERROR_WRITE_PROT_VIOLATION; - } else if ((response_r0 & SDMMC_R1_LOCK_UNLOCK_FAILED) == SDMMC_R1_LOCK_UNLOCK_FAILED) { + } else if ((resp & SDMMC_R1_LOCK_UNLOCK_FAILED) == SDMMC_R1_LOCK_UNLOCK_FAILED) { return SD_ERROR_LOCK_UNLOCK_FAILED; - } else if ((response_r0 & SDMMC_R1_COM_CRC_FAILED) == SDMMC_R1_COM_CRC_FAILED) { + } else if ((resp & SDMMC_R1_COM_CRC_FAILED) == SDMMC_R1_COM_CRC_FAILED) { return SD_ERROR_COM_CRC_FAILED; - } else if ((response_r0 & SDMMC_R1_ILLEGAL_CMD) == SDMMC_R1_ILLEGAL_CMD) { + } else if ((resp & SDMMC_R1_ILLEGAL_CMD) == SDMMC_R1_ILLEGAL_CMD) { return SD_ERROR_ILLEGAL_CMD; - } else if ((response_r0 & SDMMC_R1_CARD_ECC_FAILED) == SDMMC_R1_CARD_ECC_FAILED) { + } else if ((resp & SDMMC_R1_CARD_ECC_FAILED) == SDMMC_R1_CARD_ECC_FAILED) { return SD_ERROR_CARD_ECC_FAILED; - } else if ((response_r0 & SDMMC_R1_CC_ERROR) == SDMMC_R1_CC_ERROR) { + } else if ((resp & SDMMC_R1_CC_ERROR) == SDMMC_R1_CC_ERROR) { return SD_ERROR_CC_ERR; - } else if ((response_r0 & SDMMC_R1_STREAM_READ_UNDERRUN) == SDMMC_R1_STREAM_READ_UNDERRUN) { + } else if ((resp & SDMMC_R1_STREAM_READ_UNDERRUN) == SDMMC_R1_STREAM_READ_UNDERRUN) { return SD_ERROR_STREAM_READ_UNDERRUN; - } else if ((response_r0 & SDMMC_R1_STREAM_WRITE_OVERRUN) == SDMMC_R1_STREAM_WRITE_OVERRUN) { + } else if ((resp & SDMMC_R1_STREAM_WRITE_OVERRUN) == SDMMC_R1_STREAM_WRITE_OVERRUN) { return SD_ERROR_STREAM_WRITE_OVERRUN; - } else if ((response_r0 & SDMMC_R1_CID_CSDMMC_OVERWRITE) == SDMMC_R1_CID_CSDMMC_OVERWRITE) { + } else if ((resp & SDMMC_R1_CID_CSDMMC_OVERWRITE) == SDMMC_R1_CID_CSDMMC_OVERWRITE) { return SD_ERROR_CID_CSDMMC_OVERWRITE; - } else if ((response_r0 & SDMMC_R1_WP_ERASE_SKIP) == SDMMC_R1_WP_ERASE_SKIP) { + } else if ((resp & SDMMC_R1_WP_ERASE_SKIP) == SDMMC_R1_WP_ERASE_SKIP) { return SD_ERROR_WP_ERASE_SKIP; - } else if ((response_r0 & SDMMC_R1_CARD_ECC_DISABLED) == SDMMC_R1_CARD_ECC_DISABLED) { + } else if ((resp & SDMMC_R1_CARD_ECC_DISABLED) == SDMMC_R1_CARD_ECC_DISABLED) { return SD_ERROR_CARD_ECC_DISABLED; - } else if ((response_r0 & SDMMC_R1_ERASE_RESET) == SDMMC_R1_ERASE_RESET) { + } else if ((resp & SDMMC_R1_ERASE_RESET) == SDMMC_R1_ERASE_RESET) { return SD_ERROR_ERASE_RESET; - } else if ((response_r0 & SDMMC_R1_AKE_SEQ_ERROR) == SDMMC_R1_AKE_SEQ_ERROR) { + } else if ((resp & SDMMC_R1_AKE_SEQ_ERROR) == SDMMC_R1_AKE_SEQ_ERROR) { return SD_ERROR_AKE_SEQ_ERR; } else { return SD_ERROR_GENERAL_UNKNOWN_ERR; @@ -1431,185 +1408,19 @@ u32 SDMMC_GetCmdResp1B(SDIOHOST_TypeDef *SDIOx, u32 Timeout) } /** - * @brief Checks for error conditions for R2 (CID or CSD) response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp2(SDIOHOST_TypeDef *SDIOx) -{ - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - return SD_ERROR_NONE; -} - -/** - * @brief Checks for error conditions for R3 (OCR) response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp3(SDIOHOST_TypeDef *SDIOx) -{ - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - return SD_ERROR_NONE; -} - -/** - * @brief Checks for error conditions for R3 (OCR) response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp4(SDIOHOST_TypeDef *SDIOx) -{ - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - return SD_ERROR_NONE; -} - -/** - * @brief Checks for error conditions for R1 response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state + * @brief Checks for error conditions for R5 response. + * @param resp R5 Response of CMD. + * @retval SD Card error state. */ -u32 SDMMC_GetCmdResp5(SDIOHOST_TypeDef *SDIOx) +u32 SDMMC_CheckErrResp5(u32 resp) { - u32 response_r0; - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - /* We have received response, retrieve it. */ - response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); - - if ((response_r0 & SDMMC_R5_ERRORBITS) == SDMMC_ALLZERO) { + if ((resp & SDMMC_R5_ERRORBITS) == SDMMC_ALLZERO) { return SD_ERROR_NONE; - } else if ((response_r0 & SDMMC_R5_COM_CRC_ERROR) == SDMMC_R5_COM_CRC_ERROR) { + } else if ((resp & SDMMC_R5_COM_CRC_ERROR) == SDMMC_R5_COM_CRC_ERROR) { return SD_ERROR_CMD_CRC_FAIL; - } else if ((response_r0 & SDMMC_R5_ILLEGAL_COMMAND) == SDMMC_R5_ILLEGAL_COMMAND) { + } else if ((resp & SDMMC_R5_ILLEGAL_COMMAND) == SDMMC_R5_ILLEGAL_COMMAND) { return SD_ERROR_ILLEGAL_CMD; - } else if ((response_r0 & SDMMC_R5_OUT_OF_RANGE) == SDMMC_R5_OUT_OF_RANGE) { + } else if ((resp & SDMMC_R5_OUT_OF_RANGE) == SDMMC_R5_OUT_OF_RANGE) { return SD_ERROR_ADDR_OUT_OF_RANGE; } else { return SD_ERROR_GENERAL_UNKNOWN_ERR; @@ -1617,106 +1428,20 @@ u32 SDMMC_GetCmdResp5(SDIOHOST_TypeDef *SDIOx) } /** - * @brief Checks for error conditions for R6 (RCA) response. - * @param SDIOx Pointer to SDIO host - * @param SDMMC_CMD: The sent command index - * @param pRCA: Pointer to the variable that will contain the SD card relative - * address RCA - * @retval SD Card error state + * @brief Checks for error conditions for R6 response. + * @param resp R6 Response of CMD. + * @retval SD Card error state. */ -u32 SDMMC_GetCmdResp6(SDIOHOST_TypeDef *SDIOx, u16 *pRCA) +u32 SDMMC_CheckErrResp6(u32 resp) { - u32 response_r0; - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - /* We have received response, retrieve it. */ - response_r0 = SDIO_GetResponse(SDIOx, SDIO_RESP0); - - if ((response_r0 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | - SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO) { - *pRCA = (u16)(response_r0 >> 16); - + if ((resp & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | + SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO) { return SD_ERROR_NONE; - } else if ((response_r0 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD) { + } else if ((resp & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD) { return SD_ERROR_ILLEGAL_CMD; - } else if ((response_r0 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED) { + } else if ((resp & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED) { return SD_ERROR_COM_CRC_FAILED; } else { return SD_ERROR_GENERAL_UNKNOWN_ERR; } } - -/** - * @brief Checks for error conditions for R7 response. - * @param SDIOx Pointer to SDIO host - * @retval SD Card error state - */ -u32 SDMMC_GetCmdResp7(SDIOHOST_TypeDef *SDIOx) -{ - u32 count = 0; - u32 norm_int, err_int; - - while (1) { - norm_int = SDIO_GetNormSts(SDIOx); - err_int = SDIO_GetErrSts(SDIOx); - - if ((norm_int & SDIOHOST_BIT_CMD_COMPLETE) || (err_int & SDIO_CMD_ERR)) { - break; - } - - if (count++ >= SDMMC_CMD_TIMEOUT) { - RTK_LOGE(TAG, "%s timeout\n", __FUNCTION__); - return SD_ERROR_TIMEOUT; - } - - /* exit while-loop ASAP */ - DelayUs(1); - } - - if (norm_int & SDIOHOST_BIT_CMD_COMPLETE) { - SDIO_ClearNormSts(SDIOx, SDIOHOST_BIT_CMD_COMPLETE); - } - - if (err_int & SDIO_CMD_ERR) { - DelayUs(10); // avoid cmd_err sts is set again after clear - SDIO_ClearErrSts(SDIOx, SDIO_CMD_ERR); - if (err_int & SDIOHOST_BIT_CMD_TIMEOUT_ERR) { - return SD_ERROR_CMD_RSP_TIMEOUT; - } else { - return SD_ERROR_GENERAL_UNKNOWN_ERR; - } - } - - return SD_ERROR_NONE; -} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_sdio_device.c b/ameba/amebag2/source/fwlib/ram_common/ameba_sdio_device.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_sdio_device.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_sdio_device.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_spi.c b/ameba/amebag2/source/fwlib/ram_common/ameba_spi.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_spi.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_spi.c index a8d768c6..db196a76 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_spi.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_spi.c @@ -1187,4 +1187,4 @@ void SSI_SlaveOutputEnable(SPI_TypeDef *spi_dev, u32 Status) /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_sport.c b/ameba/amebag2/source/fwlib/ram_common/ameba_sport.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_sport.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_sport.c index 2a997780..7aa97219 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_sport.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_sport.c @@ -1991,4 +1991,4 @@ void AUDIO_SP_SetRxDataFormat(u32 index, u32 format) /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_swr.c b/ameba/amebag2/source/fwlib/ram_common/ameba_swr.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_swr.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_swr.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_thermal.c b/ameba/amebag2/source/fwlib/ram_common/ameba_thermal.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_thermal.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_thermal.c index 96084b5d..5a30cc92 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_thermal.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_thermal.c @@ -499,4 +499,4 @@ float TM_GetFdegree(u32 Data) /** @} */ /** @} */ -/** @} */ \ No newline at end of file +/** @} */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_tim.c b/ameba/amebag2/source/fwlib/ram_common/ameba_tim.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_tim.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_tim.c index 0f7c401b..49d80ec4 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_tim.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_tim.c @@ -838,4 +838,4 @@ u32 RTIM_IsChannelCaptureEnabled(RTIM_TypeDef *TIMx, u16 TIM_Channel) return RTK_FAIL; } -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_uart.c b/ameba/amebag2/source/fwlib/ram_common/ameba_uart.c similarity index 96% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_uart.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_uart.c index 886402b3..12f14974 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_uart.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_uart.c @@ -633,6 +633,38 @@ void UART_RTSForceCmd(UART_TypeDef *UARTx, u32 NewState) } } +/** + * @brief Configure UART rx timeout threshold. + * @param UARTx UART device, where x can be 0~3. + * @param RxTimeout Rx timeout value, unit is one bit time. + * @return None + */ +void UART_RxToThreConfig(UART_TypeDef *UARTx, u32 RxTimeout) +{ + assert_param(RxTimeout <= 0xFFFF); + + u32 reg = UARTx->RX_PATH_CTRL; + reg &= ~RUART_MASK_R_RXTO_THRS; + reg |= RUART_R_RXTO_THRS(RxTimeout); + UARTx->RX_PATH_CTRL = reg; +} + +/** + * @brief Configure UART rxfifo empty timeout threshold. + * @param UARTx UART device, where x can be 0~3. + * @param RxTimeout Rx timeout counter works in uart_rclk. + * @return None + */ +void UART_REToThreConfig(UART_TypeDef *UARTx, u32 RxTimeout) +{ + assert_param(RxTimeout <= 0xFFFFFFF); + + u32 reg = UARTx->TH_RETI; + reg &= ~RUART_MASK_TH_RETI; + reg |= RUART_TH_RETI(RxTimeout); + UARTx->TH_RETI = reg; +} + /** * @} */ @@ -643,4 +675,4 @@ void UART_RTSForceCmd(UART_TypeDef *UARTx, u32 NewState) /** * @} - */ \ No newline at end of file + */ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_ups.c b/ameba/amebag2/source/fwlib/ram_common/ameba_ups.c similarity index 99% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_ups.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_ups.c index e7c5e973..8465299c 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_ups.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_ups.c @@ -146,4 +146,4 @@ void UPS_SetDbcCnt(u16 Dbc_Cnt, u8 idx) Temp &= ~TIM_MASK_UPS0_DBC_CNT; Temp |= TIM_UPS0_DBC_CNT(Dbc_Cnt); HAL_WRITE32(UPS_REG_BASE, REG_LSYS_UPS_CTRLx[idx], Temp); -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_usb.c b/ameba/amebag2/source/fwlib/ram_common/ameba_usb.c similarity index 77% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_usb.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_usb.c index f86963eb..39ca36ce 100644 --- a/ameba/amebaG2/source/fwlib/ram_common/ameba_usb.c +++ b/ameba/amebag2/source/fwlib/ram_common/ameba_usb.c @@ -8,6 +8,7 @@ #include "ameba_soc.h" #include "usb_hal.h" +#include "usb_regs.h" /* Private defines -----------------------------------------------------------*/ @@ -33,7 +34,9 @@ static void usb_chip_enable_interrupt(u8 priority); static void usb_chip_disable_interrupt(void); static void usb_chip_register_irq_handler(void *handler, u8 priority); static void usb_chip_unregister_irq_handler(void); - +#if CONFIG_USB_PM +static void usb_chip_cg(u32 ms); +#endif /* Private variables ---------------------------------------------------------*/ static usb_cal_data_t usb_cal_data[USB_CAL_DATA_LEN]; @@ -48,6 +51,9 @@ usb_hal_driver_t usb_hal_driver = { .disable_interrupt = usb_chip_disable_interrupt, .register_irq_handler = usb_chip_register_irq_handler, .unregister_irq_handler = usb_chip_unregister_irq_handler, +#if CONFIG_USB_PM + .cg = usb_chip_cg, +#endif }; /* Private functions ---------------------------------------------------------*/ @@ -319,7 +325,7 @@ static void usb_chip_disable_interrupt(void) static void usb_chip_register_irq_handler(void *handler, u8 priority) { if (handler != NULL) { - InterruptRegister((IRQ_FUN)handler, USB_IRQ, (u32)NULL, priority); + InterruptRegister((IRQ_FUN)handler, USB_IRQ, NULL, priority); } } @@ -331,4 +337,92 @@ static void usb_chip_unregister_irq_handler(void) { InterruptUnRegister(USB_IRQ); } + +#if CONFIG_USB_PM +static void usb_chip_wake_event(u8 enable) +{ + if (enable) { + SOCPS_SetAPWakeEvent(WAKE_SRC_USB, ENABLE); + } else { + SOCPS_SetAPWakeEvent(WAKE_SRC_USB, DISABLE); + } +} + +static u32 usb_chip_cg_suspend_cb(u32 expected_idle_time, void *param) +{ + (void) expected_idle_time; + (void) param; + PLL_TypeDef *sys_pll = (PLL_TypeDef *)PLL_REG_BASE; + + USB_PCGCCTL = USB_PCGCCTL | USB_OTG_PCGCCTL_STOPCLK; + + sys_pll->PLL_UPLL_CTRL0 |= PLL_BIT_SUSPEND_WAK_MSK; + return TRUE; +} + +static u32 usb_chip_cg_resume_cb(u32 expected_idle_time, void *param) +{ + (void) expected_idle_time; + (void) param; + u32 reg; + + USB_PCGCCTL = USB_PCGCCTL & (~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK)); + + reg = HAL_READ32(USB_ADDON_REG_CTRL, 0); + reg &= ~USB_ADDON_REG_CTRL_BIT_DIS_SUSPEND; + HAL_WRITE32(USB_ADDON_REG_CTRL, 0U, reg); + + PLL_TypeDef *sys_pll = (PLL_TypeDef *)PLL_REG_BASE; + sys_pll->PLL_UPLL_CTRL0 &= ~PLL_BIT_SUSPEND_WAK_MSK; + + usb_chip_wake_event(0); + pmu_acquire_wakelock(PMU_OS);//Stay active + pmu_unregister_sleep_callback(PMU_DEV_USER_BASE); + return TRUE; +} + +static u32 usb_chip_aontimer_cb(void *Data) +{ + (void)Data; + + RTK_LOGS(NOTAG, RTK_LOG_INFO, "AON timer handler: %x\n", SOCPS_AONWakeReason()); + AONTimer_ClearINT(); + RCC_PeriphClockCmd(APBPeriph_ATIM, APBPeriph_ATIM_CLOCK, DISABLE); + pmu_acquire_wakelock(PMU_OS);//Stay active + return 0; +} + +static void usb_chip_aontimer_cg(u32 ms) +{ + RCC_PeriphClockCmd(APBPeriph_ATIM, APBPeriph_ATIM_CLOCK, ENABLE); + RTK_LOGS(NOTAG, RTK_LOG_INFO, "AON timer %d ms\n", ms); + + AONTimer_Setting(ms); + AONTimer_INT(ENABLE); + + InterruptRegister((IRQ_FUN)usb_chip_aontimer_cb, AON_TIM_IRQ, NULL, 3); + InterruptEn(AON_TIM_IRQ, 3); + + SOCPS_SetAPWakeEvent(WAKE_SRC_AON_TIM, ENABLE); +} + +static void usb_chip_cg(u32 ms) +{ + /*Set AP sleep type*/ + pmu_set_sleep_type(SLEEP_CG); + /*Acquire wakelock to avoid AP enter sleep mode*/ + pmu_acquire_wakelock(PMU_OS); + + pmu_register_sleep_callback(PMU_DEV_USER_BASE, (PSM_HOOK_FUN)usb_chip_cg_suspend_cb, NULL, (PSM_HOOK_FUN)usb_chip_cg_resume_cb, NULL); + + if (ms) {//Select CG wake event + usb_chip_aontimer_cg(ms);//Aon timer wakeup + } else { + usb_chip_wake_event(1);//USB event wakeup + } + /* Release wakelock, to make CPU enter sleep mode */ + pmu_release_wakelock(PMU_OS); +} +#endif + /* Exported functions --------------------------------------------------------*/ diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_uvc.c b/ameba/amebag2/source/fwlib/ram_common/ameba_uvc.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_uvc.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_uvc.c diff --git a/ameba/amebaG2/source/fwlib/ram_common/ameba_wakepin.c b/ameba/amebag2/source/fwlib/ram_common/ameba_wakepin.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_common/ameba_wakepin.c rename to ameba/amebag2/source/fwlib/ram_common/ameba_wakepin.c diff --git a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_ethernet.c b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_ethernet.c similarity index 73% rename from ameba/amebaG2/source/fwlib/ram_km4tz/ameba_ethernet.c rename to ameba/amebag2/source/fwlib/ram_km4tz/ameba_ethernet.c index 9abeceac..b6afae7a 100644 --- a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_ethernet.c +++ b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_ethernet.c @@ -189,7 +189,7 @@ void Ethernet_AutoPolling(u32 opt) u8 *Ethernet_GetTXPktInfo(ETH_InitTypeDef *ETH_InitStruct) { ETHERNET_TypeDef *RMII = ((ETHERNET_TypeDef *) RMII_REG_BASE); - u8 tx_search_idx = ETH_InitStruct->ETH_TxDescCurrentNum; + u8 tx_idx = ETH_InitStruct->ETH_TxDescCurrentNum; u8 *buf = NULL; if (ETH_InitStruct == NULL) { @@ -198,13 +198,10 @@ u8 *Ethernet_GetTXPktInfo(ETH_InitTypeDef *ETH_InitStruct) } /* check if current Tx descriptor is available */ - if ((((u32)(ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw1)) & FEMAC_TX_DSC_BIT_OWN) == 0) { - buf = (u8 *)ETH_InitStruct->ETH_TxDesc[tx_search_idx].addr; + if ((((u32)(ETH_InitStruct->ETH_TxDesc[tx_idx].dw1)) & FEMAC_TX_DSC_BIT_OWN) == 0) { + buf = (u8 *)ETH_InitStruct->ETH_TxDesc[tx_idx].addr; } else { RMII->ETH_ISR_AND_IMR |= BIT_ISR_TOK_TI; - /* enable Tx ring1 */ - //RMII->ETH_ETHER_IO_CMD |= BIT_TXFN1ST; - //RTK_LOGE(TAG, "Tx descriptor ring is full !!\r\n"); } return buf; @@ -221,7 +218,7 @@ u8 *Ethernet_GetTXPktInfo(ETH_InitTypeDef *ETH_InitStruct) void Ethernet_UpdateTXDESCAndSend(ETH_InitTypeDef *ETH_InitStruct, u32 size) { ETHERNET_TypeDef *RMII = ((ETHERNET_TypeDef *) RMII_REG_BASE); - u8 tx_search_idx = ETH_InitStruct->ETH_TxDescCurrentNum; + u8 tx_idx = ETH_InitStruct->ETH_TxDescCurrentNum; if (ETH_InitStruct == NULL) { RTK_LOGE(TAG, "Invalid parameter !!\r\n"); @@ -233,23 +230,26 @@ void Ethernet_UpdateTXDESCAndSend(ETH_InitTypeDef *ETH_InitStruct, u32 size) return; } - DCache_Clean((u32)ETH_InitStruct->ETH_TxDesc[tx_search_idx].addr, (u32)ETH_PKT_BUFF_SZ); //TODO: need invalidate or not + DCache_Clean((u32)ETH_InitStruct->ETH_TxDesc[tx_idx].addr, (u32)size); //TODO: need invalidate or not - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw2 = 0; - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw3 = 0; - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw4 = 0; + ETH_InitStruct->ETH_TxDesc[tx_idx].dw2 = 0; + ETH_InitStruct->ETH_TxDesc[tx_idx].dw3 = 0; + ETH_InitStruct->ETH_TxDesc[tx_idx].dw4 = 0; - if (tx_search_idx == ((ETH_InitStruct->ETH_TxDescNum) - 1)) { - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw1 = (FEMAC_TX_DSC_BIT_EOR | FEMAC_TX_DSC_BIT_FS | FEMAC_TX_DSC_BIT_LS | FEMAC_TX_DSC_BIT_CRC | (size & 0x1ffff)); + if (tx_idx == ((ETH_InitStruct->ETH_TxDescNum) - 1)) { + ETH_InitStruct->ETH_TxDesc[tx_idx].dw1 = FEMAC_TX_DSC_BIT_EOR | FEMAC_TX_DSC_BIT_FS | FEMAC_TX_DSC_BIT_IPCS | \ + FEMAC_TX_DSC_BIT_L4CS | FEMAC_TX_DSC_BIT_LS | FEMAC_TX_DSC_BIT_CRC | \ + FEMAC_TX_DSC_BIT_SIZE(size); } else { - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw1 = (FEMAC_TX_DSC_BIT_FS | FEMAC_TX_DSC_BIT_LS | FEMAC_TX_DSC_BIT_CRC | (size & 0x1ffff)); + ETH_InitStruct->ETH_TxDesc[tx_idx].dw1 = FEMAC_TX_DSC_BIT_FS | FEMAC_TX_DSC_BIT_LS | FEMAC_TX_DSC_BIT_IPCS | \ + FEMAC_TX_DSC_BIT_L4CS | FEMAC_TX_DSC_BIT_CRC | FEMAC_TX_DSC_BIT_SIZE(size); } - ETH_InitStruct->ETH_TxDesc[tx_search_idx].dw1 |= FEMAC_TX_DSC_BIT_OWN; + ETH_InitStruct->ETH_TxDesc[tx_idx].dw1 |= FEMAC_TX_DSC_BIT_OWN; RMII->ETH_ISR_AND_IMR |= BIT_ISR_TOK_TI; RMII->ETH_ETHER_IO_CMD |= BIT_TXFN1ST; //TODO: not need set for each pkt - if (tx_search_idx == ((ETH_InitStruct->ETH_TxDescNum) - 1)) { + if (tx_idx == ((ETH_InitStruct->ETH_TxDescNum) - 1)) { ETH_InitStruct->ETH_TxDescCurrentNum = 0; } else { ETH_InitStruct->ETH_TxDescCurrentNum++; @@ -267,20 +267,21 @@ void Ethernet_UpdateTXDESCAndSend(ETH_InitTypeDef *ETH_InitStruct, u32 size) u8 *Ethernet_GetRXPktInfo(ETH_InitTypeDef *ETH_InitStruct, u32 *rx_len) { ETHERNET_TypeDef *RMII = ((ETHERNET_TypeDef *) RMII_REG_BASE); - u8 rx_search_idx = ETH_InitStruct->ETH_RxDescCurrentNum; + u32 pkt_size = 0; + u8 rx_idx = ETH_InitStruct->ETH_RxDescCurrentNum; u8 *buf = NULL; /* check if current Rx descriptor is available */ - if ((((volatile u32)(ETH_InitStruct->ETH_RxDesc[rx_search_idx].dw1)) & FEMAC_TX_DSC_BIT_OWN) == 0) { - *rx_len = (ETH_InitStruct->ETH_RxDesc[rx_search_idx].dw1) & 0xFFF; - buf = (u8 *)(ETH_InitStruct->ETH_RxDesc[rx_search_idx].addr + 2); - DCache_Invalidate((u32)(ETH_InitStruct->ETH_RxDesc[rx_search_idx].addr), (u32)ETH_PKT_BUFF_SZ); + if ((((volatile u32)(ETH_InitStruct->ETH_RxDesc[rx_idx].dw1)) & FEMAC_RX_DSC_BIT_OWN) == 0) { + pkt_size = FEMAC_RX_DSC_LEN(ETH_InitStruct->ETH_RxDesc[rx_idx].dw1); + buf = (u8 *)(ETH_InitStruct->ETH_RxDesc[rx_idx].addr + 2); + DCache_Invalidate((u32)(ETH_InitStruct->ETH_RxDesc[rx_idx].addr), (u32)pkt_size); } else { RMII->ETH_ISR_AND_IMR |= BIT_ISR_ROK; - *rx_len = 0; - return 0; } + *rx_len = pkt_size; + return buf; } @@ -302,8 +303,8 @@ void Ethernet_UpdateRXDESC(ETH_InitTypeDef *ETH_InitStruct) } - ETH_InitStruct->ETH_RxDesc[read_idx].dw1 &= FEMAC_TX_DSC_BIT_EOR;//? clear - ETH_InitStruct->ETH_RxDesc[read_idx].dw1 |= (FEMAC_TX_DSC_BIT_OWN | ETH_PKT_BUFF_SZ);//1600 + ETH_InitStruct->ETH_RxDesc[read_idx].dw1 &= FEMAC_RX_DSC_BIT_EOR; + ETH_InitStruct->ETH_RxDesc[read_idx].dw1 |= (FEMAC_RX_DSC_BIT_OWN | ETH_InitStruct->ETH_RxBufSize); ETH_InitStruct->ETH_RxDesc[read_idx].dw2 = 0; ETH_InitStruct->ETH_RxDesc[read_idx].dw3 = 0; @@ -370,76 +371,82 @@ u8 Ethernet_WaitBusy(u32 WaitType) } /** - * @brief To read the specified FEPHY register - * - * @param[in] page The specified page number. - * @param[in] reg_addr The specified register address. - * - * @returns The register value. + * @brief Waits for the PHY MDIO bus to become idle. + * This function polls the MDIO busy flag until it is cleared or a timeout occurs. + * @param RMII Pointer to the Ethernet MAC register structure. + * @param timeout_us Timeout threshold in microseconds. + * @return 0 on success (MDIO idle), -1 on timeout. */ -u16 Ethernet_Read_PhyReg(u16 page, u16 reg_addr) +static inline int Ethernet_WaitPhyIdle(ETHERNET_TypeDef *RMII, uint32_t timeout_us) { - ETHERNET_TypeDef *RMII = ((ETHERNET_TypeDef *) RMII_REG_BASE); - u16 rd_data = 0; - - while (RMII->ETH_MIIAR & BIT_MDIO_BUSY); - - if (reg_addr > 0x1F) { - RTK_LOGE(TAG, "Invalid parameter !!\r\n"); - return 0; + uint32_t start = DTimestamp_Get(); + while ((DTimestamp_Get() - start) <= timeout_us) { + if (!(RMII->ETH_MIIAR & BIT_MDIO_BUSY)) { + return RTK_SUCCESS; + } + } + return -RTK_ERR_TIMEOUT; +} +/** + * @brief Reads a 16-bit value from a PHY register via MDIO. + * @param phy_id Physical address of the target PHY. + * @param reg_addr Register address (0~31). + * @param data Output pointer to store the read value. + * @return 0 (RTK_SUCCESS) on success, negative value on error. + */ +int Ethernet_ReadPhyReg(uint8_t phy_id, uint8_t reg_addr, uint16_t *data) +{ + ETHERNET_TypeDef *RMII = (ETHERNET_TypeDef *) RMII_REG_BASE; + if (TrustZone_IsSecure()) { + RMII = (ETHERNET_TypeDef *) RMII_REG_BASE_S; + } + if (reg_addr > FEPHY_REG_ADDR_31) { + return -RTK_FAIL; } - // Switch to the specified page by register 31 - RMII->ETH_MIIAR = (BIT_FLAG | PHYADDRESS(phy_id) | REGADDR4_0(0x1F) | page); - DelayUs(70); // wait for command complete - - Ethernet_WaitBusy(WAIT_SMI_WRITE_DONE); + if (Ethernet_WaitPhyIdle(RMII, MDIO_WAIT_TIME) != RTK_SUCCESS) { + return -RTK_ERR_BUSY; + } RMII->ETH_MIIAR = (PHYADDRESS(phy_id) | REGADDR4_0(reg_addr)); - DelayUs(70); // wait for command complete + if (Ethernet_WaitPhyIdle(RMII, MDIO_WAIT_TIME) != RTK_SUCCESS) { + return -RTK_ERR_BUSY; + } - Ethernet_WaitBusy(WAIT_SMI_READ_DONE); - rd_data = (u16)(RMII->ETH_MIIAR & 0xFFFF); - + *data = (uint16_t)GET_DATA15_0(RMII->ETH_MIIAR); - return rd_data; + return RTK_SUCCESS; } /** - * @brief To write "data" value to the specified FEPHY register - * @param[in] page The specified page number. - * @param[in] reg_addr The specified register address. - * @param[in] data The specified data value. - * - * @returns 0. + * @brief Writes a 16-bit value to a PHY register via MDIO. + * @param phy_id Physical address of the target PHY (refer to datasheet, usually from hardware pins). + * @param reg_addr Register address (0~31, according to IEEE 802.3 standard). + * @param data The value to write. + * @return 0 (RTK_SUCCESS) on success, negative value on error. */ -u32 Ethernet_Write_PhyReg(u16 page, u16 reg_addr, u16 data) +int Ethernet_WritePhyReg(uint8_t phy_id, uint8_t reg_addr, uint16_t data) { - ETHERNET_TypeDef *RMII = ((ETHERNET_TypeDef *) RMII_REG_BASE); - - if (reg_addr > 0x1F) { - RTK_LOGE(TAG, "Invalid parameter !!\r\n"); - return 0; + ETHERNET_TypeDef *RMII = (ETHERNET_TypeDef *) RMII_REG_BASE; + if (TrustZone_IsSecure()) { + RMII = (ETHERNET_TypeDef *) RMII_REG_BASE_S; + } + if (reg_addr > FEPHY_REG_ADDR_31) { + return -RTK_FAIL; } - while (RMII->ETH_MIIAR & BIT_MDIO_BUSY); - - // Switch to the specified page by register 31 - RMII->ETH_MIIAR = (BIT_FLAG | PHYADDRESS(phy_id) | BIT_DISABLE_AUTO_POLLING | REGADDR4_0(0x1F) | page); - DelayUs(70); // wait for command complete - - Ethernet_WaitBusy(WAIT_SMI_WRITE_DONE); + if (Ethernet_WaitPhyIdle(RMII, MDIO_WAIT_TIME) != RTK_SUCCESS) { + return -RTK_ERR_BUSY; + } RMII->ETH_MIIAR = (BIT_FLAG | BIT_DISABLE_AUTO_POLLING | PHYADDRESS(phy_id) | REGADDR4_0(reg_addr) | data); - DelayUs(70); // wait for command complete - - Ethernet_WaitBusy(WAIT_SMI_WRITE_DONE); - return 0; + return RTK_SUCCESS; } + /** * \brief Enable ethernet RX. * \param None. @@ -496,11 +503,12 @@ void Ethernet_StructInit(ETH_InitTypeDef *ETH_InitStruct) ETH_InitStruct->ETH_TxDescCurrentNum = 0; ETH_InitStruct->ETH_RxFrameStartDescIdx = 0; ETH_InitStruct->ETH_RxFrameLen = 0; + ETH_InitStruct->ETH_TxFrameLen = 0; ETH_InitStruct->ETH_RxSegmentCount = 0; ETH_InitStruct->ETH_TxAllocBufSize = 1600; ETH_InitStruct->ETH_RxAllocBufSize = 1600; - ETH_InitStruct->ETH_TxBufSize = 1524; - ETH_InitStruct->ETH_RxBufSize = 1524; + ETH_InitStruct->ETH_TxBufSize = ETH_PKT_MAX_SIZE; + ETH_InitStruct->ETH_RxBufSize = ETH_PKT_MAX_SIZE; } u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct) @@ -522,35 +530,39 @@ u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct) } while (RMII->ETH_CR & BIT_RST); /* reset phy */ - PHY_SW_RESET(); + PHY_SoftWareReset(PHYID_1); - DelayMs(200); + PHY_SetRefclkDir(PHYID_1, ETH_InitStruct->ETH_RefClkDirec); - PHY_SET_REFCLK_DIR(RTL_8721F, ETH_InitStruct->ETH_RefClkDirec); +#ifdef ENABLE_EEE_FUNCTION + PHY_SetEEEMode(PHYID_1, ETH_MAC_MODE); +#endif #ifdef CHECK_PHY_STATUS - u32 tmp; - tmp = Ethernet_Read_PhyReg(FEPHY_REG_ADDR_0, FEPHY_REG_ADDR_0); + uint16_t tmp; + /*select page 0*/ + Ethernet_WritePhyReg(PHYID_1, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_0); + + Ethernet_ReadPhyReg(PHYID_1, FEPHY_REG_ADDR_0, &tmp); RTK_LOGI(TAG, "page0 reg0=0x%x\n", tmp); - tmp = Ethernet_Read_PhyReg(FEPHY_REG_ADDR_0, FEPHY_REG_ADDR_1); + Ethernet_ReadPhyReg(PHYID_1, FEPHY_REG_ADDR_1, &tmp); RTK_LOGI(TAG, "page0 reg1=0x%x\n", tmp); - tmp = Ethernet_Read_PhyReg(FEPHY_REG_ADDR_0, FEPHY_REG_ADDR_2); + Ethernet_ReadPhyReg(PHYID_1, FEPHY_REG_ADDR_2, &tmp); RTK_LOGI(TAG, "page0 reg2=0x%x\n", tmp); - tmp = Ethernet_Read_PhyReg(FEPHY_REG_ADDR_0, FEPHY_REG_ADDR_3); + Ethernet_ReadPhyReg(PHYID_1, FEPHY_REG_ADDR_3, &tmp); RTK_LOGI(TAG, "page0 reg3=0x%x\n", tmp); - tmp = Ethernet_Read_PhyReg(FEPHY_REG_ADDR_7, FEPHY_REG_ADDR_16); + /*select page 7*/ + Ethernet_WritePhyReg(PHYID_1, FEPHY_REG_ADDR_31, FEPHY_REG_ADDR_7); + + Ethernet_ReadPhyReg(PHYID_1, RTL8201FR_PAGE7_REG_RMII_MODE_SET, &tmp); RTK_LOGI(TAG, "page7 reg16=0x%x\n", tmp); #endif - -#ifdef ENABLE_EEE_FUNCTION - PHY_ENABLE_EEE(PHY_TYPE_SELECT, ENABLE); - PHY_SET_EEE_MODE(PHY_TYPE_SELECT, ETH_MAC_MODE); -#endif + PHY_RestartAutoNego(PHYID_1); /* Tx settings */ @@ -586,7 +598,7 @@ u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct) /* initialize Tx descriptors */ for (i = 0; i < (ETH_InitStruct->ETH_TxDescNum); i++) { ETH_InitStruct->ETH_TxDesc[i].dw1 = 0; - ETH_InitStruct->ETH_TxDesc[i].addr = (u32)(ETH_InitStruct->ETH_TxPktBuf + (i * ETH_PKT_BUFF_SZ)); + ETH_InitStruct->ETH_TxDesc[i].addr = (u32)(ETH_InitStruct->ETH_TxPktBuf + (i * ETH_InitStruct->ETH_TxBufSize)); ETH_InitStruct->ETH_TxDesc[i].dw2 = 0;//(eth_vlan_hdr_remove << 25) | (ETH_C_VLAN_HDR & 0xFFFF); ETH_InitStruct->ETH_TxDesc[i].dw3 = 0; ETH_InitStruct->ETH_TxDesc[i].dw4 = 0; @@ -595,11 +607,11 @@ u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct) /* initialize Rx descriptors */ for (i = 0; i < (ETH_InitStruct->ETH_RxDescNum); i++) { if (i == ((ETH_InitStruct->ETH_RxDescNum) - 1)) { - ETH_InitStruct->ETH_RxDesc[i].dw1 = BIT31 | BIT30 | ETH_PKT_BUFF_SZ; + ETH_InitStruct->ETH_RxDesc[i].dw1 = FEMAC_RX_DSC_BIT_OWN | FEMAC_RX_DSC_BIT_EOR | ETH_InitStruct->ETH_RxBufSize; } else { - ETH_InitStruct->ETH_RxDesc[i].dw1 = BIT31 | ETH_PKT_BUFF_SZ; + ETH_InitStruct->ETH_RxDesc[i].dw1 = FEMAC_RX_DSC_BIT_OWN | ETH_InitStruct->ETH_RxBufSize; } - ETH_InitStruct->ETH_RxDesc[i].addr = (u32)(ETH_InitStruct->ETH_RxPktBuf + (i * ETH_PKT_BUFF_SZ)); + ETH_InitStruct->ETH_RxDesc[i].addr = (u32)(ETH_InitStruct->ETH_RxPktBuf + (i * ETH_InitStruct->ETH_RxBufSize)); ETH_InitStruct->ETH_RxDesc[i].dw2 = 0; ETH_InitStruct->ETH_RxDesc[i].dw3 = 0; } @@ -646,4 +658,4 @@ u32 Ethernet_init(ETH_InitTypeDef *ETH_InitStruct) ETH_EnableRx(); return HAL_OK; -} \ No newline at end of file +} diff --git a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_flashclk.c b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_flashclk.c similarity index 95% rename from ameba/amebaG2/source/fwlib/ram_km4tz/ameba_flashclk.c rename to ameba/amebag2/source/fwlib/ram_km4tz/ameba_flashclk.c index 391f2a25..c898b109 100644 --- a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_flashclk.c +++ b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_flashclk.c @@ -35,15 +35,22 @@ static void FLASH_PLLInit_ClockDiv(void) u32 sys_pll_clk = RRAM_DEV->clk_info_bk.SYSPLL_CLK; /* set spic clock src and div */ - spic_ckd = PLL_ClkSrcGet(sys_pll_clk, usb_pll_clk, CLK_LIMIT_SPIC); + + /* SPIC work in this clock will effect RF performance*/ + if (sys_pll_clk == PLL_393P216M) { + spic_ckd = PLL_ClkSrcGet(PLL_NONE, usb_pll_clk, CLK_LIMIT_SPIC); + } else { + spic_ckd = PLL_ClkSrcGet(sys_pll_clk, usb_pll_clk, CLK_LIMIT_SPIC); + } + if (spic_ckd & IS_SYS_PLL) { RCC_PeriphClockDividerSet(SYS_PLL_SPIC, GET_CLK_DIV(spic_ckd)); RCC_PeriphClockSourceSet(SPIC, SYS_PLL); - RTK_LOGI(TAG, "SPIC CLK: %d Hz\n", sys_pll_clk / GET_CLK_DIV(spic_ckd)); + RTK_LOGI(TAG, "FLASH CLK: %d Hz\n", sys_pll_clk / (2 * GET_CLK_DIV(spic_ckd))); } else { RCC_PeriphClockDividerSet(USB_PLL_SPIC, GET_CLK_DIV(spic_ckd)); RCC_PeriphClockSourceSet(SPIC, USB_PLL); - RTK_LOGI(TAG, "SPIC CLK: %d Hz\n", usb_pll_clk / GET_CLK_DIV(spic_ckd)); + RTK_LOGI(TAG, "FLASH CLK: %d Hz\n", usb_pll_clk / (2 * GET_CLK_DIV(spic_ckd))); } /* save spic clock para into retention memory */ @@ -58,8 +65,6 @@ int flash_handshake_highspeed(void) u8 Dphy_Dly_Cnt = 3; /* DD recommend this value */ int Ret = RTK_FAIL; - FLASH_PLLInit_ClockDiv(); - /* Note: some full voltage range Flash e.g.GD25WQ64E need 10ns HW recommend: at leaset 10ns */ SPIC->TPR1 = (SPIC->TPR1 & ~MASK_CS_ACTIVE_SETUP) | CS_ACTIVE_SETUP(2); @@ -70,6 +75,9 @@ int flash_handshake_highspeed(void) /* Open handshake function */ FLASH_Read_HandShake_Cmd(Dphy_Dly_Cnt, ENABLE); + /* If XiP, code may in flash. Handshake should be enabled before set to PLL clk */ + FLASH_PLLInit_ClockDiv(); + if (FLASH_Read_DataIsRight(valid_img1_addr)) { Ret = RTK_SUCCESS; } else { diff --git a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_npcap.c b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_npcap.c similarity index 100% rename from ameba/amebaG2/source/fwlib/ram_km4tz/ameba_npcap.c rename to ameba/amebag2/source/fwlib/ram_km4tz/ameba_npcap.c diff --git a/ameba/amebag2/source/fwlib/ram_km4tz/ameba_phy.c b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_phy.c new file mode 100644 index 00000000..9a80ca42 --- /dev/null +++ b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_phy.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ameba_soc.h" +static const char *const TAG = "PHY"; + + +int PHY_SoftWareReset(uint8_t phy_id) +{ + int ret = 0; + + /* Select page 0 */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_0); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to select page 0. PHY(%d)", phy_id); + return ret; + } + + /* Write reset command to Basic Control Register */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_0, PHY_RESET); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to write software reset. PHY(%d)", phy_id); + return ret; + } + + /* Wait for reset to complete as required by the datasheet */ + DelayMs(20); + return RTK_SUCCESS; +} + +int PHY_RestartAutoNego(uint8_t phy_id) +{ + int ret = 0; + + /* Select page 0 */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_0); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to select page 0. PHY(%d)", phy_id); + return ret; + } + + /* Restart auto-negotiation */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_0, EN_AUTO_GEN | RESTART_AUTO_GEN); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to restart auto-negotiation. PHY(%d)", phy_id); + return ret; + } + return RTK_SUCCESS; +} + +int PHY_SetMmdReg(uint8_t phy_id, uint8_t mmd_dev, uint16_t mmd_addr, uint16_t data) +{ + int ret = 0; + + /* Select page 0 */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_0); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to select page 0. PHY(%d)", phy_id); + return ret; + } + /* Set address mode and select MMD device */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_13, RTL8201FR_MACR_FUNC_ADDR(PHY_MMD_ADDR) | mmd_dev); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set address mode. PHY(%d), DEV(%d)", phy_id, mmd_dev); + return ret; + } + /* Write address value */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_14, mmd_addr); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set MMD address. PHY(%d), ADDR(0x%X)", phy_id, mmd_addr); + return ret; + } + /* Set data mode and select MMD device */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_13, RTL8201FR_MACR_FUNC_ADDR(PHY_MMD_DATA_NO_POST_INC) | mmd_dev); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set data mode. PHY(%d), DEV(%d)", phy_id, mmd_dev); + return ret; + } + /* Write data to MMD register */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_14, data); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to write data to MMD register. PHY(%d), DATA(0x%X)", phy_id, data); + return ret; + } + return RTK_SUCCESS; +} + +int PHY_GetMmdReg(uint8_t phy_id, uint8_t mmd_dev, uint16_t mmd_addr, uint16_t *p_data) +{ + int ret = 0; + uint16_t data = 0; + + /* Select page 0 */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_0); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to select page 0. PHY(%d)", phy_id); + return ret; + } + /* Set address mode and select MMD device */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_13, RTL8201FR_MACR_FUNC_ADDR(PHY_MMD_ADDR) | mmd_dev); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set address mode. PHY(%d), DEV(%d)", phy_id, mmd_dev); + return ret; + } + /* Write address value */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_14, mmd_addr); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set MMD address. PHY(%d), ADDR(0x%X)", phy_id, mmd_addr); + return ret; + } + /* Set data mode and select MMD device */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_13, RTL8201FR_MACR_FUNC_ADDR(PHY_MMD_DATA_NO_POST_INC) | mmd_dev); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to set data mode. PHY(%d), DEV(%d)", phy_id, mmd_dev); + return ret; + } + /* Read data from MMD register */ + ret = Ethernet_ReadPhyReg(phy_id, FEPHY_REG_ADDR_14, &data); + if (ret != RTK_SUCCESS) { + RTK_LOGE(TAG, "Failed to read data from MMD register. PHY(%d)", phy_id); + return ret; + } + + if (p_data) { + *p_data = data; + } + return RTK_SUCCESS; +} + +int PHY_EnableEEE(uint8_t phy_id, u32 status) +{ + int ret = 0; + + /* Reset PHY and select page 0 */ + PHY_SoftWareReset(phy_id); + + if (status != DISABLE) { + /* Enable 100BASE-TX EEE capability */ + ret = PHY_SetMmdReg(phy_id, RTL8201FR_MMD_DEV_EEE_ADV, RTL8201FR_MMD_REG_EEEAR, RTL8201FR_EEEAR_100BT_EEE_ADV(1)); + if (ret != RTK_SUCCESS) { + return ret; + } + + /* Restart auto-negotiation */ + ret = PHY_RestartAutoNego(phy_id); + if (ret != RTK_SUCCESS) { + return ret; + } + } else { + /* Disable 100BASE-TX EEE capability */ + ret = PHY_SetMmdReg(phy_id, RTL8201FR_MMD_DEV_EEE_ADV, RTL8201FR_MMD_REG_EEEAR, RTL8201FR_EEEAR_100BT_EEE_ADV(0)); + if (ret != RTK_SUCCESS) { + return ret; + } + + /* Reset PHY, enable and restart auto-negotiation */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_0, PHY_RESET | EN_AUTO_GEN | RESTART_AUTO_GEN); + if (ret != RTK_SUCCESS) { + return ret; + } + DelayMs(20); + } + + return RTK_SUCCESS; +} + +int PHY_SetEEEMode(uint8_t phy_id, uint8_t eth_mode) +{ + int ret = 0; + + /* Reset PHY and select page 0 */ + PHY_SoftWareReset(phy_id); + + /* Select MAC/PHY mode configuration page */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, RTL8211F_PHY_MODE_PAGE); + if (ret != RTK_SUCCESS) { + return ret; + } + + if (eth_mode == ETH_MAC_MODE) { + ret = Ethernet_WritePhyReg(phy_id, RTL8211F_PHYCR2_ADDR, RTL8211F_PHCR2_MAC_MODE); + if (ret != RTK_SUCCESS) { + return ret; + } + } else { + ret = Ethernet_WritePhyReg(phy_id, RTL8211F_PHYCR2_ADDR, RTL8211F_PHCR2_PHY_MODE); + if (ret != RTK_SUCCESS) { + return ret; + } + } + + return RTK_SUCCESS; +} + +int PHY_SetRefclkDir(uint8_t phy_id, u32 mac_dir) +{ + int ret = 0; + uint16_t data = 0; + + /* Select page 7 */ + ret = Ethernet_WritePhyReg(phy_id, FEPHY_REG_ADDR_31, FEPHY_REG_PAGE_7); + if (ret != RTK_SUCCESS) { + return ret; + } + + /* Read RMII mode register */ + ret = Ethernet_ReadPhyReg(phy_id, RTL8201FR_PAGE7_REG_RMII_MODE_SET, &data); + if (ret != RTK_SUCCESS) { + return ret; + } + + if (mac_dir == ETH_REFCLK_ON) { + data |= RTL8201FR_P7_16_RMII_CLK_DIR; + } else { + data &= ~RTL8201FR_P7_16_RMII_CLK_DIR; + } + + /* Write clock direction configuration back */ + ret = Ethernet_WritePhyReg(phy_id, RTL8201FR_PAGE7_REG_RMII_MODE_SET, data); + if (ret != RTK_SUCCESS) { + return ret; + } + + return RTK_SUCCESS; +} diff --git a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_pmc.c b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_pmc.c similarity index 91% rename from ameba/amebaG2/source/fwlib/ram_km4tz/ameba_pmc.c rename to ameba/amebag2/source/fwlib/ram_km4tz/ameba_pmc.c index 71320f89..309e39d6 100644 --- a/ameba/amebaG2/source/fwlib/ram_km4tz/ameba_pmc.c +++ b/ameba/amebag2/source/fwlib/ram_km4tz/ameba_pmc.c @@ -23,10 +23,10 @@ PMC_ENTRY_SECTION void PMC_ENTRY SOCPS_SleepInitEntry(struct PSCFG_TypeDef *ps_config) { /*2. Clock configuration*/ - SOCPS_ClockSourceConfig(ps_config->regu_state_in_sleep, ps_config->xtal_mode_in_sleep, ps_config->keep_osc4m_on_in_sleep); + SOCPS_ClockSourceConfig(ps_config->sleep_to_08V, ps_config->xtal_mode_in_sleep, ps_config->keep_osc4m_on); /*3. Power settings*/ - SOCPS_PowerManage(ps_config->regu_state_in_sleep); + SOCPS_PowerManage(ps_config->sleep_to_08V); if (EFUSE_GetChipVersion() == SYSCFG_CUT_VERSION_A) { /*Timing fix: Delay at least 1T before pulling down rst_n to avoid postsim bit errors. diff --git a/ameba/common/CMakeLists.txt b/ameba/common/CMakeLists.txt index 4a9540b9..68bed0f0 100644 --- a/ameba/common/CMakeLists.txt +++ b/ameba/common/CMakeLists.txt @@ -2,3 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(include) +add_subdirectory(os_wrapper) + +add_subdirectory_ifdef(CONFIG_REALTEK_AMEBA_ZEPHYR_WIFI wifi) diff --git a/ameba/common/include/rtk_compiler.h b/ameba/common/include/rtk_compiler.h index a89aa11a..30eac7a7 100644 --- a/ameba/common/include/rtk_compiler.h +++ b/ameba/common/include/rtk_compiler.h @@ -7,7 +7,9 @@ #ifndef __RTK_COMPILER_H__ #define __RTK_COMPILER_H__ +#ifdef __ZEPHYR__ #include +#endif #define Compile_Assert(exp, str) extern char __ct_[(exp) ? 1 : -1] diff --git a/ameba/usrcfg/amebaG2/CMakeLists.txt b/ameba/common/os_wrapper/CMakeLists.txt similarity index 100% rename from ameba/usrcfg/amebaG2/CMakeLists.txt rename to ameba/common/os_wrapper/CMakeLists.txt diff --git a/ameba/common/os_wrapper/include/os_wrapper.h b/ameba/common/os_wrapper/include/os_wrapper.h new file mode 100644 index 00000000..52bce6ef --- /dev/null +++ b/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 "platform_autoconf.h" +#include +#include +#include + +#include "ameba.h" +#ifdef __ZEPHYR__ +#include +#endif +/** + * @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/ameba/common/os_wrapper/include/os_wrapper_critical.h b/ameba/common/os_wrapper/include/os_wrapper_critical.h new file mode 100644 index 00000000..18209c16 --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_critical.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_CRITCAL_H__ +#define __OS_WRAPPER_CRITCAL_H__ + +/** + * Define CA32 SMP spin lock id + */ +typedef enum { + RTOS_CRITICAL_DEFAULT = 0, + RTOS_CRITICAL_SOC, + RTOS_CRITICAL_AUDIO, + RTOS_CRITICAL_WIFI, + RTOS_CRITICAL_NETWORK, + RTOS_CRITICAL_LWIP, + RTOS_CRITICAL_BT, + RTOS_CRITICAL_USB, + RTOS_CRITICAL_WPAN, + RTOS_CRITICAL_SEMA, + RTOS_CRITICAL_LOG, + RTOS_CRITICAL_MAX +} RTOS_CRITICAL_LIST; + +/** + * @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(uint32_t component_id); + +/** + * @brief Internally handles interrupt status(PRIMASK/CPSR) restore + */ +void rtos_critical_exit(uint32_t component_id); + +/** + * @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/ameba/common/os_wrapper/include/os_wrapper_memory.h b/ameba/common/os_wrapper/include/os_wrapper_memory.h new file mode 100644 index 00000000..f52f2e03 --- /dev/null +++ b/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/ameba/common/os_wrapper/include/os_wrapper_mutex.h b/ameba/common/os_wrapper/include/os_wrapper_mutex.h new file mode 100644 index 00000000..10af266a --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_mutex.h @@ -0,0 +1,136 @@ +/* + * 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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_FAIL + */ +int rtos_mutex_recursive_give(rtos_mutex_t p_handle); + +#endif diff --git a/ameba/common/os_wrapper/include/os_wrapper_queue.h b/ameba/common/os_wrapper/include/os_wrapper_queue.h new file mode 100644 index 00000000..1bf07487 --- /dev/null +++ b/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, RTOS_MAX_DELAY); + * Receive: + * rtos_queue_receive(queue_handle, p_msg, RTOS_MAX_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_FAIL + */ +int rtos_queue_peek(rtos_queue_t p_handle, void *p_msg, uint32_t wait_ms); + +#endif diff --git a/ameba/common/os_wrapper/include/os_wrapper_semaphore.h b/ameba/common/os_wrapper/include/os_wrapper_semaphore.h new file mode 100644 index 00000000..a9f999fb --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_semaphore.h @@ -0,0 +1,119 @@ +/* + * 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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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/ameba/common/os_wrapper/include/os_wrapper_specific.h b/ameba/common/os_wrapper/include/os_wrapper_specific.h new file mode 100644 index 00000000..33b9acb5 --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_specific.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OS_WRAPPER_SPECIFIC_H__ +#define __OS_WRAPPER_SPECIFIC_H__ + +#define RTOS_CONVERT_MS_TO_TICKS(MS) k_ms_to_cyc_floor32(MS) + +#endif diff --git a/ameba/common/os_wrapper/include/os_wrapper_task.h b/ameba/common/os_wrapper/include/os_wrapper_task.h new file mode 100644 index 00000000..9fb55792 --- /dev/null +++ b/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 RTK_SUCCESS Only + */ +int rtos_sched_start(void); + +/** + * @brief Stop os kernel scheduler + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +int rtos_sched_stop(void); + +/** + * @brief Suspend os kernel scheduler + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +int rtos_sched_suspend(void); + +/** + * @brief Resume os kernel scheduler + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +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 RTK_SUCCESS(0) / RTK_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 RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +int rtos_task_delete(rtos_task_t p_handle); + +/** + * @brief Suspend os level task routine. + * @param p_handle: Task handle. + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +int rtos_task_suspend(rtos_task_t p_handle); + +/** + * @brief Resume os level task routine. + * @param p_handle: Task handle. + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +int rtos_task_resume(rtos_task_t p_handle); + +/** + * @brief Yield current os level task routine. + * @retval RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +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 RTK_SUCCESS(0) / RTK_FAIL(-1) + */ +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/ameba/common/os_wrapper/include/os_wrapper_time.h b/ameba/common/os_wrapper/include/os_wrapper_time.h new file mode 100644 index 00000000..f70310e2 --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_time.h @@ -0,0 +1,57 @@ +/* + * 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); + +/** + * @brief Get the count of pended ticks since rtos_sched_suspend was called, and convert the + * return value to milliseconds. + */ +uint32_t rtos_time_get_current_pended_time_ms(void); + +#endif diff --git a/ameba/common/os_wrapper/include/os_wrapper_timer.h b/ameba/common/os_wrapper/include/os_wrapper_timer.h new file mode 100644 index 00000000..0dc6913a --- /dev/null +++ b/ameba/common/os_wrapper/include/os_wrapper_timer.h @@ -0,0 +1,128 @@ +/* + * 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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 RTK_SUCCESS or RTK_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 the timer. + * @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 RTK_SUCCESS or RTK_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/ameba/common/os_wrapper/include/platform_stdlib.h b/ameba/common/os_wrapper/include/platform_stdlib.h new file mode 100644 index 00000000..84f34943 --- /dev/null +++ b/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/ameba/common/wifi/CMakeLists.txt b/ameba/common/wifi/CMakeLists.txt new file mode 100644 index 00000000..91d50b99 --- /dev/null +++ b/ameba/common/wifi/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(source) +zephyr_include_directories(../../usrcfg/common) + +zephyr_library_sources_ifdef(CONFIG_WIFI source/wifi_feature_dis_antdiv.c) +zephyr_library_sources_ifdef(CONFIG_WIFI source/wifi_init_zephyr.c) diff --git a/ameba/common/wifi/Kconfig b/ameba/common/wifi/Kconfig new file mode 100644 index 00000000..27f4f9c0 --- /dev/null +++ b/ameba/common/wifi/Kconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config REALTEK_AMEBA_ZEPHYR_WIFI + bool "RealTek Ameba Zephyr WIFI" + default y + help + This option enables the Realtek Ameba WIFI. + +if REALTEK_AMEBA_ZEPHYR_WIFI +config WLAN + bool "enable wifi" + default y + +config AS_INIC_AP + bool + +config SINGLE_CORE_WIFI + bool + +endif # REALTEK_AMEBA_ZEPHYR_WIFI diff --git a/ameba/common/wifi/source/rtw_autoconf.h b/ameba/common/wifi/source/rtw_autoconf.h new file mode 100644 index 00000000..8d3f3e48 --- /dev/null +++ b/ameba/common/wifi/source/rtw_autoconf.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef WLANCONFIG_H +#define WLANCONFIG_H + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "platform_autoconf.h" + +#ifndef CONFIG_LITTLE_ENDIAN +#define CONFIG_LITTLE_ENDIAN +#endif + +#define WIFI_LOGO_CERTIFICATION 0 + +#define MACID_HW_MAX_NUM 16 +#define NET_IF_NUM 2 + +#endif //WLANCONFIG_H diff --git a/ameba/common/wifi/source/rtw_wifi_defs.h b/ameba/common/wifi/source/rtw_wifi_defs.h new file mode 100644 index 00000000..bb1decc1 --- /dev/null +++ b/ameba/common/wifi/source/rtw_wifi_defs.h @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RTW_WIFI_DEFS_H_ +#define __RTW_WIFI_DEFS_H_ + +#define _WEAK __attribute__ ((weak)) + +/** @defgroup WIFI_Exported_Constants WIFI Exported Constants + * @{ + */ + +/** @defgroup WLAN_Defs + *@{ + */ +#ifndef WLAN0_NAME +#define WLAN0_NAME "wlan0" /**< WLAN0 NAME */ +#endif + +#ifndef WLAN1_NAME +#define WLAN1_NAME "wlan1" /**< WLAN1 NAME */ +#endif + +#ifndef WLAN0_IDX +#define WLAN0_IDX 0 /**< wlan0 index */ +#endif + +#ifndef WLAN1_IDX +#define WLAN1_IDX 1 /**< wlan1 index */ +#endif + +#ifndef STA_WLAN_INDEX +#define STA_WLAN_INDEX 0 +#endif + +#ifndef SOFTAP_WLAN_INDEX +#define SOFTAP_WLAN_INDEX 1 +#endif + +#ifndef NAN_WLAN_INDEX +#define NAN_WLAN_INDEX 2 +#endif + +#ifndef STA_WLAN_NAME +#define STA_WLAN_NAME "wlan0" +#endif + +#ifndef SOFTAP_WLAN_NAME +#define SOFTAP_WLAN_NAME "wlan1" +#endif + +#ifndef NAN_WLAN_NAME +#define NAN_WLAN_NAME "wlan2" +#endif + +#define IsSupported24G(band_type) ((band_type) & BAND_CAP_2G? TRUE : FALSE) +#define IsSupported5G(band_type) ((band_type) & BAND_CAP_5G ? TRUE : FALSE) + +#define IsLegacyOnly(NetType) ((NetType) == ((NetType) & (WLAN_MD_11BG | WLAN_MD_11A))) + +#define IsSupportedTxOFDM(NetType) ((NetType) & (WLAN_MD_11G | WLAN_MD_11A) ? TRUE : FALSE) + +#define is_supported_ht(NetType) ((NetType) & (WLAN_MD_11N) ? TRUE : FALSE) +#define is_supported_vht(NetType) ((NetType) & (WLAN_MD_11AC) ? TRUE : FALSE) +#define is_supported_he(NetType) ((NetType) & (WLAN_MD_11AX) ? TRUE : FALSE) + +#define IS_HT_RATE(_rate) (((_rate) & 0x80) ? TRUE : FALSE) +#define IS_CCK_RATE(_rate) (MGN_1M == _rate || _rate == MGN_2M || _rate == MGN_5_5M || _rate == MGN_11M ) +#define IS_OFDM_RATE(_rate) (MGN_6M <= _rate && _rate <= MGN_54M ) + +/** + * @brief mac address format. + */ +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],\ + ((u8*)(x))[2],((u8*)(x))[3],\ + ((u8*)(x))[4],((u8*)(x))[5] +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" + +#define is_broadcast_mac_addr(Addr) ((((Addr[0]) & 0xff) == 0xff) && (((Addr[1]) & 0xff) == 0xff) && \ +(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ +(((Addr[5]) & 0xff) == 0xff)) +#define is_zero_mac_addr(Addr) ((Addr[0] == 0x00) && (Addr[1] == 0x00) && (Addr[2] == 0x00) && \ + (Addr[3] == 0x00) && (Addr[4] == 0x00) && (Addr[5] == 0x00)) + +/** + * @} + */ + + +/** @defgroup Security_Defs + *@{ + */ +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 +#define AUTH_ALG_SAE 0x8 +#define AUTH_ALG_LEAP 0x00000004 + +#define WEP_ENABLED 0x0001 /**< wep enable */ +#define TKIP_ENABLED 0x0002 /**< tkip enable */ +#define AES_ENABLED 0x0004 /**< aes enable */ +#define WSEC_SWFLAG 0x0008 /**< WSEC SWFLAG */ +#define AES_CMAC_ENABLED 0x0010 /**< aes cmac enable */ +#define ENTERPRISE_ENABLED 0x0020 /**< enterprise enable */ +#define OWE_ENABLED 0X0040 /**< owe enable */ +#define SHARED_ENABLED 0x00008000 /**< shared enable */ +#define WPA_SECURITY 0x00200000 /**< wpa */ +#define WPA2_SECURITY 0x00400000 /**< wpa2 */ +#define WPA3_SECURITY 0x00800000 /**< wpa3 */ +#define WPS_ENABLED 0x10000000 /**< wps enable*/ + +/*cipher suite from 802.11-2016 p884*/ +#define WIFI_CIPHER_SUITE_WEP_40 0x000FAC01 +#define WIFI_CIPHER_SUITE_TKIP 0x000FAC02 +#define WIFI_CIPHER_SUITE_CCMP_128 0x000FAC04 +#define WIFI_CIPHER_SUITE_WEP_104 0x000FAC05 +#define WIFI_CIPHER_SUITE_BIP_CMAC_128 0x000FAC06 +#define WIFI_CIPHER_SUITE_GCMP 0x000FAC08 +#define WIFI_CIPHER_SUITE_GCMP_256 0x000FAC09 +#define WIFI_CIPHER_SUITE_CCMP_256 0x000FAC0A +#define WIFI_CIPHER_SUITE_BIP_GMAC_128 0x000FAC0B +#define WIFI_CIPHER_SUITE_BIP_GMAC_256 0x000FAC0C +#define WIFI_CIPHER_SUITE_BIP_CMAC_256 0x000FAC0D + +#define RTW_WPA2_MAX_PSK_LEN (64) +#define RTW_WPA3_MAX_PSK_LEN (128) /**< maxmum psk length */ +#define RTW_MAX_PSK_LEN RTW_WPA3_MAX_PSK_LEN +#define RTW_MIN_PSK_LEN (8) /**< minimum psk length */ +#define MCSSET_LEN 16 /**